linux下端口扫描的实现(TCP connect、TCP SYN、TCP FIN、UDP四种方式)4 TCP SYN方式

本文介绍了Linux系统中TCP SYN扫描的工作原理和实现方式,包括如何处理字节序、线程安全、校验和等问题。在扫描过程中,通过创建线程池,对每个端口发送SYN帧,并记录响应状态。文章还提到了一些编程中需要注意的细节,如避免丢包、错误判断等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.原理

众所周知,当调用connect()时要经历三次握手的过程SYN-SYN&ACK-ACK,而这种SYN扫描方式又叫半开放式扫描,即客户端只发送SYN帧,端口开放回应SYN&ACK帧,端口关闭回应RST帧,缺点就是不可靠,可能会丢包。

2.实现方式及遇到的问题

前面架构篇有讲过,每个扫描线程(tcpSynScanPort)会建立一个线程池,对每个要扫描的端口都创建一个线程tcpSynScanEach(线程配置成detach属性)。tcpSynScanEach负责发送SYN帧到各端口,另有一个线程tcpSynScanRecv负责处理所有收到的数据包。发送的数据包要自己组装,协议可以使用原始套接字,协议选择TCP。

(1)参数传递

        也是主线程里malloc一块,从线程sendto之后就free,只不过不能只像connect一样,传递目的ip和端口,因为攒包的时候要填写本机ip与端口,所以自己定义一个数据结构。

(2)字节序

        网络字节序与主机字节序的转换。

(3)线程安全

        同上一篇

(4)校验和

在填写首部字段时免不了要写校验和字段,需要小心校验的范围,这里做一下总结。

IP校验和只校验20字节的IP报头;

ICMP校验和覆盖整个报文(ICMP报头+ICMP数据);

UDP和TCP校验和不仅覆盖整个报文,而且还有12字节的IP伪首部,包括源IP地址(4字节)、目的IP地址(4字节)、协议(2字节,第一字节补0)和TCP/UDP包长(2字节)。另外UDP、TCP数据报的长度可以为奇数字节,所以在计算校验和时需要在最后增加填充字节0(注意,填充字节只是为了计算校验和,可以不被传送)。

(5)对丢包的处理

        只发SYN和接收ACK或RST帧其实是在ip层进行的,所以丢包的可能性很大。在这种扫描模式下,无论对方端口是打开还是关闭,都会有应答,所以我用一个全局数组记录每个端口的状态,0表示没有应答,1表示ack,2表示收到rst

(6)弱智错误

对于a<x<b的判断,要写if( (a<x) && (x<b) )好嘛,不能直接a<x<b好嘛。。

(7)各线程间的同步

main函数调用端口扫描主线程,main函数pthread_join等待扫描过程结束。

扫描主线程调用各个端口扫描线程,各端口扫描线程发送之后就自动结束了,扫描主线程不用等待。

扫描主线程调用接收线程,通过判断全局变量synCnt来确定是否扫描结束,归零后由扫描主线程kill掉接收线程,用pthread_cancel函数。

(8)tcp帧头

    

struct tcphdr
  {
    u_int16_t th_sport;		/* source port */
    u_int16_t th_dport;		/* destination port */
    tcp_seq th_seq;		/* sequence number */
    tcp_seq th_ack;		/* acknowledgement number */
#  if __BYTE_ORDER == __LITTLE_ENDIAN
    u_int8_t th_x2:4;		/* (unused) */
    u_int8_t th_off:4;		/* data offset */
#  endif
#  if __BYTE_ORDER == __BIG_ENDI
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值