python3实现端口扫描器
#!/usr/bin/python# coding=utf-8import nmapimport datetimeimport threadingimport requestsimport chardet#编码检测import reimport jsonimport osrequests.packages.urllib3.disable_warnings()#关闭warning...
·
#!/usr/bin/python
# coding=utf-8
import nmap
import datetime
import threading
import requests
import chardet#编码检测
import re
import json
import os
requests.packages.urllib3.disable_warnings()#关闭warning
import Queue
#存储所有扫描的IP及端口服务
final_domains = []
#临时列表
ports = []
class PortScan(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self._queue = queue
def run(self):
while not self._queue.empty():
scan_ip = self._queue.get()
try:
portscan(scan_ip)
Scan(scan_ip)
except Exception as e:
print('this is an error:',e)
pass
#调用masscan
def portscan(scan_ip):
temp_ports = [] #设定一个临时端口列表
os.system('masscan/bin/masscan ' + scan_ip + ' -p 1-65535 -oJ masscan.json --rate 2000')
#提取json文件中的端口
with open('masscan.json', 'r') as f:
for line in f:
if line.startswith('{ '):
temp = json.loads(line[:-2]) # 取出一条完整json形式的数据
temp1 = temp["ports"][0]
temp_ports.append(str(temp1["port"]))# 端口取出加入临时端口中
if len(temp_ports) >25:
temp_ports.clear() #如果端口数量大于30,说明可能存在防火墙,属于误报,清空列表
else:
ports.extend(temp_ports) #小于30则放到总端口列表里
#获取网站的web应用程序名和网站标题信息
def Title(scan_url_port,service_name):
try:
r = requests.get(scan_url_port,timeout=3,verify=False)
#获取网站的页面编码
r_detectencode = chardet.detect(r.content)# 利用chardet模块检测编码
actual_encode = r_detectencode['encoding']
response = re.findall(u'<title>(.*?)</title>',r.content,re.S)# re.S的作用 匹配的时候扩展到整个字符串(包括换行这些\n)
if response:
#将页面解码为utf-8,获取中文标题
res = response[0].decode(actual_encode).decode('utf-8')
banner = r.headers['server']
final_domains.append(scan_url_port + '\t' + banner + '\t' + res)
else:
final_domains.append(scan_url_port + '\t' + service_name)
except Exception as e:
print("this is an error:",e)
#调用nmap识别服务
def Scan(scan_ip):
nm = nmap.PortScanner()
try:
for port in ports:
ret = nm.scan(scan_ip,port,arguments='-Pn,-sS')
service_name = ret['scan'][scan_ip]['tcp'][int(port)]['name']
print('[*]主机 ' + scan_ip + ' 的 ' + str(port) + ' 端口服务为:' + service_name)
if 'http' in service_name or service_name == 'sun-answerbook':
if service_name == 'https' or service_name == 'https-alt':
scan_url_port = 'https://' + scan_ip + ':' + str(port)
Title(scan_url_port,service_name)
else:
scan_url_port = 'http://' + scan_ip + ':' + str(port)
Title(scan_url_port,service_name)
else:
final_domains.append(scan_ip+':'+str(port)+'\t'+service_name)
except Exception as e:
print('this is an error:',e)
ports.clear()#扫完一次之后清理
#启用多线程扫描
def main():
queue = Queue(1000)
try:
f = open(r'ip.txt', 'rb')
for line in f.readlines():
final_ip = line.strip('\n')
queue.put(final_ip)
threads = []
thread_count = 100
for i in range(thread_count):
threads.append(PortScan(queue))
for t in threads:
t.start()
for t in threads:
t.join()
f.close()
except Exception as e:
print('this is an error:',e)
pass
if __name__ =='__main__':
start_time = datetime.datetime.now()
main()#主进程
tmp_domians = []
for tmp_domain in final_domains:
if tmp_domain not in tmp_domians:
tmp_domians.append(tmp_domain)
for url in tmp_domians:
with open(r'scan_url_port.txt', 'ab+') as ff:
ff.write(url+'\n')
spend_time = (datetime.datetime.now() - start_time).seconds
print ('程序共运行了: ' + str(spend_time) + '秒')
参考文章:https://www.freebuf.com/sectool/204578.html
更多推荐
已为社区贡献1条内容
所有评论(0)