Python端口扫描程序原理解析

Nmap是一款强大的端口扫描工具,渗透测试中经常用到,其功能主要有主机发现,端口扫描,版本侦测,OS侦测等。其中端口扫描是Nmap的核心功能,端口扫描有SYN扫描、TCP connect扫描、UDP扫描、ACK扫描等。为了了解Nmap的端口扫描原理,现用Python实现一个简单的端口扫描器,并用Wireshark抓包分析。附上源码:

#python3环境下运行
#encoding: utf-8  
from socket import *
import threading

lock = threading.Lock()
openNum = 0
threads = []

def portScanner(host,port):
    global openNum
    try:
        s = socket(AF_INET,SOCK_STREAM)
        s.connect((host,port))
        lock.acquire()
        openNum+=1
        print('[+] %d open' % port)
        lock.release()
        s.close()
    except:
        pass

def main():
    setdefaulttimeout(1)
    ip = input('please enter your host: ')
    for p in range(1,4000):
        t = threading.Thread(target=portScanner,args=(ip,p))
        threads.append(t)
        t.start()     

    for t in threads:
        t.join()

    print('[+] The scan is complete!')
    print('[+] A total of %d open port ' % (openNum))

if __name__ == '__main__':
    main()

上面源码用的socket模块下的socket函数,其中socket(AF_INET,SOCK_STREAM)中的SOCK_STREAM代表TCP连接,如果是SOCK_DGRAM则代表UDP连接,上面程序还用到了多线程技术。程序运行结果如下:
Python端口扫描程序原理解析_第1张图片
下面就通过Wireshark抓包工具来看看程序是如何识别开放与关闭的端口的:
这里写图片描述
端口1的TCP数据包
这里写图片描述
端口22的TCP数据包(中间两行其他端口的被cut掉了)

运行程序后,在过滤器里面直接输入TCP,可以看到tcp数据包的传输过程,以端口1和端口22为例,由程序运行结果图可知端口1是关闭的,端口22(ssh服务)是开放的。
扫描端口1时,客户端先创建套接字,然后连接远程服务器ip和端口1,发送标志位SYN,服务器端口1并没有开放,所以服务器返回[RST,ACK]标志位,RST代表复位,并强制关闭tcp连接。

扫描22端口时,客户端发送SYN标志位,服务器端口22是开放的,服务器会发送一个[SYN,ACK]标志位,然后客户端发送一个ACK标志位,整个TCP三次握手完成,最后客户端还会发送一个[FIN,ACK],FIN标志位代表连接断开。
这是TCP端口扫描方式,其原理跟Nmap中的TCP端口扫描方式一样,这种连接方式的缺点是建立了三次握手,不够隐蔽,是无法进行SYN扫描的选择,SYN扫描没有建立三次握手,隐蔽性较强。

你可能感兴趣的:(Python端口扫描程序原理解析)