Last active
February 2, 2016 05:05
-
-
Save ql-owo-lp/4660098 to your computer and use it in GitHub Desktop.
This is the source code for CIS 644 Lab 1. The description of this lab can be found here: http://www.cis.syr.edu/~wedu/seed/Labs/Sniffing_Spoofing/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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." | |
// only one of the following three should be enabled | |
//#define SNIFF_ICMP_ON | |
//#define SNIFF_TCP_PORTRANGE_ON | |
#define SNIFF_TELNET_ON | |
//#define LISTEN_TO_DEV "lo" | |
#include <pcap.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <ctype.h> | |
#include <errno.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
/* 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 << 4 | header length >> 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); | |
#ifdef SNIFF_TELNET_ON | |
void | |
sniff_telnet_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet); | |
#endif | |
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\n", APP_NAME, APP_DESC); | |
printf("%s\n", APP_COPYRIGHT); | |
printf("%s\n", APP_DISCLAIMER); | |
printf("\n"); | |
return; | |
} | |
/* | |
* print help text | |
*/ | |
void | |
print_app_usage(void) | |
{ | |
printf("Usage: %s [interface]\n", APP_NAME); | |
printf("\n"); | |
printf("Options:\n"); | |
printf(" interface Listen on <interface> for packets.\n"); | |
printf("\n"); | |
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 < len; i++) { | |
printf("%02x ", *ch); | |
ch++; | |
/* print extra space after 8th byte for visual aid */ | |
if (i == 7) | |
printf(" "); | |
} | |
/* print space to handle line less than 8 bytes */ | |
if (len < 8) | |
printf(" "); | |
/* fill hex gap with spaces if not full line */ | |
if (len < 16) { | |
gap = 16 - len; | |
for (i = 0; i < gap; i++) { | |
printf(" "); | |
} | |
} | |
printf(" "); | |
/* ascii (if printable) */ | |
ch = payload; | |
for(i = 0; i < len; i++) { | |
if (isprint(*ch)) | |
printf("%c", *ch); | |
else | |
printf("."); | |
ch++; | |
} | |
printf("\n"); | |
return; | |
} | |
/* | |
* print packet payload data (avoid printing binary data) | |
*/ | |
void | |
print_payload(const u_char *payload, int len) | |
{ | |
int len_rem = len; | |
int line_width = 16; /* number of bytes per line */ | |
int line_len; | |
int offset = 0; /* zero-based offset counter */ | |
const u_char *ch = payload; | |
if (len <= 0) | |
return; | |
/* data fits on one line */ | |
if (len <= line_width) { | |
print_hex_ascii_line(ch, len, offset); | |
return; | |
} | |
/* data spans multiple lines */ | |
for ( ;; ) { | |
/* compute current line length */ | |
line_len = line_width % len_rem; | |
/* print line */ | |
print_hex_ascii_line(ch, line_len, offset); | |
/* compute total remaining */ | |
len_rem = len_rem - line_len; | |
/* shift pointer to remaining bytes to print */ | |
ch = ch + line_len; | |
/* add offset */ | |
offset = offset + line_width; | |
/* check if we have line width chars or less */ | |
if (len_rem <= line_width) { | |
/* print last line and get out */ | |
print_hex_ascii_line(ch, len_rem, offset); | |
break; | |
} | |
} | |
return; | |
} | |
/* | |
* dissect/print packet | |
*/ | |
void | |
got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) | |
{ | |
static int count = 1; /* packet counter */ | |
/* declare pointers to packet headers */ | |
const struct sniff_ethernet *ethernet; /* The ethernet header [1] */ | |
const struct sniff_ip *ip; /* The IP header */ | |
const struct sniff_tcp *tcp; /* The TCP header */ | |
const char *payload; /* Packet payload */ | |
int size_ip; | |
int size_tcp; | |
int size_payload; | |
printf("\nPacket number %d:\n", count); | |
count++; | |
/* define ethernet header */ | |
ethernet = (struct sniff_ethernet*)(packet); | |
/* define/compute ip header offset */ | |
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); | |
size_ip = IP_HL(ip)*4; | |
if (size_ip < 20) { | |
printf(" * Invalid IP header length: %u bytes\n", size_ip); | |
return; | |
} | |
/* print source and destination IP addresses */ | |
printf(" From: %s\n", inet_ntoa(ip->ip_src)); | |
printf(" To: %s\n", inet_ntoa(ip->ip_dst)); | |
/* determine protocol */ | |
switch(ip->ip_p) { | |
case IPPROTO_TCP: | |
printf(" Protocol: TCP\n"); | |
break; | |
case IPPROTO_UDP: | |
printf(" Protocol: UDP\n"); | |
return; | |
case IPPROTO_ICMP: | |
printf(" Protocol: ICMP\n"); | |
return; | |
case IPPROTO_IP: | |
printf(" Protocol: IP\n"); | |
return; | |
default: | |
printf(" Protocol: unknown\n"); | |
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 < 20) { | |
printf(" * Invalid TCP header length: %u bytes\n", size_tcp); | |
return; | |
} | |
/* 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); | |
printf(" Src port: %d\n", ntohs(tcp->th_sport)); | |
printf(" Dst port: %d\n", ntohs(tcp->th_dport)); | |
/* | |
* Print payload data; it might be binary, so don't just | |
* treat it as a string. | |
*/ | |
if (size_payload > 0) { | |
printf(" Payload (%d bytes):\n", size_payload); | |
print_payload(payload, size_payload); | |
} | |
return; | |
} | |
#ifdef SNIFF_TELNET_ON | |
/* | |
* a little change to the got_packet so that we can extract the telnet password | |
*/ | |
void | |
sniff_telnet_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) | |
{ | |
static int count = 1; /* packet counter */ | |
/* declare pointers to packet headers */ | |
const struct sniff_ethernet *ethernet; /* The ethernet header [1] */ | |
const struct sniff_ip *ip; /* The IP header */ | |
const struct sniff_tcp *tcp; /* The TCP header */ | |
const char *payload; /* Packet payload */ | |
int size_ip; | |
int size_tcp; | |
int size_payload; | |
/* define ethernet header */ | |
ethernet = (struct sniff_ethernet*)(packet); | |
/* define/compute ip header offset */ | |
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); | |
size_ip = IP_HL(ip)*4; | |
if (ip->ip_p != IPPROTO_TCP || size_ip < 20) // just ignore this invalid packet | |
return; | |
/* define/compute tcp header offset */ | |
tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); | |
size_tcp = TH_OFF(tcp)*4; | |
if (size_tcp < 20) { | |
printf(" * Invalid TCP header length: %u bytes\n", size_tcp); | |
return; | |
} | |
/* 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); | |
// just ignore the 0 payload packets | |
if (size_payload <= 0) | |
return; | |
printf("\n#%d Telnet Packet captured! (%s -> %s)\n", count, inet_ntoa(ip->ip_src), inet_ntoa(ip->ip_dst)); | |
print_payload(payload, size_payload); | |
count++; | |
return; | |
} | |
#endif | |
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 */ | |
// find filter expression man page here: http://goo.gl/AKph8 | |
#if defined(SNIFF_TELNET_ON) | |
char filter_exp[] = "tcp port 23"; // get telnet packets | |
#elif defined(SNIFF_ICMP_ON) | |
char filter_exp[] = "icmp and (src host 10.219.219.126 and dst host 8.8.8.8) or (src host 8.8.8.8 and dst host 10.219.219.126)"; // get icmp packets between two specific hosts | |
#elif defined(SNIFF_TCP_PORTRANGE_ON) | |
char filter_exp[] = "tcp dst portrange 10-100"; // get tcp packets with specific port range | |
#else | |
char filter_exp[] = "ip"; /* filter expression [3] */ | |
#endif | |
#ifdef LISTEN_TO_DEV | |
dev = LISTEN_TO_DEV; // listen to loopback address | |
#endif | |
struct bpf_program fp; /* compiled filter program (expression) */ | |
bpf_u_int32 mask; /* subnet mask */ | |
bpf_u_int32 net; /* ip */ | |
int num_packets = -1; /* number of packets to capture, set -1 here to capture all packets until the program being stopped */ | |
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\n\n"); | |
print_app_usage(); | |
exit(EXIT_FAILURE); | |
} | |
else if (dev == NULL) { // when device is not specific | |
/* 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\n", | |
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\n", | |
dev, errbuf); | |
net = 0; | |
mask = 0; | |
} | |
/* print capture info */ | |
printf("Device: %s\n", dev); | |
printf("Number of packets: %d\n", num_packets); | |
printf("Filter expression: %s\n", 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\n", 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\n", 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\n", | |
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\n", | |
filter_exp, pcap_geterr(handle)); | |
exit(EXIT_FAILURE); | |
} | |
/* now we can set our callback function */ | |
#ifdef SNIFF_TELNET_ON | |
pcap_loop(handle, num_packets, sniff_telnet_packet, NULL); | |
#else | |
pcap_loop(handle, num_packets, got_packet, NULL); | |
#endif | |
/* cleanup */ | |
pcap_freecode(&fp); | |
pcap_close(handle); | |
printf("\nCapture complete.\n"); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* For Problem 8 only | |
* Sniff and spoof icmp packet */ | |
#define APP_NAME "sniffex" | |
#define APP_DESC "Sniffer example using libpcap" | |
#define APP_COPYRIGHT "Copyright (c) 2006 The Tcpdump Group" | |
#define APP_DISCLAIMER "THERE IS ABSOLUTELY NO WARRANTY FOR THIS PROGRAM." | |
#include <pcap.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <ctype.h> | |
#include <errno.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <net/ethernet.h> | |
#include <netinet/in.h> | |
#include <netinet/ip.h> | |
#include <netinet/ip_icmp.h> | |
#include <arpa/inet.h> | |
/* default snap length (maximum bytes per packet to capture) */ | |
#define SNAP_LEN 1518 | |
/* ethernet headers are always exactly 14 bytes [1] */ | |
#define SIZE_ETHERNET sizeof(struct ethhdr) | |
/* Spoofed packet containing only IP and ICMP headers */ | |
struct spoof_packet | |
{ | |
struct ip iph; | |
struct icmp icmph; | |
}; | |
void | |
got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet); | |
void | |
print_app_banner(void); | |
void | |
print_app_usage(void); | |
/* | |
* app name/banner | |
*/ | |
void | |
print_app_banner(void) | |
{ | |
printf("%s - %s\n", APP_NAME, APP_DESC); | |
printf("%s\n", APP_COPYRIGHT); | |
printf("%s\n", APP_DISCLAIMER); | |
printf("\n"); | |
return; | |
} | |
/* | |
* print help text | |
*/ | |
void | |
print_app_usage(void) | |
{ | |
printf("Usage: %s [interface]\n", APP_NAME); | |
printf("\n"); | |
printf("Options:\n"); | |
printf(" interface Listen on <interface> for packets.\n"); | |
printf("\n"); | |
return; | |
} | |
/* | |
* Generates ip/icmp header checksums using 16 bit words. nwords is number of 16 bit words | |
*/ | |
unsigned short in_cksum(unsigned short *addr, int len) | |
{ | |
int nleft = len; | |
int sum = 0; | |
unsigned short *w = addr; | |
unsigned short answer = 0; | |
while (nleft > 1) { | |
sum += *w++; | |
nleft -= 2; | |
} | |
if (nleft == 1) { | |
*(unsigned char *) (&answer) = *(unsigned char *) w; | |
sum += answer; | |
} | |
sum = (sum >> 16) + (sum & 0xFFFF); | |
sum += (sum >> 16); | |
answer = ~sum; | |
return (answer); | |
} | |
/* | |
* dissect/print packet | |
*/ | |
void | |
got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) | |
{ | |
static int count = 1; /* packet counter */ | |
int s; // socket | |
const int on = 1; | |
/* declare pointers to packet headers */ | |
const struct ether_header *ethernet = (struct ether_header*)(packet); | |
const struct ip *iph; /* The IP header */ | |
const struct icmp *icmph; /* The ICMP header */ | |
struct sockaddr_in dst; | |
int size_ip; | |
/* define/compute ip header offset */ | |
iph = (struct ip*)(packet + SIZE_ETHERNET); | |
size_ip = iph->ip_hl*4; // size of ip header | |
if (iph->ip_p != IPPROTO_ICMP || size_ip < 20) { // disregard other packets | |
return; | |
} | |
/* define/compute icmp header offset */ | |
icmph = (struct icmp*)(packet + SIZE_ETHERNET + size_ip); | |
/* print source and destination IP addresses */ | |
printf("%d) ICMP Sniff: from--%s\n", count, inet_ntoa(iph->ip_src) ); | |
/* Construct the spoof packet and allocate memory with the lengh of the datagram */ | |
char buf[htons(iph->ip_len)]; | |
struct spoof_packet *spoof = (struct spoof_packet *) buf; | |
/* Initialize the structure spoof by copying everything in request packet to spoof packet*/ | |
memcpy(buf, iph, htons(iph->ip_len)); | |
/* Modify ip header */ | |
//swap the destination ip address and source ip address | |
(spoof->iph).ip_src = iph->ip_dst; | |
(spoof->iph).ip_dst = iph->ip_src; | |
//recompute the checksum, you can leave it to 0 here since RAW socket will compute it for you. | |
(spoof->iph).ip_sum = 0; | |
/* Modify icmp header */ | |
// set the spoofed packet as echo-reply | |
(spoof->icmph).icmp_type = ICMP_ECHOREPLY; | |
// always set code to 0 | |
(spoof->icmph).icmp_code = 0; | |
(spoof->icmph).icmp_cksum = 0; // should be set as 0 first to recalculate. | |
(spoof->icmph).icmp_cksum = in_cksum((unsigned short *) &(spoof->icmph), sizeof(spoof->icmph)); | |
//print the forged packet information | |
printf("forged packet src is %s\n",inet_ntoa((spoof->iph).ip_src)); | |
printf("forged packet det is %s\n\n",inet_ntoa((spoof->iph).ip_dst)); | |
memset(&dst, 0, sizeof(dst)); | |
dst.sin_family = AF_INET; | |
dst.sin_addr.s_addr = (spoof->iph).ip_dst.s_addr; | |
/* create RAW socket */ | |
if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { | |
printf("socket() error"); | |
return; | |
} | |
/* socket options, tell the kernel we provide the IP structure */ | |
if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) { | |
printf("setsockopt() for IP_HDRINCL error"); | |
return; | |
} | |
if(sendto(s, buf, sizeof(buf), 0, (struct sockaddr *) &dst, sizeof(dst)) < 0) { | |
printf("sendto() error"); | |
} | |
close(s); // free resource | |
//free(buf); | |
count++; | |
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[] = "icmp[icmptype]=icmp-echo"; /* 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 = -1; /* number of packets to capture, set -1 to capture all */ | |
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\n\n"); | |
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\n", | |
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\n", | |
dev, errbuf); | |
net = 0; | |
mask = 0; | |
} | |
/* print capture info */ | |
printf("Device: %s\n", dev); | |
printf("Number of packets: %d\n", num_packets); | |
printf("Filter expression: %s\n", 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\n", 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\n", 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\n", | |
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\n", | |
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("\nCapture complete.\n"); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
gcc sniffex.c -o sniffex -lpcap | |
gcc SniffAndSpoof.c -o SniffAndSpoof -lpcap |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//---cat rawtcp.c--- | |
// Run as root or SUID 0, just datagram no data/payload | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <netinet/ip.h> | |
#include <netinet/tcp.h> | |
#include <arpa/inet.h> | |
// Packet length | |
#define PCKT_LEN 8192 | |
// Simple checksum function, may use others such as Cyclic Redundancy Check, CRC | |
unsigned short csum(unsigned short *buf, int len) | |
{ | |
unsigned long sum; | |
for(sum=0; len>0; len--) | |
sum += *buf++; | |
sum = (sum >> 16) + (sum &0xffff); | |
sum += (sum >> 16); | |
return (unsigned short)(~sum); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
int sd; | |
// No data, just datagram | |
char buffer[PCKT_LEN]; | |
// The size of the headers | |
struct ip *iph = (struct ip *) buffer; | |
struct tcphdr *tcp = (struct tcphdr *) (buffer + sizeof(struct ip)); | |
struct sockaddr_in sin, din; | |
const int one = 1; | |
memset(buffer, 0, PCKT_LEN); | |
if(argc != 5) | |
{ | |
printf("- Invalid parameters!!!\n"); | |
printf("- Usage: %s <source hostname/IP> <source port> <target hostname/IP> <target port>\n", argv[0]); | |
exit(-1); | |
} | |
sd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP); | |
if(sd < 0) | |
{ | |
perror("socket() error"); | |
exit(-1); | |
} | |
else | |
printf("socket()-SOCK_RAW and tcp protocol is OK.\n"); | |
// The source is redundant, may be used later if needed | |
// Address family | |
sin.sin_family = AF_INET; | |
din.sin_family = AF_INET; | |
// Source port, can be any, modify as needed | |
sin.sin_port = htons(atoi(argv[2])); | |
din.sin_port = htons(atoi(argv[4])); | |
// Source IP, can be any, modify as needed | |
sin.sin_addr.s_addr = inet_addr(argv[1]); | |
din.sin_addr.s_addr = inet_addr(argv[3]); | |
// IP structure | |
iph->ip_hl=5; | |
iph->ip_v=4; | |
iph->ip_tos = 16; // Low delay | |
iph->ip_len = sizeof(struct ip) + sizeof(struct tcphdr); | |
iph->ip_id = htons(54321); | |
iph->ip_off = 0; | |
iph->ip_ttl = 64; | |
iph->ip_p = 6; // TCP | |
iph->ip_sum = 0; // Done by kernel | |
// Source IP, modify as needed, spoofed, we accept through command line argument | |
(iph->ip_src).s_addr = inet_addr(argv[1]); | |
// Destination IP, modify as needed, but here we accept through command line argument | |
(iph->ip_dst).s_addr = inet_addr(argv[3]); | |
// The TCP structure. The source port, spoofed, we accept through the command line | |
tcp->source = htons(atoi(argv[2])); | |
// The destination port, we accept through command line | |
tcp->dest = htons(atoi(argv[4])); | |
tcp->seq = htonl(1); | |
tcp->ack_seq = 0; | |
tcp->doff = 5; | |
tcp->syn = 1; | |
tcp->ack = 0; | |
tcp->window = htons(32767); | |
tcp->check = 0; // Done by kernel | |
tcp->urg_ptr = 0; | |
// IP checksum calculation | |
//ip->ip_sum = csum((unsigned short *) buffer, (sizeof(struct ip) + sizeof(struct tcphdr))); | |
// Inform the kernel do not fill up the headers' structure, we fabricated our own | |
if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) < 0) | |
{ | |
perror("setsockopt() error"); | |
exit(-1); | |
} | |
else | |
printf("setsockopt() is OK\n"); | |
printf("Using:::::Source IP: %s port: %u, Target IP: %s port: %u.\n", argv[1], atoi(argv[2]), argv[3], atoi(argv[4])); | |
// sendto() loop, send every 2 second for 50 counts | |
unsigned int count; | |
for(count = 0; count < 20; count++) | |
{ | |
if(sendto(sd, buffer, iph->ip_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0) | |
// Verify | |
{ | |
perror("sendto() error"); | |
exit(-1); | |
} | |
else | |
printf("Count #%u - sendto() is OK\n", count); | |
sleep(2); | |
} | |
close(sd); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ----rawudp.c------ | |
// Must be run by root lol! Just datagram, no payload/data | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <netinet/ip.h> | |
#include <netinet/udp.h> | |
#include <arpa/inet.h> | |
// The packet length | |
#define PCKT_LEN 8192 | |
// Function for checksum calculation. From the RFC, | |
// the checksum algorithm is: | |
// "The checksum field is the 16 bit one's complement of the one's | |
// complement sum of all 16 bit words in the header. For purposes of | |
// computing the checksum, the value of the checksum field is zero." | |
unsigned short csum(unsigned short *buf, int nwords) | |
{ // | |
unsigned long sum; | |
for(sum=0; nwords>0; nwords--) | |
sum += *buf++; | |
sum = (sum >> 16) + (sum &0xffff); | |
sum += (sum >> 16); | |
return (unsigned short)(~sum); | |
} | |
// Source IP, source port, target IP, target port from the command line arguments | |
int main(int argc, char *argv[]) | |
{ | |
int sd; | |
// No data/payload just datagram | |
char buffer[PCKT_LEN]; | |
// Our own headers' structures | |
struct ip *iph = (struct ip *) buffer; | |
struct udphdr *udph = (struct udphdr *) (buffer + sizeof(struct ip)); | |
// Source and destination addresses: IP and port | |
struct sockaddr_in sin, din; | |
const int one = 1; | |
memset(buffer, 0, PCKT_LEN); | |
if(argc != 5) | |
{ | |
printf("- Invalid parameters!!!\n"); | |
printf("- Usage %s <source hostname/IP> <source port> <target hostname/IP> <target port>\n", argv[0]); | |
exit(-1); | |
} | |
// Create a raw socket with UDP protocol | |
sd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP); | |
if(sd < 0) | |
{ | |
perror("socket() error"); | |
// If something wrong just exit | |
exit(-1); | |
} | |
else | |
printf("socket() - Using SOCK_RAW socket and UDP protocol is OK.\n"); | |
// The source is redundant, may be used later if needed | |
// The address family | |
sin.sin_family = AF_INET; | |
din.sin_family = AF_INET; | |
// Port numbers | |
sin.sin_port = htons(atoi(argv[2])); | |
din.sin_port = htons(atoi(argv[4])); | |
// IP addresses | |
sin.sin_addr.s_addr = inet_addr(argv[1]); | |
din.sin_addr.s_addr = inet_addr(argv[3]); | |
// Fabricate the IP header or we can use the | |
// standard header structures but assign our own values. | |
iph->ip_hl=5; | |
iph->ip_v=4; | |
iph->ip_tos = 16; // Low delay | |
iph->ip_len = sizeof(struct ip) + sizeof(struct udphdr); | |
iph->ip_id = htons(54321); | |
iph->ip_ttl = 64; // hops | |
iph->ip_p = 17; // UDP | |
// Source IP address, can use spoofed address here!!! | |
(iph->ip_src).s_addr = inet_addr(argv[1]); | |
// The destination IP address | |
(iph->ip_dst).s_addr = inet_addr(argv[3]); | |
// Fabricate the UDP header. Source port number, redundant | |
udph->source = htons(atoi(argv[2])); | |
// Destination port number | |
udph->dest = htons(atoi(argv[4])); | |
udph->len = htons(sizeof(struct udphdr)); | |
// Calculate the checksum for integrity | |
//iph->ip_sum = csum((unsigned short *)buffer, sizeof(struct ip) + sizeof(struct udphdr)); | |
// Inform the kernel do not fill up the packet structure. we will build our own... | |
if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) < 0) | |
{ | |
perror("setsockopt() error"); | |
exit(-1); | |
} | |
else | |
printf("setsockopt() is OK.\n"); | |
// Send loop, send for every 2 second for 100 count | |
printf("Trying...\n"); | |
printf("Using raw socket and UDP protocol\n"); | |
printf("Using Source IP: %s port: %u, Target IP: %s port: %u.\n", argv[1], atoi(argv[2]), argv[3], atoi(argv[4])); | |
int count; | |
for(count = 1; count <=20; count++) | |
{ | |
if(sendto(sd, buffer, iph->ip_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0) | |
// Verify | |
{ | |
perror("sendto() error"); | |
exit(-1); | |
} | |
else | |
{ | |
printf("Count #%u - sendto() is OK.\n", count); | |
sleep(2); | |
} | |
} | |
close(sd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment