文章目录
- socket套接字
- optparse模块
- socket解析主机进行连接
- 获取banner
- threading多线程
- 端口扫描器
- python-nmap端口扫描
对自己看python绝技的一次学习记录
socket套接字
与TCP端口进行交互,先建立TCP套接字
需要导入python的BCD套接字API模块socket
socketAPI提供了一系列的函数将用来实现TCP端口扫描
函数名称 | 返回内容 |
---|
socket.gethostbyname(hostname) | 这个函数将主机名换为ip地址,例如:www.xxx.com会返回IPv4地址:1.1.1.1 |
socket.gethostbyaddr(ip_address) | 这个函数传入一个IP地址将返回一个元组,其中包含主机名,别名列表和同一接口的ip地址列表 |
socket.socket() | 这个函数将产生一个新的socket,通过给定的socket地址簇和socket类型,地址簇的可以是AF_INET(默认),AF_INET6或者是AF_UNIX,另外,socket类型可以为一个TCP套接字即SCO_STREAM(默认),或者是UDP套接字即SOCK_DGRAM,或者其他的套接字类型。最后协议号通常为零,在大多数情况下省略不写。 |
socket.create_connection | 这个函数传入一个包含ip地址和端口号的二元元组返回一个socket对象,此外还可以选择超时重连 |
optparse模块
第一步,我们输入目标主机名和要扫描的常用端口列表,接着,我们将通过目标主机名得到目标的网络ip地址。我们将用列表里面的每一个端口去连接目标地址,最后确定端口上运行的特殊服务。我们将发送特定的数据,并读取特定应用程序返回的标识。
在我们的第一步中,我们从用户那接受主机名和端口。因此我们的程序将利用 optparse 标准库来解析命令行选项,调用 optparse.OptionParser()创建一个选项分析器,然后通过 parser.add_option()函数来指定命令选项。(注:optparse 模块在 2.7 版本后将被弃用也不会得到更新,会使用 argparse 模块来替代)下面的例子显示了一个快速解析目标主机和扫描端口的方法。
首先定义帮助以及设置参数功能
代码如下:
import optparse
parser = optparse.OptionParser('usage %prog -H <target host> -p <target port>') #定义帮助信息
parser.add_option('-H',dest='tgtHost',type='string',help='specify target host') #-H输入主机
parser.add_option('-p', dest='tgtPort', type='int', help='specify target port') #-p输入端口
(options, args) = parser.parse_args()
tgtHost = options.tgtHost
tgtPort = options.tgtPort
if (tgtHost == None) | (tgtPort == None):
print(parser.usage)
exit(0)
else:
print(tgtHost)
print(tgtPort)
返回结果:
socket解析主机进行连接
接下来,我们将构建两个函数connscan和portscan,portscan函数需要主机名和端口作为参数。它首先尝试通过gethostbyname函数解析出ip地址,接着打印,然后connscan作用为连接主机,需要两个参数tgtHost和tgtport
代码如下:
import socket
def connScan(tgtHost, tgtPort):
try:
connSkt = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #实例化socket
connSkt.connect((tgtHost, tgtPort)) #建立连接
print('[+]%d/tcp open' % tgtPort) #输出
connSkt.close() #关闭连接
except:
print('[-]%d/tcp closed' % tgtPort)
def portScan(tgtHost,tgtPorts):
try:
tgtIP = socket.gethostbyname(tgtHost) #获取传入主机名的ip
except:
print("[-] Cannot resolve '%s': Unknown host" %tgtHost) #获取不了ip的化直接输出无法获取结束运行
return
try:
tgtName = socket.gethostbyaddr(tgtIP) #获取ip的主机名、别名、ip
print('\n[+] Scan Results for: ' + tgtName[0]) #索引0获取主机名
except:
print('\n[+] Scan Results for: ' + tgtIP) #为获取则输出ip
socket.setdefaulttimeout(1)
for tgtPort in tgtPorts:
print('Scanning port ' + str(tgtPort)) #遍历输出正在查询的端口
connScan(tgtHost, int(tgtPort)) #调用connScan函数,传入主机和端口
print portScan('www.baidu.com',[80,443,3389,1433,23,445])
返回结果:
[+] Scan Results for: 39.156.66.14
Scanning port 80
[+]80/tcp open
Scanning port 443
[+]443/tcp open
Scanning port 3389
[-]3389/tcp closed
Scanning port 1433
[-]1433/tcp closed
Scanning port 23
[-]23/tcp closed
Scanning port 445
[-]445/tcp closed
获取banner
也可以在程序中加上收发端口banner信息的代码,这样就可以尝试识别端口具体信息
代码如下:
connSkt.send('SanSs\r\n') #发送数据
results = connSkt.recv(100) #接收数据
返回结果:
[+]80/tcp open
[+] HTTP/1.1 400 Bad Request
threading多线程
因为我们在扫描中是使用单线程进行扫描的,在速度方面存在一定问题,我们可以引入python线程,在迭代的过程中产生的每一个线程将在同时执行。
for tgtPort in tgtPorts:
print('Scanning port ' + str(tgtPort)) #遍历输出正在查询的端口
t = threading.Thread(target=connScan, args=(tgtHost,int(tgtPort))) #多线程处理connScan函数
t.start() #开启进程
端口扫描器
多线程在速度上有很大优势,但是再打印屏幕内容的时候如果在同一时刻打印就可能会出现乱序,为了让函数完整正确输入信息我们可以用screenLock.acquire()来加锁,如果锁打开,信号量将允许线程继续运行然后打印输出,如果锁定,我们将要等到控制信号量的进程释放锁。利用信号量,我们可以保证在任何个定的时间只有一个线程在打印屏幕输出。
将所有代码结合:
# -*- 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) #实例化socket
connSkt.connect((tgtHost, tgtPort)) #建立连接
connSkt.send('SanSs\r\n') #发送数据
results = connSkt.recv(100) #接收数据
screenLock.acquire()
print('[+]%d/tcp open' % tgtPort)
print('[+] ' + str(results))
except:
screenLock.release()
print('[-]%d/tcp closed' % tgtPort+'\n')
finally:
screenLock.release()
connSkt.close()
def portScan(tgtHost,tgtPorts):
try:
tgtIP = socket.gethostbyname(tgtHost) #获取传入主机名的ip
except:
print("[-] Cannot resolve '%s': Unknown host" %tgtHost) #获取不了ip的化直接输出无法获取结束运行
return
try:
tgtName = socket.gethostbyaddr(tgtIP) #获取ip的主机名、别名、ip
print('\n[+] Scan Results for: ' + tgtName[0]) #索引0获取主机名
except:
print('\n[+] Scan Results for: ' + tgtIP) #为获取则输出ip
socket.setdefaulttimeout(1)
for tgtPort in tgtPorts:
print('Scanning port ' + str(tgtPort)) #遍历输出正在查询的端口
t = threading.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') # -H输入主机
parser.add_option('-p', dest='tgtPort', type='int', help='specify target port') # -p输入端口
(options, args) = parser.parse_args()
tgtHost = options.tgtHost
tgtPort = options.tgtPort
args.append(tgtPort)
if (tgtHost == None) | (tgtPort == None):
print(parser.usage)
exit(0)
else:
portScan(tgtHost,args)
if __name__ == '__main__':
main()
返回结果:
python-nmap端口扫描
使用python-nmap进行python调用nmap端口扫描
代码如下
# coding=UTF-8
import optparse
import nmap
def nmapScan(tgtHost, tgtPort):
nmScan = nmap.PortScanner()
results = nmScan.scan(tgtHost, tgtPort)
state = results['scan'][tgtHost]['tcp'][int(tgtPort)]['state']
print(" [*] " + tgtHost + " tcp/" + tgtPort + " " + state)
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')
(options, args) = parser.parse_args()
tgtHost = options.tgtHost
tgtPort = options.tgtPort
args.append(tgtPort)
if (tgtHost == None) | (tgtPort == None):
print('[-] You must specify a target host and port[s]!')
exit(0)
for tgport in args:
nmapScan(tgtHost, tgport)
if __name__ == '__main__':
main()
返回结果:
[*] 1.1.1.1 tcp/443 open
[*] 1.1.1.1 tcp/80 open
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)