Add some Linux T1040 packet capture tests using raw sockets
This commit is contained in:
+119
-1
@@ -153,4 +153,122 @@ atomic_tests:
|
||||
cleanup_command: |-
|
||||
pktmon filter remove
|
||||
name: command_prompt
|
||||
elevation_required: true
|
||||
elevation_required: true
|
||||
- name: Packet Capture Linux socket AF_PACKET,SOCK_RAW with sudo
|
||||
description: |
|
||||
Captures packets with domain=AF_PACKET, type=SOCK_RAW for a few seconds.
|
||||
supported_platforms:
|
||||
- linux
|
||||
input_arguments:
|
||||
csource_path:
|
||||
description: Path to C program source
|
||||
type: String
|
||||
default: PathToAtomicsFolder/T1040/src/linux_pcapdemo.c
|
||||
program_path:
|
||||
description: Path to compiled C program
|
||||
type: String
|
||||
default: /tmp/t1040_linux_pcapdemo
|
||||
dependency_executor_name: bash
|
||||
dependencies:
|
||||
- description: |
|
||||
compile C program
|
||||
prereq_command: |
|
||||
exit 1
|
||||
get_prereq_command: |
|
||||
cc #{csource_path} -o #{program_path}
|
||||
executor:
|
||||
command: |
|
||||
sudo #{program_path} -a -t 3
|
||||
cleanup_command: |
|
||||
rm -f #{program_path}
|
||||
name: bash
|
||||
elevation_required: true
|
||||
- name: Packet Capture Linux socket AF_INET,SOCK_RAW,TCP with sudo
|
||||
description: |
|
||||
Captures packets with domain=AF_INET,type=SOCK_RAW,protocol=TCP for a few seconds.
|
||||
supported_platforms:
|
||||
- linux
|
||||
input_arguments:
|
||||
csource_path:
|
||||
description: Path to C program source
|
||||
type: String
|
||||
default: PathToAtomicsFolder/T1040/src/linux_pcapdemo.c
|
||||
program_path:
|
||||
description: Path to compiled C program
|
||||
type: String
|
||||
default: /tmp/t1040_linux_pcapdemo
|
||||
dependency_executor_name: bash
|
||||
dependencies:
|
||||
- description: |
|
||||
compile C program
|
||||
prereq_command: |
|
||||
exit 1
|
||||
get_prereq_command: |
|
||||
cc #{csource_path} -o #{program_path}
|
||||
executor:
|
||||
command: |
|
||||
sudo #{program_path} -4 -p 6 -t 3
|
||||
cleanup_command: |
|
||||
rm -f #{program_path}
|
||||
name: bash
|
||||
elevation_required: true
|
||||
- name: Packet Capture Linux socket AF_INET,SOCK_PACKET,UDP with sudo
|
||||
description: |
|
||||
Captures packets with domain=AF_INET,type=SOCK_PACKET,protocol=UDP for a few seconds.
|
||||
SOCK_PACKET is "obsolete" according to the man page, but still works on Ubuntu 20.04
|
||||
supported_platforms:
|
||||
- linux
|
||||
input_arguments:
|
||||
csource_path:
|
||||
description: Path to C program source
|
||||
type: String
|
||||
default: PathToAtomicsFolder/T1040/src/linux_pcapdemo.c
|
||||
program_path:
|
||||
description: Path to compiled C program
|
||||
type: String
|
||||
default: /tmp/t1040_linux_pcapdemo
|
||||
dependency_executor_name: bash
|
||||
dependencies:
|
||||
- description: |
|
||||
compile C program
|
||||
prereq_command: |
|
||||
exit 1
|
||||
get_prereq_command: |
|
||||
cc #{csource_path} -o #{program_path}
|
||||
executor:
|
||||
command: |
|
||||
sudo #{program_path} -4 -P -p 17 -t 3
|
||||
cleanup_command: |
|
||||
rm -f #{program_path}
|
||||
name: bash
|
||||
elevation_required: true
|
||||
- name: Packet Capture Linux socket AF_PACKET,SOCK_RAW with BPF filter for UDP with sudo
|
||||
description: |
|
||||
Captures packets with domain=AF_PACKET,type=SOCK_RAW for a few seconds.
|
||||
Sets a BPF filter on the socket to filter for UDP traffic.
|
||||
supported_platforms:
|
||||
- linux
|
||||
input_arguments:
|
||||
csource_path:
|
||||
description: Path to C program source
|
||||
type: String
|
||||
default: PathToAtomicsFolder/T1040/src/linux_pcapdemo.c
|
||||
program_path:
|
||||
description: Path to compiled C program
|
||||
type: String
|
||||
default: /tmp/t1040_linux_pcapdemo
|
||||
dependency_executor_name: bash
|
||||
dependencies:
|
||||
- description: |
|
||||
compile C program
|
||||
prereq_command: |
|
||||
exit 1
|
||||
get_prereq_command: |
|
||||
cc #{csource_path} -o #{program_path}
|
||||
executor:
|
||||
command: |
|
||||
sudo #{program_path} -a -f -t 3
|
||||
cleanup_command: |
|
||||
rm -f #{program_path}
|
||||
name: bash
|
||||
elevation_required: true
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netinet/ip_icmp.h> //Provides declarations for icmp header
|
||||
#include <netinet/udp.h> //Provides declarations for udp header
|
||||
#include <netinet/tcp.h> //Provides declarations for tcp header
|
||||
#include <netinet/ip.h> //Provides declarations for ip header
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
static const struct option longopts[] = {
|
||||
{ "afpacket", no_argument, NULL, 'a'},
|
||||
{ "afinet4", no_argument, NULL, '4'},
|
||||
{ "afinet6", no_argument, NULL, '6'},
|
||||
{ "protocol", required_argument, NULL, 'p'},
|
||||
{ "sockpacket", no_argument, NULL, 'P'},
|
||||
{ "sockraw", no_argument, NULL, 'R'},
|
||||
{ "time", required_argument, NULL, 't'},
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static void usage(const char *progname)
|
||||
{
|
||||
printf("usage: %s <options>\n", progname);
|
||||
printf(" -a --afpacket Set domain to AF_PACKET.\n");
|
||||
printf(" -4 --afinet Set domain to AF_INET (default).\n");
|
||||
printf(" -6 --afinet6 Set domain to AF_PACKET.\n");
|
||||
printf(" -p --protocol <int value> Integer value to set as protocol argument. For AF_INET default is IPPROTO_TCP=6. Others:IPPROTO_UDP=17 IPPROTO_ICMP=1\n");
|
||||
printf(" -P --sockpacket Set sock_type to SOCK_PACKET.\n");
|
||||
printf(" -R --sockraw Set sock_type to SOCK_RAW (default)\n");
|
||||
printf(" -t --time <num seconds> Exit after number of seconds. Default is to run until killed.\n");
|
||||
}
|
||||
|
||||
void ProcessPacket(unsigned char* buf, int size, int af);
|
||||
|
||||
int sock_raw;
|
||||
int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j;
|
||||
struct sockaddr_in source,dest;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int af = AF_INET;
|
||||
int sock_type = SOCK_RAW;
|
||||
int sock_protocol_inet = IPPROTO_TCP;
|
||||
int sock_protocol = sock_protocol_inet;
|
||||
int timeout = 0;
|
||||
|
||||
int sock_protocol_packet = htons(3); // AF_PACKET
|
||||
|
||||
int saddr_size , data_size;
|
||||
struct sockaddr saddr;
|
||||
struct in_addr in;
|
||||
|
||||
unsigned char *buffer = (unsigned char *)malloc(65536);
|
||||
|
||||
int c;
|
||||
|
||||
while(1)
|
||||
{
|
||||
int option_index = 0;
|
||||
|
||||
c = getopt_long(argc, argv, "a46p:PRt:", longopts, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'a':
|
||||
af = AF_PACKET;
|
||||
sock_protocol = sock_protocol_packet;
|
||||
break;
|
||||
case '4':
|
||||
af = AF_INET;
|
||||
break;
|
||||
case '6':
|
||||
af = AF_INET6;
|
||||
break;
|
||||
case 'P':
|
||||
sock_type = SOCK_PACKET;
|
||||
break;
|
||||
case 'R':
|
||||
sock_type = SOCK_RAW;
|
||||
break;
|
||||
case 'p':
|
||||
sock_protocol = atoi(optarg);
|
||||
printf("using protocol=%d (0x%x)\n", sock_protocol, sock_protocol);
|
||||
break;
|
||||
case 't':
|
||||
timeout = atoi(optarg);
|
||||
printf("will exit after %d seconds\n", timeout);
|
||||
break;
|
||||
default:
|
||||
printf("invalid argument: '%c'\n", c);
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Starting...\n");
|
||||
|
||||
// create RAW socket to capture packets
|
||||
|
||||
sock_raw = socket(af , sock_type , sock_protocol);
|
||||
if(sock_raw < 0)
|
||||
{
|
||||
printf("Socket Error\n");
|
||||
return 1;
|
||||
}
|
||||
time_t tstop = time(NULL) + timeout;
|
||||
while(1)
|
||||
{
|
||||
int flags = MSG_DONTWAIT;
|
||||
saddr_size = sizeof saddr;
|
||||
//Receive a packet
|
||||
data_size = recvfrom(sock_raw , buffer , 65536 , flags , &saddr , &saddr_size);
|
||||
if(data_size <0 )
|
||||
{
|
||||
if (EAGAIN == errno || EWOULDBLOCK == errno) {
|
||||
usleep(15000);
|
||||
if (timeout > 0 && time(NULL) >= tstop) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("Recvfrom error , failed to get packets\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ProcessPacket(buffer , data_size, af);
|
||||
}
|
||||
close(sock_raw);
|
||||
printf("Finished\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ProcessPacket(unsigned char* buffer, int size, int af)
|
||||
{
|
||||
++total;
|
||||
|
||||
if (AF_PACKET == af)
|
||||
{
|
||||
return; // TODO: parse ether
|
||||
}
|
||||
|
||||
//Get the IP Header part of this packet
|
||||
struct iphdr *iph = (struct iphdr*)buffer;
|
||||
switch (iph->protocol) //Check the Protocol and do accordingly...
|
||||
{
|
||||
case IPPROTO_ICMP:
|
||||
++icmp;
|
||||
break;
|
||||
|
||||
case IPPROTO_TCP:
|
||||
++tcp;
|
||||
break;
|
||||
|
||||
case IPPROTO_UDP:
|
||||
++udp;
|
||||
break;
|
||||
|
||||
default:
|
||||
++others;
|
||||
break;
|
||||
}
|
||||
printf("TCP : %d UDP : %d ICMP : %d Others : %d Total : %d\n",tcp,udp,icmp,others,total);
|
||||
}
|
||||
Reference in New Issue
Block a user