失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【Python脚本进阶】2.1 端口扫描器(上):TCP全连接扫描

【Python脚本进阶】2.1 端口扫描器(上):TCP全连接扫描

时间:2020-04-30 22:56:24

相关推荐

【Python脚本进阶】2.1 端口扫描器(上):TCP全连接扫描

目录

一、简介

1.1、基础:

1.2、TCP:

二、TCP全连接扫描

2.1、简介:

2.2、函数:

2.3、实现:

第一步:获得主机名和端口

第二步: connScan和portScan函数

第三步:抓应用的Banner

第四步:线程扫描

第五步:加锁

2.4、合体:

一、简介

1.1、基础:

扫描目标主机开放的TCP 端口的侦查脚本。当然, 为了与TCP 端口进行交互, 要建立TCP 套接字。

Python 也提供了访问BSD 套接字的接口。BSD 套接字提供了一个应用编程接口(API) , 使程序员能编写在主机之间进行网络通信的应用程序。通过一系列的套接字API 函数, 我们可以创建、绑定、监听、连接, 或在TCP/IP 套接字上发送数据。在这一点上, 为了进一步开发我们自己的攻击程序, 必须对TCP/lP 套接字有一个更深入的了解。

1.2、TCP:

大多数能访问互联网的应用使用的都是TCP 协议。例如, Web 服务器可能位于TCP 80 端口, 电子邮件服务器在TCP25 端口, FTP 服务器在TCP21 端口。要连接目标组织中的任一服务器, 攻击者必须知道与服务器相关联的IP 地址和TCP 端口。

网络攻击一般都是以端口扫描开始。有一种类型的端口扫描会向一系列常用的端口发送TCP SYN 数据包, 并等待TCP ACK 响应一一这能让我们确定这个端口是开放的。相反,TCP 连接扫描是使用完整的三次握手来确定服务器或端口是否可用的

二、TCP全连接扫描

2.1、简介:

用TCP 全连接扫描来识别主机的TCP 端口的扫描器。

要导入Python 的BSD 套接字API 实现。套接字API 会为我们提供一些在实现TCP 端口扫描程序时有用的函数。要更深入地了解Python 标准库文档

2.2、函数:

socket.gethostbyname(hostname)

此功能以主机名这样如并返回IPv4地址格式69.163.177.2

socket.gethostbyaddr(ip address)

此功能采用IPv4地址并重新添加一个包含HOS名称的三倍,替代名称。主机名和同一接口的IPv4/V6地址列表在主机上。

socket.socket(\[family\[, type\[, proto]]])

此功能创建一个一个新socket的实例给定family。socket的选项family为af_inet,af_inet6或af_unix。此外,socket可以指定为tcp套接字或sock_dgram的sock_streamUDPsocket。最后,协议编号通常为零,并且在大多数情况下被省略。

socket.create_connection(address\[, timeout\[, source_address]])

这个功能采用2核(主机,端口),并返回一个实例网络socket。此外,它还可以选择超时和源地址。

2.3、实现:

第一步:获得主机名和端口

从用户那里获得主机名和端口。为了做到这一点, 我们在程序中使用optparse 库解析命令行参数。调用optparse.OptionPaser ([usage message])会生成一个参数解析器(option parser) 类的实例。接着, 在parser.add_option 中指定这个脚本具体要解析哪个命令行参数。下面的例子显示了一个快速解析要扫描的目标主机名和端口的方法。

import optparseparser = optparse.OptionParser('usage %prog - H' + '<target host> -p <targe port>')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.tgtHosttgtPort = options.tgtPortif (tgtHost == None) | (tgtPort == None) :print(parser.usage)exit(0)

第二步: connScan和portScan函数

两个函数: connScan和portScan

portScan函数以参数的形式接收主机名和目标端口列表。它首先会尝试用gethostbyname()函数确定主机名对应的IP地址。

使用connScan函数输出主机名(或IP地址), 并使用connScan()函数尝试逐个连接我们要连接的每个端口。connScan 函数接收两个参数: tgtHost 和tgtPort, 它会去尝试建立与目标主机和端口的连接。如果成功, connScan将打印出一个端口开放的消息。如果不成功,它会打印出端口关闭的消息。

import optparsefrom socket import *def connScan(tgtHost, tgtPort):try:connSkt = socket(AF_INET, SOCK_STREAM)connSkt.connect((tgtHost,tgtPort))print('[+] %d/tcp open' % tgtPort)connSkt.close()except:print('[-] %d/tcp closed' % tgtPort)def portScan(tgtHost, tgtPorts):try:tgtIP = gethostbyname(tgtHost)except:print('[-] Cannot resolve ' %s ':Unknown host' %tgtHost)returntry:tgtName = gethostbyaddr(tgtIP)print('\n[+] Scan Results for: '+ tgtName[0])except:print('\n[+] Scan Results for: '+ tgtIP)setdefaulttimeout(1)for tgtPort in tgtPorts:print('[+] Scanning port ' + tgtPort)connScan(tgtHost,int(tgtPort))

第三步:抓应用的Banner

为了抓取目标主机上应用的Banner, 先在connScan 函数中插入一些新增的代码。找到开放的端口后, 向它发送一个数据串并等待响应。跟进收集到的响应,推断出在目标主机和端口上运行的应用

import optparseimport socketfrom socket import *def connScan(tgtHost, tgtPort):try:connSkt = socket(AF_INET, SOCK_STREAM)connSkt.connect((tgtHost,tgtPort))connSkt.send(bytes('ViolentPython\r\n',"utf8"))results = connSkt.recv(100)print('[+] %d/tcp open' % tgtPort)print( '[+] ' + str( results ) )connSkt.close()except:print('[-] %d/tcp closed' % tgtPort)def portScan(tgtHost, tgtPorts):try:tgtIP = gethostbyname(tgtHost)except:print('[-] Cannot resolve ' %s ':Unknown host' %tgtHost)returntry:tgtName = gethostbyaddr(tgtIP)print('\n[+] Scan Results for: '+ tgtName[0])except:print('\n[+] Scan Results for: '+ tgtIP)setdefaulttimeout(1)for tgtPort in tgtPorts:print('Scanning port ' + tgtPort)connScan(tgtHost,int(tgtPort))def main():parser = optparse.OptionParser("usage%prog " + "-H <target host> -p <target port>")parser.add_option('-H', dest='tgtHost', type='string', help='specify target host')parser.add_option('-p', dest='tgtPort', type='string',help='specify target port[s] separated by comma')(options, args) = parser.parse_args()tgtHost = options.tgtHosttgtPorts = str(options.tgtPort).split (', ')if (tgtHost == None) | (tgtPorts[0] == None):print('[一] You must specify a target host and port[s].')exit(0)portScan(tgtHost,tgtPorts)if __name__ == '__main__':main()

第四步:线程扫描

根据套接字中timeout变量的值, 每扫描一个套接字都会花费几秒钟。但如果我们要扫描多个主机或端口, 时间总量就会成倍增加。同时扫描多个套接字进行扫描。必须引入Python线程, 线程是一种能提供这类同时执行多项任务的方法。具体到我们这个扫描器, 我们要修改的是portScan()函数中迭代循环里的代码

for tgtPort in tgtPorts:t = Thread(target=connScan, args=(tgtHost, int(tgtPort)))t.start()

第五步:加锁

速度显著提升, 但connScanO函数在屏幕上打印一个输出。如果多个线程同时打印输出, 就可能会出现乱码和失序。

为了让一个函数获得完整的屏幕控制权, 需要使用一个信号量(semaphore)。一个简单的信号量就能阻止其他线程运行。注意, 在打印输出前, 我们用screenLock.acquire()执行一个加锁操作。如果信号量还没被锁上, 线程就有权继续运行, 并输出打印到屏幕上。如果信号量已经被锁定, 只能等待, 直到持有信号量的线程释放信号量。通过利用信号量, 能够确保在任何给定的时间点上只有一个线程可以打印屏幕。在异常处理代码中, 位千fmally关键字前面的是在终止阻塞(其他线程)之前需要执行的代码

screenLock = Semaphore(value=1)def connScan(tgtHost, tgtPort):try:connSkt = socket(AF_INET, SOCK_STREAM)connSkt.connect((tgtHost,tgtPort))connSkt.send(bytes('ViolentPython\r\n',"utf8"))results = connSkt.recv(100)screenLock.acquire()print('[+] %d/tcp open' % tgtPort)print( '[+] ' + str( results ) )except:screenLock.acquire()print('[-] %d/tcp closed' % tgtPort)finally:screenLock.release()connSkt.close()

2.4、合体:

把所有的函数放入同一个脚本中, 并添加一些参数解析代码, 这就有了我们最终的端口扫描器脚本。

import optparseimport socketfrom socket import *screenLock = Semaphore(value=1)def connScan(tgtHost, tgtPort):try:connSkt = socket(AF_INET, SOCK_STREAM)connSkt.connect((tgtHost,tgtPort))connSkt.send(bytes('ViolentPython\r\n',"utf8"))results = connSkt.recv(100)screenLock.acquire()print('[+] %d/tcp open' % tgtPort)print( '[+] ' + str( results ) )except:screenLock.acquire()print('[-] %d/tcp closed' % tgtPort)finally:screenLock.release()connSkt.close()def portScan(tgtHost, tgtPorts):try:tgtIP = gethostbyname(tgtHost)except:print('[-] Cannot resolve ' %s ':Unknown host' %tgtHost)returntry:tgtName = gethostbyaddr(tgtIP)print('\n[+] Scan Results for: '+ tgtName[0])except:print('\n[+] Scan Results for: '+ tgtIP)setdefaulttimeout(1)for tgtPort in tgtPorts:t = Thread( target=connScan, args=(tgtHost, int( tgtPort )) )t.start()def main():parser = optparse.OptionParser("usage%prog " + "-H <target host> -p <target port>")parser.add_option('-H', dest='tgtHost', type='string', help='specify target host')parser.add_option('-p', dest='tgtPort', type='string',help='specify target port[s] separated by comma')(options, args) = parser.parse_args()tgtHost = options.tgtHosttgtPorts = str(options.tgtPort).split (', ')if (tgtHost == None) | (tgtPorts[0] == None):print(parser.usage)exit(0)portScan(tgtHost,tgtPorts)if __name__ == '__main__':main()

如果觉得《【Python脚本进阶】2.1 端口扫描器(上):TCP全连接扫描》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。