用Python进行渗透测试
- 编写一个端口扫描器
- 构建一个SSH僵尸网络
- 通过FTP批量抓取肉机
- 重现蠕虫病毒
- 构建攻击脚本
蠕虫历史
22年,Morris蠕虫病毒使用了一个三管齐下的攻击方式入侵系统,首先利用了UNIX邮件发送程序中的漏洞,其次利用UNIX系统的finger守护进程中的一个独立的漏洞。最后,它会利用一些常见的用户名/密码,尝试连接那些使用RSH(远程shell)协议目标主机,只要三个攻击中的任何一个成功,蠕虫就会执行一个小程序,下载并执行病毒的剩余部分。Morris中的大部分攻击代码都是用C语言写的,我们将用Python重现Morris蠕虫的部分功能及现代的攻击方法。
编写一个端口扫描器
Python提供了访问BSD套接字的接口,BSD套接字提供了一个应用编程接口(API),能编写在主机之间进行网络通信的应用程序,通过一系列的套接字API函数,我们可以创建,绑定,监听,连接或在TCP/IP套接字上发送数据。TCP连接扫描是实用完整的三次握手来确定服务器或端口是否使用。
输入一个主机名和逗号分隔的端口列表,并予以扫描。
我们在程序中使用optparse库解析命令行参数,调用optparse.OptionPaser([usage message])会生成一个参数解析器(option parser)类的实例。接着,在parser.add_option中指定这个脚本具体要解析哪个命令行参数。下面是快速解析扫描的目标主机和端口的方法。
import optparse 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='string', help='specify target port') (options, args) = parser.parse_args() tgtHost = options.tgtHost tgtPort = options.tgtPort if tgtHost == None or tgtPort == None: print(parser.usage) exit(0) else: print(tgtHost) print(tgtPort)
将主机名转换成IPv4互联网地址,对列表每个端口,我们都会连接目标地址与该端口。
尝试建立与扫描出来的目标主机和端口进行连接。
from 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 Exception: print('[-] %d/tcp closed' % tgtPort) def portScan(tgtHost, tgtPorts): try: tgtIP = gethostbyname(tgtHost) except: print("[-] Cannot resolve '%s': Unknown host" % tgtHost) return try: tgtName = gethostbyaddr(tgtHost) print("\n[+] Scan Results for: " + tgtName[0]) except: print("\n[-] Scan Results for: " + tgtIP) setdefaulttimeout(1) for tgtPost in tgtPorts: print("Scannint port " + tgtPost) connScan(tgtHost, tgtPost)
发送垃圾数据并读取具体应用返回的Banner。
抓取目标主机上的应用的Banner,找到开放的端口发送数据串并等待响应,收集响应判断出在目标主机和端口上运行的应用。
from socket import * def connScan(tgtHost, tgtPort): try: connSkt = socket(AF_INET, SOCK_STREAM) connSkt.connect((tgtHost, tgtPort)) connSkt.send('Hello Python\r\n') results = connSkt.recv(1024) print('[+] {}/tcp open'.format(tgtPort)) print('[+] ' + str(results)) connSkt.close() except: print('[-] {}/tcp closed'.format(tgtPort)) def portScan(tgtHost, tgtPorts): try: tgtIP = gethostbyname(tgtHost) except: print("[-] Cannot resolve '{}': Unknown host".format(tgtHost)) return try: #通过主机名获取地址 In [6]: socket.gethostbyaddr('www.baidu.com') Out[6]: ('127.0.0.1', [], ['119.75.216.20']) 主机名 别名 IP 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, tgtPort) def main(): import optparse 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='string', help='specify target port') (options, args) = parser.parse_args() tgtHost = options.tgtHost tgtPorts = (options.tgtPort).split(' ') if tgtPorts[0] == None or tgtHost == None: print('[-] You must specify a target host and port[s].') exit(0) portScan(tgtHost, tgtPorts) if __name__ == '__main__': main()