Computer-Science

Sending a SYN packet with winpcap

1. algorithm

       ..............
       fp = pcap_open(..........);
       unsigned char  packet[65535];    // max packet size is 65535
       build_packet(packet);
       pcap_sendpacket(fp, packet, ......);

2. build_packet() : ethernet header, ip header, tcp header

1) Build ethernet header

2) Build ip header

3) Build tcp header

3. Send the packet

if (pcap_sendpacket(fp, packet, 14+20+tcp_header_len) != 0) {
   printf("err in packet send:%s\n",pcap_geterr(fp));
}

4. Exercise

1) Send a SYN packet to the server.

1-1)

STEP 1 : sniffer.c๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์˜€๋‹ค. ์ˆ˜์ •ํ•œ sniffer.c๋ฅผ โ€œ__gxx_personality_v0 errorโ€๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด g++๋กœ -lpcap ์˜ต์…˜์„ ์ฃผ์–ด ์ปดํŒŒ์ผํ•˜๊ณ , ์‹คํ–‰ ํŒŒ์ผ์„ sudo ๊ถŒํ•œ์„ ์ฃผ์–ด ์‹คํ–‰ํ•œ๋‹ค.

์ €๋ฒˆ lecture์—์„œ ์‚ฌ์šฉํ•˜์˜€๋˜ sniffer.c๋ฅผ original_sniffer.c๋ผ๊ณ  ํ•˜์ž.
๋ณธ ๋ฌธ์ œ์—์„œ๋Š” original_sniffer.c๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ด ๋ฌธ์ œ์—์„œ ์š”๊ตฌํ•˜๋Š” ๊ฐ ๋‹จ๊ณ„์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•˜์˜€๋‹ค.

sniffer.c :

int main()
{
  ......

  while ((res = pcap_next_ex(fp, &header, &pkt_data)) >= 0) // 1 if success
	{
		if (res == 0) // 0 if time-out
		{
			continue;
		}

		print_raw_packet(pkt_data, header->caplen);
		// print_ether_header(pkt_data);
		// print_ip_header(pkt_data);
		// print_tcp_header(pkt_data);
		// print_data(pkt_data, header->caplen);

		// 1-1-1)
		printf("\nNow breaking this loop\n");
		break; // break out of the while loop after capturing the first SYN packet.
	}

	// 1-1-2)
	struct tcp_header *th = (struct tcp_header *)(pkt_data + 14 + 20);
	int tcp_length = th->data_offset * 4;
	// now we have syn packet in pkt_data
	printf("\nLet's send SYN ===========\n");
	printf("Checking TCP header length : %d\n", tcp_length);
	printf("Length of SYN packet       : %d\n", header->caplen); // header : struct pcap_pkthdr
	print_raw_packet(pkt_data, header->caplen);					 // display the packet in raw bytes.

	// 1-1-3) kill the server and the client (manually)
	printf("\nKill server and the client.\n");
	// 1-1-4) run the original sniffer
	printf("Run the original sniffer.\n");
	// 1-1-5) rerun the server
	printf("Rerun the server and hit '9' when ready : ");
	int x;
	scanf("%d", &x);

	if (x == 9)
	{
		// 1-1-6) send the captured SYN packet to the server
		printf("\nNow we send our SYN. See if we receive ACK from the server.\n");
		if (pcap_sendpacket(fp, pkt_data, 14 + 20 + tcp_length) != 0)
		{
			printf("err in packet send : %s\n", pcap_geterr(fp));
		}
	}

	return 0;
}
$ g++ -o sniffer sniffer.c -lpcap
$ sudo ./sniffer

interface number๋กœ 1์„ ์ž…๋ ฅํ•˜์˜€๋‹ค.

availableํ•œ dev๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

STEP 2 : server์— ์ ‘์†ํ•˜์—ฌ ./serv๋ฅผ ์‹คํ–‰ํ•œ ํ›„, ๋กœ์ปฌ์—์„œ client ์‹คํ–‰ ํŒŒ์ผ์ธ ./cli๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.


์œ„ ํ™”๋ฉด์—์„œ ์™ผ์ชฝ ํ„ฐ๋ฏธ๋„์€ ./sniffer๋ฅผ ์‹คํ–‰ํ•œ ํ™”๋ฉด์ด๋‹ค. ์˜ค๋ฅธ์ชฝ ์œ„ ํ„ฐ๋ฏธ๋„์€ server์˜ ํ„ฐ๋ฏธ๋„์ด๊ณ , ์˜ค๋ฅธ์ชฝ ์•„๋ž˜ ํ„ฐ๋ฏธ๋„์ด client์˜ ํ„ฐ๋ฏธ๋„์ด๋‹ค.

Raw Byte Stream of the Packet
New Packet of Size : 78
7819 f706 4001 08f8 bc6a a8db 0800 4500
0040 0000 4000 4006 e980 a5f6 deb3 a5f6
2697 d3d1 30e8 1ac2 0fab 0000 0000 b0c2
ffff 7e78 0000 0204 05b4 0103 0306 0101
080a a80b 8f59 0000 0000 0402 0000

Now breaking this loop

Let's send SYN ===========
Checking TCP header length : 44
Length of SYN packet       : 78

Raw Byte Stream of the Packet
New Packet of Size : 78
7819 f706 4001 08f8 bc6a a8db 0800 4500
0040 0000 4000 4006 e980 a5f6 deb3 a5f6
2697 d3d1 30e8 1ac2 0fab 0000 0000 b0c2
ffff 7e78 0000 0204 05b4 0103 0306 0101
080a a80b 8f59 0000 0000 0402 0000

Kill server and the client.
Run the original sniffer.
Rerun the server and hit '9' when ready :

STEP 3 : ./serv์™€ ./cli๋ฅผ ^C๋กœ ์ˆ˜๋™์œผ๋กœ ๊ฐ•์ œ ์ข…๋ฃŒํ•œ๋‹ค.

STEP 4 : ./original_sniffer๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

STEP 5 : ./serv๋ฅผ ์žฌ์‹คํ–‰ํ•œ๋‹ค.

STEP 6 : ./sniffer์— โ€˜9โ€™๋ฅผ ์ž…๋ ฅํ•˜์—ฌ, ./serv์— captured SYN packet์„ ์ „์†กํ•œ๋‹ค.

STEP 7 : ./original_sniffer์• ์„œ packet์„ ํ™•์ธํ•œ๋‹ค.

์•„๋ž˜ Packet์˜ MAC Address ๋ถ€๋ถ„๊ณผ IP Address ๋ถ€๋ถ„์—์„œ -์€ ์ฃผ์†Œ๋ฅผ ์ผ๋ถ€ ๊ฐ€๋ฆฐ ๊ฒƒ์ด๋‹ค.

Raw Byte Stream of the Packet
New Packet of Size : 78
7819 f706 4001 08f8 bc6a a8db 0800 4500
0040 0000 4000 4006 e980 a5f6 deb3 a5f6
2697 d3d1 30e8 1ac2 0fab 0000 0000 b0c2
ffff 7e78 0000 0204 05b4 0103 0306 0101
080a a80b 8f59 0000 0000 0402 0000

Printing Ethernet Header:
	Destination MAC Address: --19--06--01 // Server MAC
	Source MAC Address: 08--bc--a8-- // PC MAC
	Protocol Type: 0800

Printing IP Header:
	IP Version: 4
	IP Header Length: 5 bytes
	IP Type of Service: 0
	IP Total Length: 64
	IP Identification: 0
	IP Reserved Zero: 0
	IP Don't Fragment: 1
	IP More Fragment: 0
	IP Frag Offset: 00
	IP Frag Offset 1: 00
	IP TTL: 40
	IP Protocol: 06
	IP CheckSum: e980
	Source IP Address: --f6--b3 // Server IP
	Destination IP Address: a5--26-- // PC IP

Printing TCP Header: 	Source Port Number: 54225
	Destination Port Number: 12520
	Sequence Number: 448925611
	ACK Number: 0
	TCP Data Offset: b
	Reserved Part 1: 0
	TCP NS: 0
	FIN: 0
	SYN: 1
	RST: 0
	PSH: 0
	ACK: 0
	URG: 0
	ECN: 1
	CWR: 1
	Window: 65535
	TCP CheckSum: 7e78
	Urgent Pointer: 0000

Printing data of packet :
0204 05b4 0103 0306 0101 080a a80b 8f59
0000 0000 0402 0000

Raw Byte Stream of the Packet
New Packet of Size : 74
08f8 bc6a a8db 7819 f706 4001 0800 4500
003c 0000 4000 3f06 ea84 a5f6 2697 a5f6
deb3 30e8 d3d1 2c45 f93b 1ac2 0fac a052
3890 6152 0000 0204 05b4 0402 080a f0a8
dfde a80b 8f59 0103 0307

Printing Ethernet Header:
	Destination MAC Address: 08--bc--a8-- // PC MAC
	Source MAC Address: --19--06--01 // Server MAC
	Protocol Type: 0800

Printing IP Header:
	IP Version: 4
	IP Header Length: 5 bytes
	IP Type of Service: 0
	IP Total Length: 60
	IP Identification: 0
	IP Reserved Zero: 0
	IP Don't Fragment: 1
	IP More Fragment: 0
	IP Frag Offset: 00
	IP Frag Offset 1: 00
	IP TTL: 3f
	IP Protocol: 06
	IP CheckSum: ea84
	Source IP Address: a5--26-- // PC IP
	Destination IP Address: --f6--b3 // Server IP

Printing TCP Header: 	Source Port Number: 12520
	Destination Port Number: 54225
	Sequence Number: 742783291
	ACK Number: 448925612
	TCP Data Offset: a
	Reserved Part 1: 0
	TCP NS: 0
	FIN: 0
	SYN: 1
	RST: 0
	PSH: 0
	ACK: 1
	URG: 0
	ECN: 1
	CWR: 0
	Window: 14480
	TCP CheckSum: 6152
	Urgent Pointer: 0000

Printing data of packet :
0204 05b4 0402 080a f0a8 dfde a80b 8f59
0103 0307

Raw Byte Stream of the Packet
New Packet of Size : 54
7819 f706 4001 08f8 bc6a a8db 0800 4500
0028 0000 4000 4006 e998 a5f6 deb3 a5f6
2697 d3d1 30e8 1ac2 0fac 0000 0000 5004
0000 2f81 0000

Printing Ethernet Header:
	Destination MAC Address: --19--06--01 // Server MAC
	Source MAC Address: 08--bc--a8-- // PC MAC
	Protocol Type: 0800

Printing IP Header:
	IP Version: 4
	IP Header Length: 5 bytes
	IP Type of Service: 0
	IP Total Length: 40
	IP Identification: 0
	IP Reserved Zero: 0
	IP Don't Fragment: 1
	IP More Fragment: 0
	IP Frag Offset: 00
	IP Frag Offset 1: 00
	IP TTL: 40
	IP Protocol: 06
	IP CheckSum: e998
	Source IP Address: --f6--b3 // Server IP
	Destination IP Address: a5--26-- // PC IP

Printing TCP Header: 	Source Port Number: 54225
	Destination Port Number: 12520
	Sequence Number: 448925612
	ACK Number: 0
	TCP Data Offset: 5
	Reserved Part 1: 0
	TCP NS: 0
	FIN: 0
	SYN: 0
	RST: 1
	PSH: 0
	ACK: 0
	URG: 0
	ECN: 0
	CWR: 0
	Window: 0
	TCP CheckSum: 2f81
	Urgent Pointer: 0000

STEP 8 : check if you can see the ACK packet from the server.

Packet 1
Printing TCP Header: 	Source Port Number: 54225
  ......
	TCP NS: 0
	FIN: 0
	SYN: 1
	RST: 0
	PSH: 0
	ACK: 0
	URG: 0
	ECN: 1
	CWR: 1
	Window: 65535
	TCP CheckSum: 7e78
	Urgent Pointer: 0000

์ฒ˜์Œ Packet์—์„œ ์„œ๋ฒ„๋Š” SYN ํŒจํ‚ท ๋งŒ์„ ๋ณด๋ƒˆ๋‹ค.

Packet 2
Printing TCP Header: 	Source Port Number: 12520
  ......
	TCP NS: 0
	FIN: 0
	SYN: 1
	RST: 0
	PSH: 0
	ACK: 1
	URG: 0
	ECN: 1
	CWR: 0
	Window: 14480
	TCP CheckSum: 6152
	Urgent Pointer: 0000

๋‘๋ฒˆ์งธ Packet์—์„œ ์„œ๋ฒ„๋Š” SYN/ACK ํŒจํ‚ท์„ PC๋กœ ๋ณด๋ƒˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ PC์—์„œ ์‘๋‹ต์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ ํ›„๋กœ๋„ ํŒจํ‚ท์„ ๊ณ„์†ํ•ด์„œ ๋ณด๋‚ธ๋‹ค.

1-2) Modify the sniffer further such that it re-computes ip and tcp checksum.

STEP 1 : sniffer.c๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์˜€๋‹ค. ์ˆ˜์ •ํ•œ sniffer.c๋ฅผ โ€œ__gxx_personality_v0 errorโ€๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด g++๋กœ -lpcap ์˜ต์…˜์„ ์ฃผ์–ด ์ปดํŒŒ์ผํ•˜๊ณ , ์‹คํ–‰ ํŒŒ์ผ์„ sudo ๊ถŒํ•œ์„ ์ฃผ์–ด ์‹คํ–‰ํ•œ๋‹ค.

์ €๋ฒˆ lecture์—์„œ ์‚ฌ์šฉํ•˜์˜€๋˜ sniffer.c๋ฅผ original_sniffer.c๋ผ๊ณ  ํ•˜์ž.
๋ณธ ๋ฌธ์ œ์—์„œ๋Š” original_sniffer.c๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ด ๋ฌธ์ œ์—์„œ ์š”๊ตฌํ•˜๋Š” ๊ฐ ๋‹จ๊ณ„์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•˜์˜€๋‹ค.

sniffer.c :

#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <string.h>
#include <arpa/inet.h>

#define IP_OF_YOUR_PC "165.---.222.---"
#define IP_OF_DEST "165.246.38.151"

......

// 1-2)
unsigned short in_checksum(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; // use โ€œshortโ€ in MacOS instead of โ€œSHORTโ€

	return (answer);
}

int main()
{
  ......
  while ((res = pcap_next_ex(fp, &header, &pkt_data)) >= 0) // 1 if success
	{
		if (res == 0) // 0 if time-out
		{
			continue;
		}

		print_raw_packet(pkt_data, header->caplen);
		// print_ether_header(pkt_data);
		// print_ip_header(pkt_data);
		// print_tcp_header(pkt_data);
		// print_data(pkt_data, header->caplen);

		// 1-1-1), 1-2-1)
		printf("\nNow breaking this loop\n");
		break; // 1-1-1), 1-2-1) break out of the while loop after capturing the first SYN packet.
	}

	// 1-2-2) copy them into another buffer: pkt_data=>packet
	const unsigned char *packet = (unsigned char *)malloc(65535);
	packet = pkt_data;

	// 1-2-3)
	struct ip_header *ih = (struct ip_header *)(pkt_data + 14);
	struct tcp_header *th = (struct tcp_header *)(pkt_data + 14 + 20);
	// 1-2-3) set ip_check_sum and tcp_check_sum to zero
	ih->ip_checksum = 0;
	th->checksum = 0;

	// 1-2-4), 1-2-5)
	int tcp_length = th->data_offset * 4;

	struct pseudo_header psh;
	// to use inet_pton(), include "winsock2.h" and "ws2tcpip.h" in windows
	// in MacOS, include <arpa/inet.h>
	inet_pton(AF_INET, IP_OF_YOUR_PC, &(psh.source_address)); // ip of your pc
	inet_pton(AF_INET, IP_OF_DEST, &(psh.dest_address));	  // dest ip
	psh.placeholder = 0;									  // reserved
	psh.protocol = 6;										  // protocol number for tcp
	psh.tcp_length = htons(tcp_length);						  // store multi byte number in network byte order

	unsigned char *seudo;
	seudo = (unsigned char *)malloc(sizeof(struct pseudo_header) + tcp_length);
	memcpy(seudo, &psh, sizeof(struct pseudo_header));
	memcpy(seudo + sizeof(struct pseudo_header), th, tcp_length);

	// 1-2-4), 1-2-5) recompute ip_check_sum and tcp_check_sum
	ih->ip_checksum = in_checksum((unsigned short *)ih, 20);
	th->checksum = in_checksum((unsigned short *)seudo, sizeof(struct pseudo_header) + tcp_length);

	// 1-1-2) now we have syn packet in pkt_data
	printf("\nLet's send SYN ===========\n");
	printf("Checking TCP header length : %d\n", tcp_length);
	printf("Length of SYN packet       : %d\n", header->caplen); // header : struct pcap_pkthdr
	print_raw_packet(pkt_data, header->caplen);					 // 1-2-6) display the packet in raw bytes.
																 // this should be same as pkt_data

	// 1-1-3), 1-2-7) kill the server and the client (manually)
	printf("\nKill server and the client.\n");
	// 1-1-4), 1-2-8) run the original sniffer
	printf("Run the original sniffer.\n");
	// 1-1-5), 1-2-9) rerun the server
	printf("Rerun the server and hit '9' when ready : ");
	int x;
	scanf("%d", &x);

	if (x == 9)
	{
		// 1-1-6), 1-2-10) send the captured SYN packet to the server
		printf("\nNow we send our SYN. See if we receive ACK from the server.\n");
		if (pcap_sendpacket(fp, pkt_data, 14 + 20 + tcp_length) != 0)
		{
			printf("err in packet send : %s\n", pcap_geterr(fp));
		}
	}

	return 0;
}
$ g++ -o sniffer sniffer.c -lpcap
$ sudo ./sniffer

interface number๋กœ 1์„ ์ž…๋ ฅํ•˜์˜€๋‹ค.

availableํ•œ dev๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

STEP 2 : server์— ์ ‘์†ํ•˜์—ฌ ./serv๋ฅผ ์‹คํ–‰ํ•œ ํ›„, ๋กœ์ปฌ์—์„œ client ์‹คํ–‰ ํŒŒ์ผ์ธ ./cli๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.


์œ„ ํ™”๋ฉด์—์„œ ์™ผ์ชฝ ํ„ฐ๋ฏธ๋„์€ ./sniffer๋ฅผ ์‹คํ–‰ํ•œ ํ™”๋ฉด์ด๋‹ค. ์˜ค๋ฅธ์ชฝ ์œ„ ํ„ฐ๋ฏธ๋„์€ server์˜ ํ„ฐ๋ฏธ๋„์ด๊ณ , ์˜ค๋ฅธ์ชฝ ์•„๋ž˜ ํ„ฐ๋ฏธ๋„์ด client์˜ ํ„ฐ๋ฏธ๋„์ด๋‹ค.

Raw Byte Stream of the Packet
New Packet of Size : 78
8836 6cd6 128c 08f8 bc6a a8db 0800 4500
0040 0000 4000 4006 ad6c c0a8 0016 a5f6
2697 dc47 30e8 9636 35d2 0000 0000 b002
ffff f171 0000 0204 05b4 0103 0306 0101
080a fbe7 e31d 0000 0000 0402 0000

Now breaking this loop

Let's send SYN ===========
Checking TCP header length : 44
Length of SYN packet       : 78

Raw Byte Stream of the Packet
New Packet of Size : 78
8836 6cd6 128c 08f8 bc6a a8db 0800 4500
0040 0000 4000 4006 ad6c c0a8 0016 a5f6
2697 dc47 30e8 9636 35d2 0000 0000 b002
ffff 2d86 0000 0204 05b4 0103 0306 0101
080a fbe7 e31d 0000 0000 0402 0000

Kill server and the client.
Run the original sniffer.
Rerun the server and hit '9' when ready :

STEP 3 : ./serv์™€ ./cli๋ฅผ ^C๋กœ ์ˆ˜๋™์œผ๋กœ ๊ฐ•์ œ ์ข…๋ฃŒํ•œ๋‹ค.

STEP 4 : ./original_sniffer๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

$ sudo ./original_sniffer

STEP 5 : ./serv๋ฅผ ์žฌ์‹คํ–‰ํ•œ๋‹ค.

STEP 6 : ./sniffer์— โ€˜9โ€™๋ฅผ ์ž…๋ ฅํ•˜์—ฌ, ./serv์— captured SYN packet์„ ์ „์†กํ•œ๋‹ค.

STEP 7 : ./original_sniffer์• ์„œ packet์„ ํ™•์ธํ•œ๋‹ค.

์•„๋ž˜ Packet์˜ MAC Address ๋ถ€๋ถ„๊ณผ IP Address ๋ถ€๋ถ„์—์„œ -์€ ์ฃผ์†Œ๋ฅผ ์ผ๋ถ€ ๊ฐ€๋ฆฐ ๊ฒƒ์ด๋‹ค.

Raw Byte Stream of the Packet
New Packet of Size : 78
8836 6cd6 128c 08f8 bc6a a8db 0800 4500
0040 0000 4000 4006 ad6c c0a8 0016 a5f6
2697 dc47 30e8 9636 35d2 0000 0000 b002
ffff 2d86 0000 0204 05b4 0103 0306 0101
080a fbe7 e31d 0000 0000 0402 0000

Printing Ethernet Header:
	Destination MAC Address: --36--d6--8c // Server MAC
	Source MAC Address: 08--bc--a8-- // PC MAC
	Protocol Type: 0800

Printing IP Header:
	IP Version: 4
	IP Header Length: 5 bytes
	IP Type of Service: 0
	IP Total Length: 64
	IP Identification: 0
	IP Reserved Zero: 0
	IP Don't Fragment: 1
	IP More Fragment: 0
	IP Frag Offset: 00
	IP Frag Offset 1: 00
	IP TTL: 40
	IP Protocol: 06
	IP CheckSum: ad6c
	Source IP Address: --a8--16 // Server IP
	Destination IP Address: a5--26-- // PC IP

Printing TCP Header: 	Source Port Number: 56391
	Destination Port Number: 12520
	Sequence Number: -1774832174
	ACK Number: 0
	TCP Data Offset: b
	Reserved Part 1: 0
	TCP NS: 0
	FIN: 0
	SYN: 1
	RST: 0
	PSH: 0
	ACK: 0
	URG: 0
	ECN: 0
	CWR: 0
	Window: 65535
	TCP CheckSum: 2d86
	Urgent Pointer: 0000

Printing data of packet :
0204 05b4 0103 0306 0101 080a fbe7 e31d
0000 0000 0402 0000

STEP 8 : check if you can see the ACK packet from the server.

Printing TCP Header: 	Source Port Number: 56391
	......
	TCP NS: 0
	FIN: 0
	SYN: 1
	RST: 0
	PSH: 0
	ACK: 0
	URG: 0
	ECN: 0
	CWR: 0
	Window: 65535
	TCP CheckSum: 2d86
	Urgent Pointer: 0000

2) Implement a stealth scanner.

1-2์˜ sniffer.c๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ sniffer_2.c๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

int main()
{
	......

	while ((res = pcap_next_ex(fp, &header, &pkt_data)) >= 0) // 1 if success
	{
		if (res == 0) // 0 if time-out
		{
			continue;
		}

		print_raw_packet(pkt_data, header->caplen);
		// print_ether_header(pkt_data);
		// print_ip_header(pkt_data);
		// print_tcp_header(pkt_data);
		// print_data(pkt_data, header->caplen);

		// 1-1-1), 1-2-1)
		printf("\nNow breaking this loop\n");
		break; // 1-1-1), 1-2-1) break out of the while loop after capturing the first SYN packet.
	}

	// 1-2-2) copy them into another buffer: pkt_data=>packet
	const unsigned char *packet = (unsigned char *)malloc(65535);
	packet = pkt_data;

	// 1-1-3), 1-2-7) kill the server and the client (manually)
	printf("\nKill server and the client.\n");
	// 1-1-4), 1-2-8) run the original sniffer
	printf("Run the original sniffer.\n");
	// 1-1-5), 1-2-9) rerun the server
	printf("Rerun the server and hit '9' when ready : ");
	int x;
	scanf("%d", &x);

	if (x == 9)
	{
		int p;
		for (p = 1; p <= 65535; p++) // 2) ํฌํŠธ ๋ฒˆํ˜ธ : 1~65535
		{
			// 1-2-3)
			struct ip_header *ih = (struct ip_header *)(pkt_data + 14);
			struct tcp_header *th = (struct tcp_header *)(pkt_data + 14 + 20);

			// 2) destination port ๋ณ€๊ฒฝ (1~65535)
			th->dest_port = htons(p);

			// 1-2-3) set ip_check_sum and tcp_check_sum to zero
			ih->ip_checksum = 0;
			th->checksum = 0;

			// 1-2-4), 1-2-5)
			int tcp_length = th->data_offset * 4;

			struct pseudo_header psh;
			// to use inet_pton(), include "winsock2.h" and "ws2tcpip.h" in windows
			// in MacOS, include <arpa/inet.h>
			inet_pton(AF_INET, IP_OF_YOUR_PC, &(psh.source_address)); // ip of your pc
			inet_pton(AF_INET, IP_OF_DEST, &(psh.dest_address));	  // dest ip
			psh.placeholder = 0;									  // reserved
			psh.protocol = 6;										  // protocol number for tcp
			psh.tcp_length = htons(tcp_length);						  // store multi byte number in network byte order

			unsigned char *seudo;
			seudo = (unsigned char *)malloc(sizeof(struct pseudo_header) + tcp_length);
			memcpy(seudo, &psh, sizeof(struct pseudo_header));
			memcpy(seudo + sizeof(struct pseudo_header), th, tcp_length);

			// 1-2-4), 1-2-5) recompute ip_check_sum and tcp_check_sum
			ih->ip_checksum = in_checksum((unsigned short *)ih, 20);
			th->checksum = in_checksum((unsigned short *)seudo, sizeof(struct pseudo_header) + tcp_length);

			/*
			// 1-1-2) now we have syn packet in pkt_data
			printf("\nLet's send SYN ===========\n");
			printf("Checking TCP header length : %d\n", tcp_length);
			printf("Length of SYN packet       : %d\n", header->caplen); // header : struct pcap_pkthdr
			print_raw_packet(pkt_data, header->caplen);					 // 1-2-6) display the packet in raw bytes.
																		 // this should be same as pkt_data
			*/

			printf("send SYN packet to port %d\n", p); // 2) ์ „์†กํ•œ ํŒจํ‚ท์˜ destination ํฌํŠธ ๋ฒˆํ˜ธ ์ถœ๋ ฅ
			// 1-1-6), 1-2-10) send the captured SYN packet to the server
			// printf("\nNow we send our SYN. See if we receive ACK from the server.\n");
			if (pcap_sendpacket(fp, pkt_data, 14 + 20 + tcp_length) != 0)
			{
				printf("err in packet send : %s\n", pcap_geterr(fp));
			}
		}
	}

	return 0;
}

sniffer_2.c๋Š” ์ตœ์ดˆ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์บก์ฒ˜ํ•œ SYN ํŒจํ‚ท์„ ๋ณต์‚ฌํ•œ๋‹ค. ์ด ํŒจํ‚ท์˜ destination port ๋ฒˆํ˜ธ๋ฅผ 1๋ถ€ํ„ฐ 65535๊นŒ์ง€ ๋ณ€๊ฒฝํ•˜๋ฉฐ ์ด 65535๊ฐœ์˜ SYN ํŒจํ‚ท์„ ์„œ๋ฒ„๋กœ ์ „์†กํ•œ๋‹ค.


1-2์˜ sniffer.c๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ stealth_scanner.c๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

stealth_scanner๋Š” ๋ชจ๋“  ํฌํŠธ ๋ฒˆํ˜ธ๋กœ๋ถ€ํ„ฐ ์˜ค๋Š” SYN/ACK ํŒจํ‚ท์„ ์บก์ณํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด์˜ filter ๊ทœ์น™์—์„œ ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ์ œ๊ฑฐํ•˜์˜€๋‹ค.

12520๋ฒˆ ํฌํŠธ๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์ด ์˜จ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.