-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmasnmapcan_py3.py
executable file
·170 lines (151 loc) · 5.33 KB
/
masnmapcan_py3.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import argparse
import sys
import nmap
import datetime
import threading
import requests
import re
import json
import os
from queue import Queue
import urllib3
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(e)
pass
def portscan(scan_ip):
"""
调用masscan程序进行端口扫描
"""
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(json.dumps(line[:-2] + "}"))
temp1 = eval(temp)["ports"][0]
temp_ports.append(str(temp1["port"]))
if len(temp_ports) > 50:
temp_ports.clear() # 如果端口数量大于50,说明可能存在防火墙,属于误报,清空列表
else:
ports.extend(temp_ports) # 小于50则放到总端口列表里
def Title(scan_url_port,service_name):
"""
获取网站的web应用程序名和网站标题信息
"""
try:
r = requests.get(scan_url_port, timeout=3, verify=False, )
response = re.findall(u'<title>(.*?)</title>', r.content.decode("utf-8"), re.S)
if response == []:
final_domains.append((scan_url_port + '\t' + service_name).encode())
else:
# 若网站的响应头中无server字段,直接写入无server,若有就写
banner = "无server"
try:
banner = r.headers['server']
except Exception as e:
pass
finally:
final_domains.append(scan_url_port + b'\t' + banner.encode("utf-8") + b'\t' + str(response[0]).encode("utf-8"))
except Exception as e:
print(e)
pass
def Scan(scan_ip):
"""
调用nmap识别服务
"""
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)).encode()
Title(scan_url_port, service_name)
else:
scan_url_port = ('http://' + scan_ip + ':' + str(port)).encode()
Title(scan_url_port, service_name)
else:
final_domains.append((scan_ip + ':' + str(port) + '\t' + service_name).encode())
except Exception as e:
print(e)
def parse_args():
parser = argparse.ArgumentParser(epilog='\tExample: \r\npython3 ' + sys.argv[0] + " -i 192.168.1.1")
parser.add_argument("-i", "--ip", help="The scan ip")
parser.add_argument("-f", "--file", help="The scan ip list file")
parser.add_argument("-o", "--output", help="Output file name")
parser.add_argument("-t", "--thread", help="Number of Threads", default=100)
return parser.parse_args()
def main(ip_list_file):
"""
启用多线程扫描
"""
queue = Queue()
try:
# 单个ip扫描
if args.ip:
final_ip = args.ip
queue.put(final_ip)
threads = []
for i in range(int(args.thread)):
threads.append(PortScan(queue))
for t in threads:
t.start()
for t in threads:
t.join()
else:
# 批量ip扫描
f = open(ip_list_file, 'rb')
for line in f.readlines():
final_ip = line.decode().strip('\n')
queue.put(final_ip)
threads = []
for i in range(int(args.thread)):
threads.append(PortScan(queue))
for t in threads:
t.start()
for t in threads:
t.join()
f.close()
except Exception as e:
print(e)
pass
if __name__ == '__main__':
start_time = datetime.datetime.now()
urllib3.disable_warnings()
args = parse_args()
# 判断是否指定ip列表文件
if args.file == None:
main("ip.txt")
else:
main(args.file)
tmp_domians = []
for tmp_domain in final_domains:
if tmp_domain not in tmp_domians:
tmp_domians.append(tmp_domain)
# 判断是否指定文件输出
if args.output:
os.mknod(args.output) #创建文件
for url in tmp_domians:
with open(args.output, 'ab+') as ff:
ff.write(url + '\n'.encode())
else:
for url in tmp_domians:
with open(r'scan_url_port.txt', 'ab+') as ff:
ff.write(url + '\n'.encode())
spend_time = (datetime.datetime.now() - start_time).seconds
print('程序共运行了: ' + str(spend_time) + '秒')