Python之TCP端口扫描

 TCP端口及服务扫描器的设计

在学习完《Python绝技》一章后,认真的总结下笔记。

 常见的端口扫描是基于TCP三次握手或者是四次挥手过程,常见的是发送一个TCP syn包到指定主机的指定端口,根据返回的结果判断该端口是否开放。

1. TCP端口扫描根据不同的发包可以分为:

 (1)TCP SYN扫描:也称半开放扫描,该扫描类型发送一个SYN的TCP链接数据包等待响应,当返回RST数据包表示端

口关闭,返回ACK表示端口开放。

 (2)TCP NULL扫描:TCP空扫描设置TCP的标志头为零,如果返回一个RST数据包则表示这个端口是关闭的。

 (3)TCP FIN扫描:TCP FIN扫描发送一个FIN数据包,请求关闭链接,等待一个个圆满的终止,如果返回RST数据包则

表示该端口是关闭的。

 (4)TCP XMAS扫描:TCP XSMAS扫描设置PSH,FIN和URG TCP的标志位,如果返回RST数据包则表示这个端口是关

闭的。

2.扫描器设计思路:

 (1)用户输入目标主机名和要扫描的常用端口列表,通过主机名得到目标网络的IP地址,用列表中的每一个端口号去链

接目标地址,最后确定端口上运行的特殊服务,可以发送特定的数据,并读取特定应用程序返回的标识。

 (2)从用户那里接收主机名和端口,利用optparse标准库来解析命令行选项,调用optparse.OptionParser()创建一个

选项分析器,然后通过parser.add_option()函数来指定命令选项。

3.多线程端口扫描器应注意:

 (1)多线程在速度上有明显优势,但是端口回显的信息可能是无序的,必须在同一时间内只有一个打印信息的函数,但

是访问端口的却可以是多个的,同时还要避免重复访问同一个端口,造成资源浪费。因此,必须使用信号量加锁

 (2)使用acquire()加锁,新好像允许信号运行,如果锁定了必须要等到信号量的进程释放锁,利用信号量可以保证在同

一时间只有一个线程在打印输出结果

4.用到的模块及函数

(1)optparse模块:

optparse.OptionParser()

optparse.add_option()

optparse.parse_args()

以上三个函数不多介绍,基本就是命令解释的作用。如果感兴趣,请参考大神的文章:点击打开链接

(2)sock模块:

 socket.gethostbyname(hostname):将主机名转换成IP地址返回
 socket.gethostbyaddr(ip_address):传入一个Ip地址返回一个元组,其中包括主机名,别名列表和同一接口的Ip地址列表 socket.socket():创建一个socket

 socket. connect(address,timeout,source_address):传入Ip地址和端口号返回一个socket对象,可以设置超时重连的时间
socket.send(data):项目地主机端口发送数据 socket.recv(size):从socket中接受size大小的字节数据

(3)threading模块:

threading.Semaphore(value=num):创建信号量为num的锁

threading.acquire():加锁

threading.release():解锁,释放信号量

    5.程序代码:

# coding = UTF-8

import optparse
import socket
import threading


screenLock = threading.Semaphore(value = 1)

def connScan(tgtHost,tgtPort):

    try:

        connSkt = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

        connSkt.connect((tgtHost,tgtPort))

        connSkt.send('ViolentPython\r\n')

        results = connSkt.recv(100)

        screenLock.acquire()

        print('[+]%d/tcp open' %tgtPort)

        print('[+]' + results.decode('utf-8'))

    except:

        screenLock.acquire()

        print('[-]%d/tcp closed' %tgtPort)

    finally:

        screenLock.release()

        connSkt.close()



def portScan(tgtHost,tgtPorts):

    try:

        tgtIP = socket.gethostbyname(tgtHost)

    except:

        print("[-] Cannot resolve '%s': Unknown host" %tgtHost)

        return

    try:

        tgtName = socket.gethostbyaddr(tgtIP)

        print('\n [+]Scan Results for:' + tgtName[0])

    except:

        print('\n [+]Scan Results for:' + tgtIP)

    socket.setdefaulttimeout(1)

    for tgtPort in tgtPorts:

        print('Scanning por' + str(tgtPort))

        t = threading.Thread(target = connScan,args = (tgtHost,int(tgtPort)))

        t.start()


def main():

    parser = optparse.OptionParser('usage %prog -H  -p ')

    parser.add_option('-H',dest = 'tgtHost',type = 'string',help = 'specify target host')

    parser.add_option('-p',dest = 'tgtPort',type ='int',help = 'specify target port')

    (options,args) = parser.parse_args()

    tgtHost = options.tgtHost

    tgtPort = options.tgtPort


    if(tgtHost == None) or (tgtPort == None):

        print('[-] You must specify a target host and port[s]!')

        exit(0)

    portScan(tgtHost,args)


if __name__ == '__main__':
    main()
 运行结果如下:
 
   

你可能感兴趣的:(Python)