以ä¸ã®ã¨ã³ããªã¯ä¸é¨èª¤èªãå«ã¾ãã¦ããã®ã§ãä¸è¨ã¨ã³ããªã«ãã®æ¨ãã¾ã¨ãã¾ããã®ã§å¾¡è¦§ãã ããã
ã¨ããäºæ
ã§ããã«ã¦ã§ã¢ä¸ããé«éã«ãªã¢ã¼ããã¹ãã®ãã¼ãã®Listenãã§ãã¯ãããããªãã¾ããããã¼ã«ã«ãã¹ãã®ãã¼ãã§ããã°ã/proc
ãnetlinkãªã©ã使ã£ã¦ç´ æ©ããã§ãã¯ããæ¹æ³ãããã¾ãããä»åã¯å¯¾è±¡ããªã¢ã¼ããã¹ããªã®ã§ã½ã±ããã§ãªãã¨ãããå¿
è¦ãããã¾ãã
ããã§ã誰ããã¾ãæãã¤ãã®ã¯ãconnect()
ã·ã¹ãã ã³ã¼ã«ã«ãã£ã¦ãªã¢ã¼ããã¹ãã®ãã¼ãã«æ¥ç¶ãã«ãã£ã¦ãconnectã§ããã°OKãã§ããªããã°NGã¨å¤å®ããæ¹æ³ãããå¾ãã§ããããï¼é«è² è·æã«æ¥ç¶ã§ããªããã¿ã¼ã³ã¯Listenãã¦ããªãã¨å¤å®ãã¦ããï¼
ããã§ä¸æ¦ãæä½ésocket()
ã·ã¹ãã ã³ã¼ã«ã¨connect()
ã·ã¹ãã ã³ã¼ã«ã§æ¥ç¶ããæã®ãã±ãããtcpdumpã§çºãã¦ã¿ã¾ãã
06:35:01.857749 IP (tos 0x0, ttl 64, id 27212, offset 0, flags [DF], proto TCP (6), length 60) 127.0.0.1.47498 > 127.0.0.1.53: Flags [S], cksum 0xfe30 (incorrect -> 0x73a5), seq 3957461550, win 43690, options [mss 65495,sackOK,TS val 22509666 ecr 0,nop,wscale 7], length 0 06:35:01.857757 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 127.0.0.1.53 > 127.0.0.1.47498: Flags [S.], cksum 0xfe30 (incorrect -> 0x2020), seq 2210551288, ack 3957461551, win 43690, options [mss 65495,sackOK,TS val 22509666 ecr 22509666,nop,wscale 7], length 0 06:35:01.857765 IP (tos 0x0, ttl 64, id 27213, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.47498 > 127.0.0.1.53: Flags [.], cksum 0xfe28 (incorrect -> 0xf264), seq 1, ack 1, win 342, options [nop,nop,TS val 22509666 ecr 22509666], length 0 06:35:01.858468 IP (tos 0x0, ttl 64, id 36578, offset 0, flags [DF], proto TCP (6), length 60) 127.0.0.1.47500 > 127.0.0.1.53: Flags [S], cksum 0xfe30 (incorrect -> 0xeada), seq 2421749376, win 43690, options [mss 65495,sackOK,TS val 22509666 ecr 0,nop,wscale 7], length 0 06:35:01.858474 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 127.0.0.1.53 > 127.0.0.1.47500: Flags [S.], cksum 0xfe30 (incorrect -> 0x77bf), seq 3628867844, ack 2421749377, win 43690, options [mss 65495,sackOK,TS val 22509666 ecr 22509666,nop,wscale 7], length 0 06:35:01.858539 IP (tos 0x0, ttl 64, id 36579, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.47500 > 127.0.0.1.53: Flags [.], cksum 0xfe28 (incorrect -> 0x4a04), seq 1, ack 1, win 342, options [nop,nop,TS val 22509666 ecr 22509666], length 0 06:35:01.858754 IP (tos 0x0, ttl 64, id 41537, offset 0, flags [DF], proto TCP (6), length 60) 127.0.0.1.47502 > 127.0.0.1.53: Flags [S], cksum 0xfe30 (incorrect -> 0x8919), seq 242604579, win 43690, options [mss 65495,sackOK,TS val 22509666 ecr 0,nop,wscale 7], length 0 06:35:01.858759 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 127.0.0.1.53 > 127.0.0.1.47502: Flags [S.], cksum 0xfe30 (incorrect -> 0x854e), seq 71402943, ack 242604580, win 43690, options [mss 65495,sackOK,TS val 22509666 ecr 22509666,nop,wscale 7], length 0 06:35:01.858765 IP (tos 0x0, ttl 64, id 41538, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.47502 > 127.0.0.1.53: Flags [.], cksum 0xfe28 (incorrect -> 0x5793), seq 1, ack 1, win 342, options [nop,nop,TS val 22509666 ecr 22509666], length 0
ãµããããconnectæåæã¯9ãã±ããã®ãã±ããéåä¿¡ãçºçãã¦ãã¾ããããããè¦ãã¨ããã¼ãã®ãã§ãã¯ã ãããããã®ã«9ãã±ããã£ã¦ã6ãã±ããåãããã¯ç¡é§ã«æãã¾ããããTCPã®3wayhandshakeçã«ã¯ãsynãã±ããéã£ã¦syn+ackãããã£ã¦ããã°ããã§åºæ¬ã¯Listenãã¦ããã¨ã¿ãªããã®ã ãããsynãã±ããéä¿¡âsyn+ackãã±ããåä¿¡ârstãã±ããéä¿¡ãã®3ãã±ããã§ååãªããã§ããããã ã£ãããã¦ã¼ã¶ã©ã³ãã«ç°¡æTCPã¹ã¿ãã¯ãèªä½ãã¦ãsynãã±ãããä½ã£ã¦RAWã½ã±ãããä»ãã¦æ»ãã®ãã±ãããåä¿¡ãã¦ããã°è¯ãããã§ããã
2017/02/13追è¨
@matsumotory è¨äºåé ã®9ãã±ããçºçãã¦ãããã±ããã®ãã³ããªãã§ããã©ããã¼ã«ã«ãã¼ããå¤ããªãã3åãã³ãã·ã§ã¤ã¯ãã¦ããããã«è¦ããã®ã§ããè²¼ãééãã ã£ãããã¾ãã..ï¼
— ã¿ãã³ (@pandax381) 2017å¹´2æ13æ¥
ã«ããææã®éããå®éã¯æ®éã«connectãã¦closeããã¨ä»¥ä¸ã®ãããªtcpdumpã§ãããå ¨é¨ã§æ®éã¯6ãã±ããã§ããã
09:13:59.353115 IP (tos 0x0, ttl 64, id 45250, offset 0, flags [DF], proto TCP (6), length 60) 127.0.0.1.47536 > 127.0.0.1.53: Flags [S], cksum 0xfe30 (incorrect -> 0xd259), seq 3532090005, win 43690, options [mss 65495,sackOK,TS val 24894039 ecr 0,nop,wscale 7], length 0 09:13:59.353128 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 127.0.0.1.53 > 127.0.0.1.47536: Flags [S.], cksum 0xfe30 (incorrect -> 0x4130), seq 394239430, ack 3532090006, win 43690, options [mss 65495,sackOK,TS val 24894039 ecr 24894039,nop,wscale 7], length 0 09:13:59.353140 IP (tos 0x0, ttl 64, id 45251, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.47536 > 127.0.0.1.53: Flags [.], cksum 0xfe28 (incorrect -> 0x1375), seq 1, ack 1, win 342, options [nop,nop,TS val 24894039 ecr 24894039], length 0 09:14:04.641694 IP (tos 0x0, ttl 64, id 45252, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.47536 > 127.0.0.1.53: Flags [F.], cksum 0xfe28 (incorrect -> 0x0e49), seq 1, ack 1, win 342, options [nop,nop,TS val 24895362 ecr 24894039], length 0 09:14:04.642176 IP (tos 0x0, ttl 64, id 18320, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.53 > 127.0.0.1.47536: Flags [F.], cksum 0xfe28 (incorrect -> 0x091d), seq 1, ack 2, win 342, options [nop,nop,TS val 24895362 ecr 24895362], length 0 09:14:04.642189 IP (tos 0x0, ttl 64, id 45253, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.47536 > 127.0.0.1.53: Flags [.], cksum 0xfe28 (incorrect -> 0x091d), seq 2, ack 2, win 342, options [nop,nop,TS val 24895362 ecr 24895362], length 0
ã¦ã¼ã¶ã©ã³ãã«ç°¡æTCPã¹ã¿ãã¯ãä½ã
IPããããTCPããããæ§é ä½ã§å®ç¾©ããããã«ãæåã¯ä»¥ä¸ã®ãããªæ§é ä½ãèªåã§ä½ã£ã¦ãã±ãããä½ã£ã¦ãã¾ããã
#pragma pack(1) struct tcp { __extension__ union { struct { u_int16_t src_port; u_int16_t dst_port; u_int32_t seq; u_int32_t ack; #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ u_int8_t dummy : 4; u_int8_t offset : 4; #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ u_int8_t offset : 4; u_int8_t dummy : 4; #endif u_int8_t flags; u_int16_t win_size; u_int16_t cksum; u_int16_t urg_ptr; }; }; }
ã¡ããã©synãã±ãããéããããã«ãªã£ã¦ããæãããã«ããããã調ã¹ã¦ããã¨#include <netinet/ip.h>
ã#include <netinet/tcp.h>
ãããã«IPããããTCPãããã®æ§é ä½ãæ¢ã«å®ç¾©æ¸ã¿ã§ãããã使ã£ãæ¹ãã ãã¶æ¥½ã ã¨ãããã¨ãåãã£ãã®ã§ããããã®ããããã¡ã¤ã«ãå©ç¨ãã¾ãã
以ä¸ã®ããã«ãRAWã½ã±ãããä½ã£ã¦ãIPããããTCPããããèªåã§å®ç¾©ãã¦ãã±ãããéãã¤ãã¾ããããã«ãã£ã¦ãã¦ã¼ã¶ã©ã³ãã§éåä¿¡ãããã¼ã¿ã«ãTCP/IPããããå«ã¾ããããã«ãªãã¾ããæ¦ã以ä¸ã®ããã«æ¸ããã¨ã«ãªãã¾ãã
int s; int src_port, dst_port; char *dst_host; char packet[4096]; char source_ip[20]; struct sockaddr_in dest; struct pseudo_header psh; struct iphdr *iph = (struct iphdr *)packet; struct tcphdr *tcph = (struct tcphdr *)(packet + sizeof(struct ip)); int flag = 1; const int *val = &flag; src_port = 54321; dst_host = argv[1]; dst_port = atoi(argv[2]); s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if (s < 0) { ERROR("socket"); } if (inet_addr(dst_host) != -1) { dest_ip.s_addr = inet_addr(dst_host); } else { char *ip = hostname_to_ip(dst_host); if (ip != NULL) { printf("%s resolved to %s\n", dst_host, ip); dest_ip.s_addr = inet_addr(hostname_to_ip(dst_host)); } else { printf("Unable to resolve hostname: %s", dst_host); exit(1); } } local_ip(source_ip); memset(packet, 0, 4096); iph->ihl = 5; iph->version = 4; iph->tos = 0; iph->tot_len = sizeof(struct ip) + sizeof(struct tcphdr); iph->id = htons(54321); iph->frag_off = htons(16384); iph->ttl = 64; iph->protocol = IPPROTO_TCP; iph->check = 0; iph->saddr = inet_addr(source_ip); iph->daddr = dest_ip.s_addr; iph->check = cksum((unsigned short *)packet, iph->tot_len >> 1); tcph->source = htons(src_port); tcph->dest = htons(80); tcph->seq = htonl(1105024978); tcph->ack_seq = 0; tcph->doff = sizeof(struct tcphdr) / 4; tcph->fin = 0; tcph->syn = 1; tcph->rst = 0; tcph->psh = 0; tcph->ack = 0; tcph->urg = 0; tcph->window = htons(14600); tcph->check = 0; tcph->urg_ptr = 0; if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, val, sizeof(flag)) < 0) { printf("Error setting IP_HDRINCL. Error number : %d . Error message : %s \n", errno, strerror(errno)); exit(0); } dest.sin_family = AF_INET; dest.sin_addr.s_addr = dest_ip.s_addr; dest.sin_port = ntohs(tcph->dest); tcph->dest = htons(dst_port); tcph->check = 0; psh.source_address = inet_addr(source_ip); psh.dest_address = dest.sin_addr.s_addr; psh.placeholder = 0; psh.protocol = IPPROTO_TCP; psh.tcp_length = htons(sizeof(struct tcphdr)); memcpy(&psh.tcp, tcph, sizeof(struct tcphdr)); tcph->check = cksum((unsigned short *)&psh, sizeof(struct pseudo_header)); if (sendto(s, packet, sizeof(struct iphdr) + sizeof(struct tcphdr), 0, (struct sockaddr *)&dest, sizeof(dest)) < 0) { ERROR("sendto"); }
IPãããã¨TCPãããã®æ§é ä½ããã³ããããµã¤ãºã«æ°ãã¤ããªããpacket
ãããã¡ä¸ã®ãã¤ã³ã¿ã®ä½ç½®ã移åãããIPããã³TCPããããå®ç¾©ãã¦ããã¾ããä»åã¯ãªã¢ã¼ããã¹ãã80ãã¼ããListenãã¦ãããããã§ãã¯ããããã«ããããã®æ
å ±ã¨synãã©ã°ãç«ã¦ãTCPããããä½ãã¾ãããã¾ããIPãããããã³TCPãããã以ä¸ã®ããã«è¨ç®ãã¾ãããã§ãã¯ãµã ã«ã¤ãã¦ã¯ä»åã¯æµãã説æãããã詳細ãçç¥ãã¾ããã°ã°ãã¨æ²¢å±±ã§ã¦ãã¾ãã®ã§ã
unsigned short cksum(unsigned short *ptr, int nbytes) { register long sum; unsigned short oddbyte; register short answer; sum = 0; while (nbytes > 1) { sum += *ptr++; nbytes -= 2; } if (nbytes == 1) { oddbyte = 0; *((u_char *)&oddbyte) = *(u_char *)ptr; sum += oddbyte; } sum = (sum >> 16) + (sum & 0xffff); sum = sum + (sum >> 16); answer = (short)~sum; return (answer); }
ããã¦ããã±ãããä½ããã¨ãã§ãããããããsendto()
ã·ã¹ãã ã³ã¼ã«ã«ãã£ã¦éä¿¡ãã¾ããããã§ããªã¢ã¼ããã¹ãã«å¯¾ãã¦synãã©ã°ã®ãã£ããã±ãããã¦ã¼ã¶ã©ã³ãã§ä½ã£ã¦éããã¨ãã§ãã¾ãã
å®éã«ä¸è¨ã®ãããªãã±ããã®ä½ãæ¹ã§tcpdumpãè¦ãã¨ä»¥ä¸ã®ããã«ãªãã¾ãã
06:54:15.278121 IP (tos 0x0, ttl 64, id 54321, offset 0, flags [DF], proto TCP (6), length 40) 10.0.2.15.54321 > 10.0.2.15.80: Flags [S], cksum 0xf08b (correct), seq 1105024978, win 14600, length 0
ã¡ããã¨synãã±ãããéãã¦ãã¾ããã
å¾ã¯synã¨ackã®ãã©ã°ãç«ã£ããã±ãããåæ§ã«recvfrom()
ããã°è¯ãã ã….ã¨ãªãã¾ãããããã§å¤§ããªåé¡ãçºçãã¾ãã
ã«ã¼ãã«ã®TCPã¹ã¿ãã¯ã«éªéããã
RAWã½ã±ãããä»ãã¦ãã¦ã¼ã¶ã©ã³ãã§èªåã§ä½ã£ããã±ãããéä¿¡ãããã®å¾ãªã¢ã¼ããã¹ãããè¿ãã®ãã±ãããåä¿¡ããå ´åãã¦ã¼ã¶ã©ã³ãã®TCPã¹ã¿ãã¯ã ãã§ãªãã«ã¼ãã«ã®TCPã¹ã¿ãã¯ãééãããã¨ã«ãªãã¾ããããã¨ãã«ã¼ãã«ã®TCPã¹ã¿ãã¯ã¯ãããªè¿ãã®ãã±ããç¥ããªãï¼ã¨ãã£ã¦ãä¸è¦ãªãã±ããã¨ã¿ãªãrstãã©ã°ã®ãã£ããã±ãããè¿ãã¦ããã¾ãã¾ããå®éã«RAWã½ã±ããã§synãã±ãããéã£ãå¾ã®tcpdumpã®åºåãã¦ã¯ä»¥ä¸ã®ããã«ãªãã¾ãã
06:54:15.278121 IP (tos 0x0, ttl 64, id 54321, offset 0, flags [DF], proto TCP (6), length 40) 10.0.2.15.54321 > 10.0.2.15.80: Flags [S], cksum 0xf08b (correct), seq 1105024978, win 14600, length 0 06:54:15.278133 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 44) 10.0.2.15.80 > 10.0.2.15.54321: Flags [S.], cksum 0x183c (incorrect -> 0xbe01), seq 1991915580, ack 1105024979, win 43690, options [mss 65495], length 0 06:54:15.278139 IP (tos 0x0, ttl 64, id 45579, offset 0, flags [DF], proto TCP (6), length 40) 10.0.2.15.54321 > 10.0.2.15.80: Flags [R], cksum 0x2991 (correct), seq 1105024979, win 0, length 0
ããã¯ãã¦ã¼ã¶ã©ã³ãå´ã§TCP/IPããããå«ããã±ãããrecvfrom()
ããªãã¦ãçºçãã¾ããã¨ããã®ããã«ã¼ãã«ã®TCPã¹ã¿ãã¯ãå
ã«rstãã±ãããéã£ã¦ãã¾ã£ã¦ããããã§ãããããªãã¨ããªã¢ã¼ããã¹ãã¯éä¿¡ãçµäºãããã¨ã«ãªãããã®å¾ã«ã¦ã¼ã¶ã©ã³ãã®TCPã¹ã¿ãã¯ããrecvfrom
ããã¨ãã¦ãæ¥ç¶ã¯åãã¦ããã¨å¤å®(è¿ãå¤0)ããããã±ãããåä¿¡ã§ããªããªãã¾ããçµæãã¦ã¼ã¶ã©ã³ãTCPã¹ã¿ãã¯ä¸ã§syn+ackãã±ãããè¿ã£ã¦ãããã¨ãå¤å®ã§ãã¾ããã
ããã§ãã¦ã¼ã¶ã©ã³ãã§ããããç¥ãæ¹æ³ã¨ãã¦ä»¥ä¸ã®2ã¤ã®æ¦ç¥ããããã¾ãã
- ã«ã¼ãã«ã®TCPã¹ã¿ãã¯ãrstãéããããéãã¦ã¼ã¶ã©ã³ãã§ãã±ãããåä¿¡ãã
- ã¦ã¼ã¶ã©ã³ãã®TCPã¹ã¿ãã¯ã§ãã±ãããå¦çããªããBPFçµç±ã§ãã±ãããã¢ãã¿ãªã³ã°ãã
ã§ã¯ãããããã®æ¹éã§å®è£ ãé²ãã¦ã¿ã¾ãããã
ã«ã¼ãã«ã®TCPã¹ã¿ãã¯ãrstãéããããéãã¦ã¼ã¶ã©ã³ãã§ãã±ãããåä¿¡ãã
ãã±ãããã«ã¼ãã«ã®TCPã¹ã¿ãã¯ãç»ãåã«ãRAWã½ã±ããã¨ãã¦ã¯ã¦ã¼ã¶ã©ã³ãå´ã«ãã³ãã¼ãããã¯ããªã®ã§ãã«ã¼ãã«ã®TCPã¹ã¿ãã¯ã®å¦çãããå ã«ã¦ã¼ã¶ã©ã³ãå´ã§ãã±ãããåä¿¡ããå¿ è¦ãããã¾ããããã§ãã¦ã¼ã¶ã©ã³ãã®TCPã¹ã¿ãã¯ã§ä½ã£ãsynãã±ãããéä¿¡ããåã«ããããããåä¿¡å°ç¨ã®ã¹ã¬ãããä½ã£ã¦åä¿¡å¦çãã«ã¼ãããã¦å¾ æ©ãã¦ãããsynãã±ããéä¿¡å¾ãè¿ãã®ãã±ãããã§ããã ãéãåä¿¡ã§ããããã«è©¦ã¿ã¦ã¿ã¾ãããã®å ´åã以ä¸ã®ãããªå®è£ ã«ãªãã¾ãã
pthread_t new_packet_reciever_thread; if (pthread_create(&new_packet_reciever_thread, NULL, new_packet_reciever, NULL) < 0) { ERROR("pthread_create"); } dest.sin_family = AF_INET; dest.sin_addr.s_addr = dest_ip.s_addr; dest.sin_port = ntohs(tcph->dest); tcph->dest = htons(dst_port); tcph->check = 0; psh.source_address = inet_addr(source_ip); psh.dest_address = dest.sin_addr.s_addr; psh.placeholder = 0; psh.protocol = IPPROTO_TCP; psh.tcp_length = htons(sizeof(struct tcphdr)); memcpy(&psh.tcp, tcph, sizeof(struct tcphdr)); tcph->check = cksum((unsigned short *)&psh, sizeof(struct pseudo_header)); if (sendto(s, packet, sizeof(struct iphdr) + sizeof(struct tcphdr), 0, (struct sockaddr *)&dest, sizeof(dest)) < 0) { ERROR("sendto"); } pthread_join(new_packet_reciever_thread, NULL);
æµãã¨ãã¦ã¯ãä¸è¨ã®ããã«sendto
åããåä¿¡ã¹ã¬ãããèµ°ããã¦ãããã¹ã¬ããã®å¦çã¯ä»¥ä¸ã®ããã«å®è£
ãã¦ããã¾ãã
/* thread */ void *new_packet_reciever(void *ptr) { int socket_raw, saddr_size, data_size; struct sockaddr saddr; unsigned char *buffer = (unsigned char *)malloc(65536); socket_raw = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if (socket_raw < 0) { ERROR("socket"); } saddr_size = sizeof(saddr); while (1) { data_size = recvfrom(socket_raw, buffer, 65536, 0, (struct sockaddr *)&saddr, &saddr_size); if (data_size < 0) { ERROR("recvfrom"); } if (found_syn_ack_packet(buffer, data_size)) { printf("found syn_ack packet by new_packet_reciever thread\n"); break; } } close(socket_raw); }
ãã®ä¸ã§ãéè¯ãã«ã¼ãã«ãrstãéãããããéãsyn+ackãã±ãããåä¿¡ã§ããå ´åã«ãããã®ãã±ããã表示ããããã«ãã¾ãã
static int found_syn_ack_packet(unsigned char *buffer, int size) { struct iphdr *iph = (struct iphdr *)buffer; struct sockaddr_in source, dest; unsigned short iphdrlen; if (iph->protocol == 6) { struct iphdr *iph = (struct iphdr *)buffer; iphdrlen = iph->ihl * 4; struct tcphdr *tcph = (struct tcphdr *)(buffer + iphdrlen); memset(&source, 0, sizeof(source)); source.sin_addr.s_addr = iph->saddr; memset(&dest, 0, sizeof(dest)); dest.sin_addr.s_addr = iph->daddr; if (tcph->syn == 1 && tcph->ack == 1 && source.sin_addr.s_addr == dest_ip.s_addr) { ip_capture(buffer); return 1; } else { printf("raw packet recieved. but isn't syn_ack packet\n"); } } return 0; }
ããã§ãçå±ä¸ã¯ãã¾ãããããã§ããã¾ããTCPã¹ã¿ãã¯å士ã®å¦çé度ã§ã¯åè² ã«ãªããªãã¯ããªã®ã§ãTCPã¹ã¿ãã¯ã®å¦çãç¡è¦ã§ããã»ã©ã®ã¬ã¤ãã³ã·ã¼ã®ä½ããªã¢ã¼ããã¹ãã§ããã°ãrstãã«ã¼ãã«ãããªã¢ã¼ããã¹ãã«å±ã(1å¾å¾©å)ãããéããã¦ã¼ã¶ã©ã³ãã§syn+ackãåä¿¡(1å¾å¾©)ã§ããå¯è½æ§ã¯é«ããªãããã§ãã
ã¦ã¼ã¶ã©ã³ãã®TCPã¹ã¿ãã¯ã§ãã±ãããå¦çããªããBPFçµç±ã§ãã±ãããã¢ãã¿ãªã³ã°ãã
ããä¸ã¤ã®æ¦ç¥ã¯BPFçµç±ã§ãã±ãããã¢ãã¿ãªã³ã°ããæ¹æ³ã§ããä¸è¬çã«ã¯libpcapãªã©ã使ãã°ããã®ã§ãæ¯è¼çç°¡åã«å®è£ ã§ããã§ãããããã¯ãã¦ã¼ã¶ã©ã³ãã§ãã£ã¦ããã¨è¨ã£ã¦ããã®ãä¸æã§ãããã¨ããããå®è£ ãã¦ã¿ã¾ããããããä¸ã¤ç®ã®æ¦ç¥ã¨åæ§ã«ãã±ãããè¦å¤±ããªãããã«äºãã¹ã¬ãããåããã¦ããã±ãããç£è¦ããããã«ãã¾ããã¾ãã¯ãåæ§ã«ä»¥ä¸ã®ããã«ã¹ã¬ãããä½ãã¾ãã
pthread_t new_packet_capture_run_thread; if (pthread_create(&new_packet_capture_run_thread, NULL, new_packet_capture_run, NULL) < 0) { ERROR("pthread_create"); } dest.sin_family = AF_INET; dest.sin_addr.s_addr = dest_ip.s_addr; dest.sin_port = ntohs(tcph->dest); tcph->dest = htons(dst_port); tcph->check = 0; psh.source_address = inet_addr(source_ip); psh.dest_address = dest.sin_addr.s_addr; psh.placeholder = 0; psh.protocol = IPPROTO_TCP; psh.tcp_length = htons(sizeof(struct tcphdr)); memcpy(&psh.tcp, tcph, sizeof(struct tcphdr)); tcph->check = cksum((unsigned short *)&psh, sizeof(struct pseudo_header)); if (sendto(s, packet, sizeof(struct iphdr) + sizeof(struct tcphdr), 0, (struct sockaddr *)&dest, sizeof(dest)) < 0) { ERROR("sendto"); } pthread_join(new_packet_capture_run_thread, NULL);
recvfrom
ã®ã«ã¼ãæ¦ç¥ã¨åæ§ã§ãããããã«ãã¹ã¬ããä¸ã§BPFã«ãããã±ããã¢ãã¿ãªã³ã°ãå®è£
ãã¾ãã
/* thread */ void *new_packet_capture_run(void *ptr) { pcap_t *pd; char errbuf[PCAP_ERRBUF_SIZE]; bpf_u_int32 netp; bpf_u_int32 maskp; struct bpf_program fprog; struct pcap_userdata pud; char *filter = "dst host 10.0.2.15 and src port 80 and dst port 54321"; char *dev = "enp0s3"; int dl = 0; int dl_len = 0; if ((pd = pcap_open_live(dev, 1514, 1, 500, errbuf)) == NULL) { ERROR("pcap_open_live"); } pcap_lookupnet(dev, &netp, &maskp, errbuf); pcap_compile(pd, &fprog, filter, 0, netp); if (pcap_setfilter(pd, &fprog) == -1) { ERROR("pcap_setfilter"); } pcap_freecode(&fprog); dl = pcap_datalink(pd); switch (dl) { case 1: dl_len = 14; break; default: dl_len = 14; break; } pud.l1_len = dl_len; pud.pd = pd; if (pcap_loop(pd, -1, raw_packet_receiver, (u_char *)&pud) < 0) { printf("found syn_ack packet by new_packet_capture_run thread\n"); } }
pcapã§ãã±ããããã£ã«ã¿ãã¤ã¤ãpcap_loop
ã§ã¢ãã¿ãªã³ã°ãç¶ãã¾ãããã®ä¸ã§ããã±ãããåä¿¡ããããã®ãã±ããã®ãã©ã°ã解æããsyn+ackãªãã±ããã§ããã°ãpcap_loop
ãæããããã«pcap_breakloop
ãå®è¡ãã¾ãããã®ãããã¯libeventã«ãä¼¼ãã¤ã³ã¿ã¼ãã§ã¤ã¹ã«ãªã£ã¦ãã¾ããããã®ã³ã¼ãã®found_syn_ack_packet
ã¯recvfrom
ã«ããåä¿¡ã¹ã¬ããã®ãã®ã¨åä¸ã§ãã
void raw_packet_receiver(u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet) { struct pcap_userdata *pud = (struct pcap_userdata *)udata; if (found_syn_ack_packet((char *)(packet + pud->l1_len), sizeof(struct ip) + sizeof(struct tcphdr))) { pcap_breakloop(pud->pd); } }
å®éã«è©¦ãã¦ã¿ã¾ããã
å®éã«ãããã®ã³ã¼ããå ¨ã¦ã¾ã¨ãããã®ã以ä¸ã«ãªãã¾ããé·ãã§ãã
/* * gcc raw_packet.c -g -lpcap -lpthread -o tcp_port_check * */ #include <stdio.h> #include <string.h> #include <stdint.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <errno.h> #include <netdb.h> #include <arpa/inet.h> #include <netinet/tcp.h> #include <netinet/ip.h> #include <pcap.h> #include <pthread.h> #define ERROR(name) \ perror(name); \ exit(EXIT_FAILURE) struct in_addr dest_ip; struct pcap_userdata { int l1_len; pcap_t *pd; }; struct pseudo_header { unsigned int source_address; unsigned int dest_address; unsigned char placeholder; unsigned char protocol; unsigned short tcp_length; struct tcphdr tcp; }; static void tcp_capture(char *packet) { struct tcphdr *tcphdr; int i; tcphdr = (struct tcphdr *)packet; printf("src port: %d\n", ntohs(tcphdr->source)); printf("dst port: %d\n", ntohs(tcphdr->dest)); printf("sec num: %zu\n", (size_t)ntohl(tcphdr->seq)); printf("ack num: %zu\n", (size_t)ntohl(tcphdr->ack_seq)); printf("reserve : 0x%x\n", tcphdr->res1); printf("offset: 0x%x\n", ntohs(tcphdr->doff)); printf("fin: %x\n", tcphdr->fin); printf("syn: %x\n", tcphdr->syn); printf("rst: %x\n", tcphdr->rst); printf("psh: %x\n", tcphdr->psh); printf("ack: %x\n", tcphdr->ack); printf("urg: %x\n", tcphdr->urg); printf("res2: %x\n", tcphdr->res2); printf("window size: %d\n", ntohs(tcphdr->window)); printf("checksum: 0x%x\n", ntohs(tcphdr->check)); printf("urgent ptr: 0x%x\n", ntohs(tcphdr->urg_ptr)); } static void ip_capture(char *packet) { struct ip *iphdr; iphdr = (struct ip *)packet; printf("ip version: %x\n", iphdr->ip_v); printf("header length: %xbyte\n", iphdr->ip_hl); printf("service type: 0x%.2x\n", iphdr->ip_tos); printf("packet length: �yte\n", ntohs(iphdr->ip_len)); printf("identify: 0x%.4x\n", ntohs(iphdr->ip_id)); printf("flag offset: 0x%.4x\n", ntohs(iphdr->ip_off)); printf("ttl: 0x%.2x\n", iphdr->ip_ttl); switch (iphdr->ip_p) { case 1: printf("protocol: ICMP\n"); break; case 6: printf("protocol: TCP\n"); break; case 17: printf("protocol: UDP\n"); break; default: printf("protocol: 0x%.2x\n", iphdr->ip_p); break; } printf("header checksum: 0x%.4x\n", ntohs(iphdr->ip_sum)); printf("src ipaddress: %s\n", inet_ntoa(iphdr->ip_src)); printf("dst ipaddress: %s\n", inet_ntoa(iphdr->ip_dst)); if (iphdr->ip_p == 6) tcp_capture((char *)(packet + sizeof(struct ip))); } static int found_syn_ack_packet(unsigned char *buffer, int size) { struct iphdr *iph = (struct iphdr *)buffer; struct sockaddr_in source, dest; unsigned short iphdrlen; if (iph->protocol == 6) { struct iphdr *iph = (struct iphdr *)buffer; iphdrlen = iph->ihl * 4; struct tcphdr *tcph = (struct tcphdr *)(buffer + iphdrlen); memset(&source, 0, sizeof(source)); source.sin_addr.s_addr = iph->saddr; memset(&dest, 0, sizeof(dest)); dest.sin_addr.s_addr = iph->daddr; if (tcph->syn == 1 && tcph->ack == 1 && source.sin_addr.s_addr == dest_ip.s_addr) { ip_capture(buffer); return 1; } else { printf("raw packet recieved. but isn't syn_ack packet\n"); } } return 0; } void raw_packet_receiver(u_char *udata, const struct pcap_pkthdr *pkthdr, const u_char *packet) { struct pcap_userdata *pud = (struct pcap_userdata *)udata; if (found_syn_ack_packet((char *)(packet + pud->l1_len), sizeof(struct ip) + sizeof(struct tcphdr))) { pcap_breakloop(pud->pd); } } /* thread */ void *new_packet_capture_run(void *ptr) { pcap_t *pd; char errbuf[PCAP_ERRBUF_SIZE]; bpf_u_int32 netp; bpf_u_int32 maskp; struct bpf_program fprog; struct pcap_userdata pud; char *filter = "dst host 10.0.2.15 and src port 80 and dst port 54321"; char *dev = "enp0s3"; int dl = 0; int dl_len = 0; if ((pd = pcap_open_live(dev, 1514, 1, 500, errbuf)) == NULL) { ERROR("pcap_open_live"); } pcap_lookupnet(dev, &netp, &maskp, errbuf); pcap_compile(pd, &fprog, filter, 0, netp); if (pcap_setfilter(pd, &fprog) == -1) { ERROR("pcap_setfilter"); } pcap_freecode(&fprog); dl = pcap_datalink(pd); switch (dl) { case 1: dl_len = 14; break; default: dl_len = 14; break; } pud.l1_len = dl_len; pud.pd = pd; if (pcap_loop(pd, -1, raw_packet_receiver, (u_char *)&pud) < 0) { printf("found syn_ack packet by new_packet_capture_run thread\n"); } } unsigned short cksum(unsigned short *ptr, int nbytes) { register long sum; unsigned short oddbyte; register short answer; sum = 0; while (nbytes > 1) { sum += *ptr++; nbytes -= 2; } if (nbytes == 1) { oddbyte = 0; *((u_char *)&oddbyte) = *(u_char *)ptr; sum += oddbyte; } sum = (sum >> 16) + (sum & 0xffff); sum = sum + (sum >> 16); answer = (short)~sum; return (answer); } char *hostname_to_ip(char *hostname) { struct hostent *he; struct in_addr **addr_list; int i; if ((he = gethostbyname(hostname)) == NULL) { herror("gethostbyname"); return NULL; } addr_list = (struct in_addr **)he->h_addr_list; for (i = 0; addr_list[i] != NULL; i++) { return inet_ntoa(*addr_list[i]); } return NULL; } int local_ip(char *buffer) { int err; int sock; const char *p; struct sockaddr_in serv; struct sockaddr_in name; socklen_t namelen; sock = socket(AF_INET, SOCK_DGRAM, 0); memset(&serv, 0, sizeof(serv)); serv.sin_family = AF_INET; serv.sin_addr.s_addr = inet_addr("8.8.8.8"); serv.sin_port = htons(53); err = connect(sock, (const struct sockaddr *)&serv, sizeof(serv)); namelen = sizeof(name); err = getsockname(sock, (struct sockaddr *)&name, &namelen); p = inet_ntop(AF_INET, &name.sin_addr, buffer, 100); close(sock); } /* thread */ void *new_packet_reciever(void *ptr) { int socket_raw, saddr_size, data_size; struct sockaddr saddr; unsigned char *buffer = (unsigned char *)malloc(65536); socket_raw = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if (socket_raw < 0) { ERROR("socket"); } saddr_size = sizeof(saddr); while (1) { data_size = recvfrom(socket_raw, buffer, 65536, 0, (struct sockaddr *)&saddr, &saddr_size); if (data_size < 0) { ERROR("recvfrom"); } if (found_syn_ack_packet(buffer, data_size)) { printf("found syn_ack packet by new_packet_reciever thread\n"); break; } } close(socket_raw); } int main(int argc, char **argv) { int s; int src_port, dst_port; char *dst_host; char packet[4096]; char source_ip[20]; struct sockaddr_in dest; struct pseudo_header psh; struct iphdr *iph = (struct iphdr *)packet; struct tcphdr *tcph = (struct tcphdr *)(packet + sizeof(struct ip)); int flag = 1; const int *val = &flag; if (argc != 3) { printf("dst_host dst_port \n"); exit(1); } src_port = 54321; dst_host = argv[1]; dst_port = atoi(argv[2]); s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if (s < 0) { ERROR("socket"); } if (inet_addr(dst_host) != -1) { dest_ip.s_addr = inet_addr(dst_host); } else { char *ip = hostname_to_ip(dst_host); if (ip != NULL) { printf("%s resolved to %s\n", dst_host, ip); dest_ip.s_addr = inet_addr(hostname_to_ip(dst_host)); } else { printf("Unable to resolve hostname: %s", dst_host); exit(1); } } local_ip(source_ip); memset(packet, 0, 4096); iph->ihl = 5; iph->version = 4; iph->tos = 0; iph->tot_len = sizeof(struct ip) + sizeof(struct tcphdr); iph->id = htons(54321); iph->frag_off = htons(16384); iph->ttl = 64; iph->protocol = IPPROTO_TCP; iph->check = 0; iph->saddr = inet_addr(source_ip); iph->daddr = dest_ip.s_addr; iph->check = cksum((unsigned short *)packet, iph->tot_len >> 1); tcph->source = htons(src_port); tcph->dest = htons(80); tcph->seq = htonl(1105024978); tcph->ack_seq = 0; tcph->doff = sizeof(struct tcphdr) / 4; tcph->fin = 0; tcph->syn = 1; tcph->rst = 0; tcph->psh = 0; tcph->ack = 0; tcph->urg = 0; tcph->window = htons(14600); tcph->check = 0; tcph->urg_ptr = 0; if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, val, sizeof(flag)) < 0) { printf("Error setting IP_HDRINCL. Error number : %d . Error message : %s \n", errno, strerror(errno)); exit(0); } pthread_t new_packet_capture_run_thread; if (pthread_create(&new_packet_capture_run_thread, NULL, new_packet_capture_run, NULL) < 0) { ERROR("pthread_create"); } pthread_t new_packet_reciever_thread; if (pthread_create(&new_packet_reciever_thread, NULL, new_packet_reciever, NULL) < 0) { ERROR("pthread_create"); } dest.sin_family = AF_INET; dest.sin_addr.s_addr = dest_ip.s_addr; dest.sin_port = ntohs(tcph->dest); tcph->dest = htons(dst_port); tcph->check = 0; psh.source_address = inet_addr(source_ip); psh.dest_address = dest.sin_addr.s_addr; psh.placeholder = 0; psh.protocol = IPPROTO_TCP; psh.tcp_length = htons(sizeof(struct tcphdr)); memcpy(&psh.tcp, tcph, sizeof(struct tcphdr)); tcph->check = cksum((unsigned short *)&psh, sizeof(struct pseudo_header)); if (sendto(s, packet, sizeof(struct iphdr) + sizeof(struct tcphdr), 0, (struct sockaddr *)&dest, sizeof(dest)) < 0) { ERROR("sendto"); } pthread_join(new_packet_capture_run_thread, NULL); pthread_join(new_packet_reciever_thread, NULL); return 0; }
ããã以ä¸ã®ããã«ãã«ããã¾ãã
gcc raw_packet.c -g -lpcap -lpthread -o tcp_port_check
å®è¡ã¯ãRAWã½ã±ãããæ±ãããCAP_NET_ADMINã®ç¹æ¨©ãå¿ è¦ã¨ãªãã®ã§ãsudoã§å®è¡ãã¾ãã
sudo ./tcp_port_check 10.0.2.15 80
ããã«ãããã«ã¼ãã«ãããéãã¦ã¼ã¶ã©ã³ãã®TCPã¹ã¿ãã¯ã§ãããããã¨ãã§ããããã±ããã®ãã³ãã表示ãããã¯ããã§ã¯å®è¡ãã¦ã¿ã¾ãããã
raw packet recieved. but isn't syn_ack packet raw packet recieved. but isn't syn_ack packet raw packet recieved. but isn't syn_ack packet raw packet recieved. but isn't syn_ack packet raw packet recieved. but isn't syn_ack packet ip version: 4 header length: 5byte service type: 0x00 packet length: 44byte identify: 0x9d0e flag offset: 0x0000 ttl: 0x40 protocol: TCP header checksum: 0xc97a src ipaddress: xxx.xxx.xxx.xxx dst ipaddress: 10.0.2.15 src port: 80 dst port: 54321 sec num: 1385297409 ack num: 1105024979 reserve : 0x0 offset: 0x600 fin: 0 syn: 1 rst: 0 psh: 0 ack: 1 urg: 0 res2: 0 window size: 65535 checksum: 0xcd0d urgent ptr: 0x0 found syn_ack packet by new_packet_reciever thread # âããã¯åä¿¡ã¹ã¬ãã ip version: 4 header length: 5byte service type: 0x00 packet length: 44byte identify: 0x9d0e flag offset: 0x0000 ttl: 0x40 protocol: TCP header checksum: 0xc97a src ipaddress: xxx.xxx.xxx.xxx dst ipaddress: 10.0.2.15 src port: 80 dst port: 54321 sec num: 1385297409 ack num: 1105024979 reserve : 0x0 offset: 0x600 fin: 0 syn: 1 rst: 0 psh: 0 ack: 1 urg: 0 res2: 0 window size: 65535 checksum: 0xcd0d urgent ptr: 0x0 found syn_ack packet by new_packet_capture_run thread # âããã¯BPFã¹ã¬ãã
ãããï¼åä¿¡ã§ããï¼ãã±ããã®æ°ããã£ãã®3ãã±ããã ï¼
09:45:15.246002 IP (tos 0x0, ttl 64, id 54321, offset 0, flags [DF], proto TCP (6), length 40) 10.0.2.15.54321 > 10.0.2.15.80: Flags [S], cksum 0xd948 (correct), seq 45298, win 14600, length 0 09:45:15.246015 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 44) 10.0.2.15.80 > 10.0.2.15.54321: Flags [S.], cksum 0x183c (incorrect -> 0x5ca3), seq 3390123776, ack 45299, win 43690, options [mss 65495], length 0 09:45:15.246021 IP (tos 0x0, ttl 64, id 16593, offset 0, flags [DF], proto TCP (6), length 40) 10.0.2.15.54321 > 10.0.2.15.80: Flags [R], cksum 0x124e (correct), seq 45299, win 0, length 0
ãã£ãã¼ã¼ã¼ã¼ã¼ï¼
connect
ã§9ãã±ããéãå¿
è¦ç¡ããã9åãéãã¨é
ããªããããã¦ã¼ã¶ã©ã³ãã«ç°¡æTCPã¹ã¿ãã¯ãä½ã£ã¦ãã¹ã¬ãããé§ä½¿ãã¦ã«ã¼ãã«ãrstéããããããéãsyn+ackãã±ããåä¿¡ããããBPFã§ãã±ããã¢ãã¿ãªã³ã°ãããã¨ã«ãã£ã¦ãã±ãã6åãæ¸ããã¦ãå
¨é¨ã§3ãã±ããã§ãã¼ãã®Listenãã§ãã¯ã§ããå¦çãå®ç¾ã§ãããã¼ã¼ã¼ã¼ã¼ã¼ï¼ï¼
ããï¼
ã¾ã¨ã
ã¨ãããã¨ã§ãçµè«ã¨ãã¦ã¯é«éã«ãªã¢ã¼ããã¹ãã®ãã¼ããListenãã¦ãããããã§ãã¯ããã«ã¯ç¹æ¨©ããããªãconnectã§ååã§ãããã¨ãåããã¾ããï¼connectã§ããªãã£ãå ´åã¯ãã£ãã®2ãã±ããï¼ãã¾ãããã±ããã3ã¤ã«æããæã§ãä»åã®ãããªå®è£ ã ã¨å®éã®ãã§ãã¯ã³ã¹ãã¯ä¸æããã1000åãããããã£ã¦ããããã±ãã6åãæ¸ããããã«ã¦ã¼ã¶ã©ã³ãTCPã¹ã¿ãã¯ã®å®è£ ããã±ããã®èªåå®è£ ãBPFã«ãããã£ã«ã¿ãªã³ã°çãè²ã é å¼µãã¾ããããããã«ã¦ã§ã¢ã®ãããªã½ããã¦ã§ã¢ããé«éã«ãªã¢ã¼ããã¹ãã®ãã¼ãã®Listenç¶æ ããã§ãã¯ããã¨ãã観ç¹ã§ã¯ãã¼ããªã¥ã¼ã§ãã£ããã·ã¥ã§ããã
2017/02/13追è¨
åé ã§è¿½è¨ããããã«ã
@matsumotory è¨äºåé ã®9ãã±ããçºçãã¦ãããã±ããã®ãã³ããªãã§ããã©ããã¼ã«ã«ãã¼ããå¤ããªãã3åãã³ãã·ã§ã¤ã¯ãã¦ããããã«è¦ããã®ã§ããè²¼ãééãã ã£ãããã¾ãã..ï¼
— ã¿ãã³ (@pandax381) 2017å¹´2æ13æ¥
ã«ããææã®éããå®éã¯æ®éã«connectãã¦closeããã¨ä»¥ä¸ã®ãããªtcpdumpã§ãããå ¨é¨ã§æ®éã¯6ãã±ããã§ããã
09:13:59.353115 IP (tos 0x0, ttl 64, id 45250, offset 0, flags [DF], proto TCP (6), length 60) 127.0.0.1.47536 > 127.0.0.1.53: Flags [S], cksum 0xfe30 (incorrect -> 0xd259), seq 3532090005, win 43690, options [mss 65495,sackOK,TS val 24894039 ecr 0,nop,wscale 7], length 0 09:13:59.353128 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 127.0.0.1.53 > 127.0.0.1.47536: Flags [S.], cksum 0xfe30 (incorrect -> 0x4130), seq 394239430, ack 3532090006, win 43690, options [mss 65495,sackOK,TS val 24894039 ecr 24894039,nop,wscale 7], length 0 09:13:59.353140 IP (tos 0x0, ttl 64, id 45251, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.47536 > 127.0.0.1.53: Flags [.], cksum 0xfe28 (incorrect -> 0x1375), seq 1, ack 1, win 342, options [nop,nop,TS val 24894039 ecr 24894039], length 0 09:14:04.641694 IP (tos 0x0, ttl 64, id 45252, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.47536 > 127.0.0.1.53: Flags [F.], cksum 0xfe28 (incorrect -> 0x0e49), seq 1, ack 1, win 342, options [nop,nop,TS val 24895362 ecr 24894039], length 0 09:14:04.642176 IP (tos 0x0, ttl 64, id 18320, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.53 > 127.0.0.1.47536: Flags [F.], cksum 0xfe28 (incorrect -> 0x091d), seq 1, ack 2, win 342, options [nop,nop,TS val 24895362 ecr 24895362], length 0 09:14:04.642189 IP (tos 0x0, ttl 64, id 45253, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.47536 > 127.0.0.1.53: Flags [.], cksum 0xfe28 (incorrect -> 0x091d), seq 2, ack 2, win 342, options [nop,nop,TS val 24895362 ecr 24895362], length 0
ç¾å®çã«ã¯ connect æåãã¦ãã SO_LINGER 0 ãæå®ã㦠close ããã° RST ãé£ã㧠4 packet ã§ãã£ããã·ã¥ã ãã©ãããããã®å¤§å¥½ã https://t.co/v6IxzhRSqJ
— ã¿ãã³ (@pandax381) 2017å¹´2æ13æ¥
ãã®æ¹æ³ã«ãããã«ã¼ãã«ã®TCPã¹ã¿ãã¯ã使ã£ã¦ã4ãã±ããã§ãã£ããã·ã¥å¯è½ããã§ãã ãããã¨ããããã¾ãï¼
å®é試ãã¨ï¼ã¨ã©ã¼å¦çã¯çç¥ï¼ã
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> int main(int argc, char **argv) { int s; int dst_port; char *dst_host; struct sockaddr_in dest; struct linger so_linger; dst_host = argv[1]; dst_port = atoi(argv[2]); s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); dest.sin_family = AF_INET; dest.sin_addr.s_addr = inet_addr(dst_host); dest.sin_port = ntohs(dst_port); connect(s, (struct sockaddr *)&dest, sizeof(dest)); so_linger.l_onoff = 1; so_linger.l_linger = 0; setsockopt(s, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger)); close(s); return 0; }
ããã ã¨ã以ä¸ã®ãããªtcpdumpçµæã¨ãªãã¾ããã4ãã±ããã§ãã£ããã·ã¥ãã¦ããã®ã§ãã«ã¼ãã«ã®TCPã®ã¹ã¿ãã¯ã使ãå ´åã®æå°ãã±ããæ°ã¨æããã¾ãã
09:32:01.527284 IP (tos 0x0, ttl 64, id 15485, offset 0, flags [DF], proto TCP (6), length 60) 10.0.2.15.52154 > 10.0.2.15.80: Flags [S], cksum 0x184c (incorrect -> 0xdb93), seq 527746906, win 43690, options [mss 65495,sackOK,TS val 25164583 ecr 0,nop,wscale 7], length 0 09:32:01.527292 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.0.2.15.80 > 10.0.2.15.52154: Flags [S.], cksum 0x184c (incorrect -> 0xccf3), seq 2287569294, ack 527746907, win 43690, options [mss 65495,sackOK,TS val 25164583 ecr 25164583,nop,wscale 7], length 0 09:32:01.527299 IP (tos 0x0, ttl 64, id 15486, offset 0, flags [DF], proto TCP (6), length 52) 10.0.2.15.52154 > 10.0.2.15.80: Flags [.], cksum 0x1844 (incorrect -> 0x9f38), seq 1, ack 1, win 342, options [nop,nop,TS val 25164583 ecr 25164583], length 0 09:32:01.527393 IP (tos 0x0, ttl 64, id 15487, offset 0, flags [DF], proto TCP (6), length 52) 10.0.2.15.52154 > 10.0.2.15.80: Flags [R.], cksum 0x1844 (incorrect -> 0x9f34), seq 1, ack 1, win 342, options [nop,nop,TS val 25164583 ecr 25164583], length 0