Design and implement a half-connection port scanner of TCP protocol

2023.04.07

Design and implement a half-connection port scanner of TCP protocol

Generally speaking, the basic skill requirements for network knowledge are still very high. This article will not list these basic knowledge points of the TCP/IP protocol stack.

A student fan sent a question:

picture

This topic can be seen at a glance that this student is a major in network security.

Many fans thought Mr. Peng was driven by knowledge,

But in fact, as a veteran with multiple network protocol patents,

Network knowledge is quite good!

Application layer sockets, networking, and network card drivers have all been involved.

At present, there is still a lack of Linux kernel protocol stack, which has not been studied in depth, and will be added later.

1. Topic summary

The title requirement is to scan all TCP semi-connected ports, and the functions to be implemented are as follows:

  1. The attacker starts task 1, and   sends SYN packets to the specified server + port in a loop (the port starts increasing from 0)
  2. If there is a service on the server that opens this port, it will reply SYN+ACK , and the server enters the SYN_RCVD state at this time.
  3. The attacker starts task 2 to scan all received SYN+ACK packets. If the client receives SYN+ACK, it means that the server port is opened, and task 2 can print out all open port information
  • Task 1 uses socket API
  • Task 2 uses the pcap library

2. Basic knowledge of TCP

To solve this problem, you must master the following knowledge points:

  1. What is TCP
  2. TCP 3-way handshake
  3. What is a semi-join
  4. TCP, IP protocol header
  5. How to use the Libpcap library
  6. thread, process

Generally speaking, the basic skill requirements for network knowledge are still very high. This article will not list these basic knowledge points of the TCP/IP protocol stack.

The following mainly strengthens the knowledge points of TCP involved in this topic.

1.TCP

The first is that we must understand the TCP protocol header:

picture

  • Serial number: The random number generated by the computer is used as the initial value when the connection is established, and is sent to the receiving host through the SYN packet. Every time data is sent, the size of the "number of data bytes" is "accumulated". Used to solve the problem of out-of-order network packets
  • Confirmation response number: refers to the serial number of the data that is "expected" to be received next time. After receiving this confirmation response, the sender can consider that the data before this serial number has been received normally. Used to solve the problem of not losing packets
  • Control bit: ACK: When this bit is 1, the field of "Confirmation Response" becomes valid, and TCP stipulates that this bit must be set to 1 except for the SYN packet when the connection is initially established RST: When this bit is 1, it means that the TCP connection If an exception occurs, the connection must be forcibly disconnected SYN: When this bit is 1, it means that you want to establish a connection, and set the initial value of the serial number in the field of its "serial number" FIN: When this bit is 1, it means that you will not If there is another data to send, I hope to disconnect. When the communication ends and you want to disconnect, the hosts on both sides of the communication can exchange TCP segments with the FIN position set to 1.

Related to this topic is that the most important field is the control bit, and the operation of the control bit is mainly reflected in the 3-way handshake and 4-way handshake.

2. tcp three-way handshake

picture

At the beginning, both the client and the server are in the CLOSED state, and then the server starts to listen to a certain port and enter the LISTEN state:

  • The first handshake (SYN=1, seq=x), after sending, the client enters the SYN_SENT state
  • The second handshake (SYN=1, ACK=1, seq=y, ACKnum=x+1), after sending, the server enters the SYN_RCVD state
  • The third handshake (ACK=1, ACKnum=y+1). After sending, the client enters the ESTABLISHED state. When the server receives this packet, it also enters the ESTABLISHED state. After the TCP handshake, data transmission can begin

picture

picture

picture

3. tcp waved four times

picture

Four wave process:

  • The client intends to close the connection. At this time, it will send a message with the FIN flag set to 1 in the TCP header, that is, a FIN message, and then the client enters the FIN_WAIT_1 state
  • After receiving the message, the server sends an ACK response message to the client, and then the server enters the CLOSED_WAIT state
  • After receiving the ACK response message from the server, the client enters the FIN_WAIT_2 state
  • After waiting for the server to process the data, it also sends a FIN message to the client, and then the server enters the LAST_ACK state
  • After receiving the FIN message from the server, the client returns an ACK response message, and then enters the TIME_WAIT state
  • After the server receives the ACK response message, it enters the CLOSE state, and the server has completed the closing of the connection.
  • After the client has passed 2MSL for a period of time, it automatically enters the CLOSE state, and the client has also completed the closing of the connection.

4.TCP state

The TCP protocol state transition diagram is as follows:

picture

  • CLOSED: Indicates the initial state
  • LISTEN: Indicates that a SOCKET on the server side is in the listening state and can accept connections
  • SYN_RCVD: Indicates that a SYN message has been received
  • SYN_SENT: Indicates that the client has sent a SYN message
  • ESTABLISHED: Indicates that the connection has been established
  • TIME_WAIT: Indicates that the other party’s FIN message has been received and an ACK message has been sent, and it will return to the CLOSED available state after waiting for 2MSL
  • CLOSING: It means that after you sent the FIN message, you did not receive the other party's ACK message, but instead received the other party's FIN message. If both parties close a SOCKET almost at the same time, then there will be a situation where both parties send FIN messages at the same time, that is, the CLOSING state will appear, indicating that both parties are closing the SOCKET connection
  • CLOSE_WAIT: Indicates that it is waiting to close

5. Half connection/full connection

TCP semi-connection and full connection status play an important role in the performance analysis of the server, which usually reflects the processing capability of the server

1) Semi-connected queue (syn queue)

The client sends a SYN packet, and the server responds with SYN+ACK after receiving it, and the server enters the SYN_RCVD state. At this time, the socket will be placed in the semi-connected queue.

picture

2) Full connection queue (accept queue)

When the server receives the client's ACK, the socket will be moved from the semi-connected queue to the fully connected queue. When the accpet function is called, the available sockets will be returned to the user process from the head of the full connection queue.

Stored in the full connection queue is the process of completing the TCP three-way handshake, waiting to be processed, the status of both the client and the server is ESTABLISHED

3. Example of packet capture

If you want to learn the network well, you must master the packet capture tool.

The picture below is a complete tcp  3-way handshake + HTTP GET request + 4-way handshake  complete communication packet captured by Yikoujun through the packet capture tool.

picture

https://www.bilibili.com/video/BV1xr4y1T7cT/?vd_source=07570058a62e0e8a6cf489efac35cfec
  • 1.

Four, socket

Regarding the content of the socket API, you can refer to the following article "What exactly is a socket ?" ​​​​》

Five, libpcap

Libpcap is a network packet capture function library with very powerful functions. The famous tcpdump under Linux is based on it.

libpcap is mainly composed of two parts: network tap (network tap) and data filter (packet filter).

The network tap collects data from the network device driver for copying, and the filter decides whether to accept the data packet.

libpcap uses the BSD packet filter (BPF) algorithm to filter the link layer data packets received by the network card.

The packet capture mechanism of libpcap is to add a bypass processing at the data link layer. When a data packet arrives at the network interface, libpcap first uses the created socket to obtain a copy of the data packet from the link layer driver, and then sends the data packet to the BPF filter through the Tap function.

The BPF filter matches the data packets one by one according to the filtering rules defined by the user. If the matching is successful, it will be placed in the kernel buffer and passed to the user buffer. If the matching fails, it will be discarded directly.

If no filtering rules are set, all packets will be put into the kernel buffer and passed to the user layer buffer.

1. libpcap installation

  1. Install online

sudo apt-get  install  libpcap-dev
  • 1.

This is suitable for friends with internet

How to fail to install try to update the next source:

sudo apt-get update
  • 1.

  1. Compile and install offline

http://www.tcpdump.org/#latest-release
  • 1.

picture

然后解压
tar zxvf libpcap-1.10.3.tar.gz  
cd libpcap-1.10.3
./configure
sudo make
sudo make install
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

2. The packet capture process of Libpcap:

  1. Find network devices: The purpose is to find available network cards. The implemented function is pcap_lookupdev(). If there are multiple network cards currently, the function will return a pointer list of network device names.
  2. Open the network device: Use the return value in the previous step to decide which network card to use, open the network card through the function pcap_open_live(), and return the number of seconds used to capture network packets.
  3. Obtaining network parameters: here is to use the function pcap_lookupnet() to obtain the IP address and subnet mask of the specified network device.
  4. Compile filtering strategy: The main function of Lipcap is to provide data packet filtering, which is realized by the function pcap_compile().
  5. Set filter: Use the pcap_setfilter() function to set on the basis of the previous step.
  6. Use the callback function to capture data packets: functions pcap_loop() and pcap_dispatch() to capture data packets, or use functions pcap_next() and pcap_next_ex() to complete the same work.
  7. Close the network device: the pcap_close() function is related to the device and releases resources.

3. Data structure description:

struct pcap_pkthdr {
    struct timeval ts;  /* time stamp */
    bpf_u_int32 caplen; /* 抓到的数据包实际长度 */
    bpf_u_int32 len;    /*数据包的长度 */
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

4. libcap library function

For a detailed explanation of libcap, an article will be published later.

This article only talks about a few important functions.

  • open network interface

//这个函数会返回指定接口的pcap_t类型指针,后面的所有操作都要使用这个指针。
pcap_t * pcap_open_live(const char * device, int snaplen, int promisc, int to_ms, char * errbuf)
device:网络接口字符串,可以直接使用硬编码,比如eth0。
snaplen:对于每个数据包,从开头要抓多少个字节,我们可以设置这个值来只抓每个数据包的头部,而不关心具体的内容。典型的以太网帧长度是1518字节,但其他的某些协议的数据包会更长一点,但任何一个协议的一个数据包长度都必然小于65535个字节。
promisc:指定是否打开混杂模式(Promiscuous Mode),0表示非混杂模式,任何其他值表示混合模式。如果要打开混杂模式,那么网卡必须也要打开混杂模式,可以使用如下的命令打开eth0混杂模式:ifconfig eth0 
to_ms:抓包时长单位为毫秒,0标示一直等待。
errbuf: 输出参数,打开网络接口失败原因。
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

  • Open offline pcap files

pcap_t * pcap_open_offline (const char *fname, char *errbuf)
fname :文件名称。
errbuf :打开失败的错误信息。
  • 1.
  • 2.
  • 3.

  • capture function

int pcap_loop(pcap_t * p, int cnt, pcap_handler callback, u_char * user)
p: 打开的pcap_t类型指针。
cnt:一共抓多少个包,如果为负数就一直循环。
callback:回调函数指针
user:传递给回调函数的参数。
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
void callback(u_char * userarg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
userarg:是pcap_loop的最后一个参数,当收到足够数量的包后pcap_loop会调用callback回调函数,同时将pcap_loop()的user参数传递给它
pkthdr: 抓到的报文头信息。
packet:收到的包的数据。
  • 1.
  • 2.
  • 3.
  • 4.

  • filter function compilation

int pcap_compile(pcap_t * p, struct bpf_program * fp, char * str, int optimize, bpf_u_int32 netmask)
//fp:这是一个传出参数,存放编译后的bpf
//str:过滤表达式
//optimize:是否需要优化过滤表达式
//metmask:简单设置为0即可
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

  • set filter function

int pcap_setfilter(pcap_t * p,  struct bpf_program * fp)
//参数fp就是pcap_compile()的第二个参数,存放编译后的bpf
  • 1.
  • 2.

  • release network interface

void pcap_close(pcap_t * p)
//该函数用于关闭pcap_open_live()获取的pcap_t的网络接口对象并释放相关资源。
  • 1.
  • 2.

  • Open network package save file

pcap_dumper_t * pcap_dump_open (pcap_t *p, const char *fname)
 //p:是我们已经打开的网络设备,从这个设备接收数据包。
  // fname:是我们要写入的文件名,随便起。
  //return: 如果出错,会返回NULL。可以借此检查这个文件有没有打开。
  • 1.
  • 2.
  • 3.
  • 4.

  • write network packets to file

void pcap_dump (u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
user:就是文件描述符dumpfp,只不过要做一下类型转换。
由于这个函数一般在pcap_loop()的函数指针所指向的packet_handler中使用,所以packet_handler中的user就是这里的user。
 h:就是pkt_header
  • 1.
  • 2.
  • 3.
  • 4.

  • netpack file close

pcap_dump_close(pcap_dumper_t * t);
  • 1.

5. libcap filter rules

Some examples of filter expressions are as follows:

  • Only receive packets with source ip address 192.168.1.177

src host 192.168.1.177
  • 1.

  • Only receive packets whose tcp/udp destination port is 80

dst port 80
  • 1.

  • Only receive packets that do not use the tcp protocol

not tcp
  • 1.

  • Only receive packets with the SYN flag set and the destination port is 22 or 23 (the 13th byte starting from the tcp header)

tcp[13] == 0x02 and (dst port 22 or dst port 23)
  • 1.

  • Only receive icmp ping request and ping response packets

icmp[icmptype] == icmp-echoreply or icmp[icmptype] == icmp-echo
  • 1.

  • Only receive packets whose Ethernet mac address is 00:e0:09:c1:0e:82

ether dst 00:e0:09:c1:0e:82
  • 1.

Only receive packets with ip ttl=5 (the 8th byte starting from the ip header)

ip[8] == 5
  • 1.

In this example, only the data packets whose ip address is the local IP are captured, and then the program parses the data packet protocol header:

host 192.168.0.113
  • 1.

6. Design plan

Implementation principle:

The atach and cap processes run in ubuntu, and the target terminal to attack can be any device in the network, as long as it can be pinged. This example is tested on Windows, and bridge mode is used to bridge the network port of Ubuntu and the network port of Windows.

picture

The main functions of the atach process:

  • create tcp socket
  • Set the ip+port of the terminal that needs to be attacked, and then execute the connect function
  • The connect is successful, indicating that the port of the other party can be used
  • Modify the port value and repeat the previous 3 steps

The main functions of the cap process:

  • Through eth0, capture the specified rule: host 192.168.0.116 packets
  • Parse the Ethernet header, tcp header, ip header, tcp header, and judge all data packets whose sync+ack bit is 1 in the tcp header
  • Print out the packets filtered out in step 2

Code flow:

picture

7. Test

1. Environment:

windows ip:192.168.0.116
ubuntu ip:192.168.0.113
  • 1.
  • 2.

2. Documentation:

peng@ubuntu:~/work/test/pcap$ ls
atach  header.c        libpcap-1.10.3.tar.gz  cap.c
cap    libpcap-1.10.3  atach.c             protocol.h
  • 1.
  • 2.
  • 3.

Among them, atach is the attacker, which is used to send sync packets to the specified ip. cap is used to detect the sync+ack packets received by all network cards. The program runs in ubuntu.

3. Start the network debugging assistant

Start the network debugging assistant on windows,

Create several Tcp Servers, port numbers are 55, 56, 57

picture

insert image description here

4. Start the program

1) Start cap first

peng@ubuntu:~/work/test/pcap$ sudo ./cap 192.168.0.116
found device: eth0
netaddr:0000a8c0
try to open device eth0
filter:host 192.168.0.116
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

2) Start the attack program atach

A new terminal needs to be opened.

peng@ubuntu:~/work/test/pcap$ ./atach 192.168.0.116
  • 1.

5. The running screenshot is as follows:

picture

The log on the right is visible, listing all accessible ports, including 55, 56, and 57.

Note: The word atach deliberately lacks a t, otherwise it will not compile:

picture

Everyone can try your compiler, no punishment!

8. Code

The code has been synchronized to gitee, the address is as follows:

https://gitee.com/yikoulinux/pcap.git
  • 1.