Answered step by step
Verified Expert Solution
Question
1 Approved Answer
Add the spoofing code to the sniffex.c Sniffex.c #define APP_NAME sniffex #define APP_DESC Sniffer example using libpcap #define APP_COPYRIGHT Copyright (c) 2005 The Tcpdump Group
Add the spoofing code to the sniffex.c
Sniffex.c
#define APP_NAME "sniffex" #define APP_DESC "Sniffer example using libpcap" #define APP_COPYRIGHT "Copyright (c) 2005 The Tcpdump Group" #define APP_DISCLAIMER "THERE IS ABSOLUTELY NO WARRANTY FOR THIS PROGRAM." #include #include #include #include #include #include #include #include #include #include /* default snap length (maximum bytes per packet to capture) */ #define SNAP_LEN 1518 /* ethernet headers are always exactly 14 bytes [1] */ #define SIZE_ETHERNET 14 /* Ethernet addresses are 6 bytes */ #define ETHER_ADDR_LEN 6 /* Ethernet header */ struct sniff_ethernet { u_char ether_dhost[ETHER_ADDR_LEN]; /* destination host address */ u_char ether_shost[ETHER_ADDR_LEN]; /* source host address */ u_short ether_type; /* IP? ARP? RARP? etc */ }; /* IP header */ struct sniff_ip { u_char ip_vhl; /* version > 2 */ u_char ip_tos; /* type of service */ u_short ip_len; /* total length */ u_short ip_id; /* identification */ u_short ip_off; /* fragment offset field */ #define IP_RF 0x8000 /* reserved fragment flag */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ u_char ip_ttl; /* time to live */ u_char ip_p; /* protocol */ u_short ip_sum; /* checksum */ struct in_addr ip_src,ip_dst; /* source and dest address */ }; #define IP_HL(ip) (((ip)->ip_vhl) & 0x0f) #define IP_V(ip) (((ip)->ip_vhl) >> 4) /* TCP header */ typedef u_int tcp_seq; struct sniff_tcp { u_short th_sport; /* source port */ u_short th_dport; /* destination port */ tcp_seq th_seq; /* sequence number */ tcp_seq th_ack; /* acknowledgement number */ u_char th_offx2; /* data offset, rsvd */ #define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) u_char th_flags; #define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 #define TH_ECE 0x40 #define TH_CWR 0x80 #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) u_short th_win; /* window */ u_short th_sum; /* checksum */ u_short th_urp; /* urgent pointer */ }; void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet); void print_payload(const u_char *payload, int len); void print_hex_ascii_line(const u_char *payload, int len, int offset); void print_app_banner(void); void print_app_usage(void); /* * app name/banner */ void print_app_banner(void) { printf("%s - %s ", APP_NAME, APP_DESC); printf("%s ", APP_COPYRIGHT); printf("%s ", APP_DISCLAIMER); printf(" "); return; } /* * print help text */ void print_app_usage(void) { printf("Usage: %s [interface] ", APP_NAME); printf(" "); printf("Options: "); printf(" interface Listen on for packets. "); printf(" "); return; } /* * print data in rows of 16 bytes: offset hex ascii * * 00000 47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a GET / HTTP/1.1.. */ void print_hex_ascii_line(const u_char *payload, int len, int offset) { int i; int gap; const u_char *ch; /* offset */ printf("%05d ", offset); /* hex */ ch = payload; for(i = 0; i ip_src)); printf(" To: %s ", inet_ntoa(ip->ip_dst)); /* determine protocol */ switch(ip->ip_p) { case IPPROTO_TCP: printf(" Protocol: TCP "); break; case IPPROTO_UDP: printf(" Protocol: UDP "); return; case IPPROTO_ICMP: printf(" Protocol: ICMP "); return; case IPPROTO_IP: printf(" Protocol: IP "); return; default: printf(" Protocol: unknown "); return; } /* * OK, this packet is TCP. */ /* define/compute tcp header offset */ tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); size_tcp = TH_OFF(tcp)*4; if (size_tcp th_sport)); printf(" Dst port: %d ", ntohs(tcp->th_dport)); /* define/compute tcp payload (segment) offset */ payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp); /* compute tcp payload (segment) size */ size_payload = ntohs(ip->ip_len) - (size_ip + size_tcp); /* * Print payload data; it might be binary, so don't just * treat it as a string. */ if (size_payload > 0) { printf(" Payload (%d bytes): ", size_payload); print_payload(payload, size_payload); } return; } int main(int argc, char **argv) { char *dev = NULL; /* capture device name */ char errbuf[PCAP_ERRBUF_SIZE]; /* error buffer */ pcap_t *handle; /* packet capture handle */ char filter_exp[] = "ip"; /* filter expression [3] */ struct bpf_program fp; /* compiled filter program (expression) */ bpf_u_int32 mask; /* subnet mask */ bpf_u_int32 net; /* ip */ int num_packets = 10; /* number of packets to capture */ print_app_banner(); /* check for capture device name on command-line */ if (argc == 2) { dev = argv[1]; } else if (argc > 2) { fprintf(stderr, "error: unrecognized command-line options "); print_app_usage(); exit(EXIT_FAILURE); } else { /* find a capture device if not specified on command-line */ dev = pcap_lookupdev(errbuf); if (dev == NULL) { fprintf(stderr, "Couldn't find default device: %s ", errbuf); exit(EXIT_FAILURE); } } /* get network number and mask associated with capture device */ if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { fprintf(stderr, "Couldn't get netmask for device %s: %s ", dev, errbuf); net = 0; mask = 0; } /* print capture info */ printf("Device: %s ", dev); printf("Number of packets: %d ", num_packets); printf("Filter expression: %s ", filter_exp); /* open capture device */ handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf); if (handle == NULL) { fprintf(stderr, "Couldn't open device %s: %s ", dev, errbuf); exit(EXIT_FAILURE); } /* make sure we're capturing on an Ethernet device [2] */ if (pcap_datalink(handle) != DLT_EN10MB) { fprintf(stderr, "%s is not an Ethernet ", dev); exit(EXIT_FAILURE); } /* compile the filter expression */ if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s ", filter_exp, pcap_geterr(handle)); exit(EXIT_FAILURE); } /* apply the compiled filter */ if (pcap_setfilter(handle, &fp) == -1) { fprintf(stderr, "Couldn't install filter %s: %s ", filter_exp, pcap_geterr(handle)); exit(EXIT_FAILURE); } /* now we can set our callback function */ pcap_loop(handle, num_packets, got_packet, NULL); /* cleanup */ pcap_freecode(&fp); pcap_close(handle); printf(" Capture complete. "); return 0; }3.2 Task 2: Spoofing When a normal user sends out a packet, operating systems usually do not allow the user to set all the fields in the protocol headers (such as TCP, UDP, and IP headers). OSes will set most of the fields, while only allowing users to set a few fields, such as the destination IP address, and the destination port number, etc. However, if the user has the root privilege, he/she can set any arbitary field in the packet headers. This is essentially packet spoofing, and it can be done through raw sockets. Raw sockets give programmers the absolute control over the packet construction, allowing programmers to construct any arbitrary packet, including setting the header fields and the payload. Using raw sockets is quite straightforward; it involves four steps: (1) create a raw socket, (2) set socket option, (3) construct the packet, and (4) send out the packet through the raw socket. There are many online tutorials that can teach you how to use raw sockets in C programming. In this task, we will not focus on any specific tutorial. Your task is to read some of these tutorials, then either write your own packet spoofing program or download a program from other places. After playing with these programs, please solve the following problems: Problem 8: Please combine your sniffing and the spoofing programs to implement a sniff-and-then- spoof program. This program monitors its local network; whenever it sees an ICMP echo request packet, it spoofs an ICMP echo reply packet with the information of another machine (other than the sender and receiver) in the network (in your AWS enclave). Please include screendump in your report to show that your program works (you might capture ICMP echo request and reply from the sender machine). Please also attach the code in your report. When you send out a packet using raw sockets, you basically construct the packet inside a buffer, so when you need to send it out, you simply give the operating system the buffer and the size of the packet. Working directly on the buffer is not easy, so a common way is to typecast the buffer (or part of the buffer) into structures, such as IP header structure, so you can refer to the elements of the buffer using the fields of those structures. You can define the IP, ICMP, TCP, UDP and other header structres in your program. The following example show how you can construct an UDP packet: struct ipheader type field; struct udpheader type field; // This buffer will be used to construct raw packet char buffer [1024] / Typecasting the buffer to the IP header structure struct ipheader ip -(struct ipheaderbuffer; Typecasting the buffer to the UDP header structure struct udpheader *udp (struct udpheader *) (buffer + sizeof (struct ipheader)) // Assign value to the IP and UDP header fields. ip->field . . . . udp->field
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started