在信息收集阶段,端口开放情况尤为重要
服务器看做房子,则端口就是进出房子的门
不同的端口(门)可以指向不同的服务(房间)
import sys
import socket
from optparse import OptionParser
import queue
from threading import Thread
# 使用Socket模块编写一个简便的多线程端口扫描工具
# 编写一个端口扫描类
class PortScan(Thread):
# 需要传入端口队列、目标IP,探测超时时间
def __init__(self,portqueue,ip,timeout=3):
Thread.__init__(self)
self._portqueue = portqueue
self._ip = ip
self._timeout = timeout
def run(self):
while True:
# 判断端口队列是否为空
if self._portqueue.empty():
# 端口队列为空,说明已经扫描完毕,跳出循环
break
# 从端口队列中取出端口,超时时间为1s
port = self._portqueue.get(timeout=0.5)
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(self._timeout)
result_code = s.connect_ex((self._ip, port))
# sys.stdout.write("[%d]Scan\n" % port)
#若端口开放,则会返回0
if result_code == 0:
sys.stdout.write("[%d]Scan\n" % port)
except Exception as e:
print(e)
finally:
s.close()
# 编写一个函数,根据用户的参数来指定目标IP、端口队列的生成以及子线程的生成
# 同时能支持单个端口扫描和范围端口的扫描
def StartScan(targetip, port, threadNum):
# 端口列表
portList = []
portNum = port
# 判断是单个端口还是范围端口
if '-' in port:
for i in range(int(port.split('-')[0]), int(port.split('-')[1])+1):
portList.append(i)
else:
portList.append(int(port))
# 目标ip地址
ip = targetip
# 线程列表
threads = []
# 线程数量
threadNumber = threadNum
# 端口队列
portQueue = queue.Queue()
# 生成端口,加入端口队列
for port in portList:
portQueue.put(port)
for t in range(threadNumber):
threads.append(PortScan(portQueue,ip,timeout=3))
# 启动线程
for thread in threads:
thread.start()
# 阻塞线程
for thread in threads:
thread.join()
# 编写主函数制定参数的规则
if __name__ == '__main__':
parser = optparse.OptionParser('Example:python %prog -i 127.0.0.1 -p 80 \n python %prog -i 127.0.0.1 -p 1-100\n')
# 目标IP参数 -i
parser.add_option('-i','--ip',dest='targetIP',default='127.0.0.1',type='string',help='target IP')
parser.add_option('-p', '--port', dest='port', default='80', type='string', help='scann port')
# 线程数量参数 -t
parser.add_option('-t', '--thread', dest='threadNum', default='100', type='int', help='scann thread number')
(options,args) = parser.parse_args()
StartScan(options.targetIP,options.port,options.threadNum)
默认端口可以改为:default='1-65535'
只要是开放的端口都可以打印出来