-
Notifications
You must be signed in to change notification settings - Fork 150
/
masnmapcan-V1.0.py
197 lines (172 loc) · 6.16 KB
/
masnmapcan-V1.0.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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/usr/bin/python
# coding: utf-8
import nmap
import datetime
import time
import threading
import requests
import chardet
import re
import json
import os
import sys
import socket
import Queue
requests.packages.urllib3.disable_warnings()
reload(sys)
sys.setdefaultencoding('utf-8')
ports = []
final_url = []
ips = []
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:
Masportscan(scan_ip)
Nmapscan(scan_ip)
except Exception as e:
print e
pass
# 调用masscan
def Masportscan(scan_ip):
temp_ports = [] # 设定一个临时端口列表
os.system('../masscan/bin/masscan ' + scan_ip + ' -p 1-65535 -oJ masscan.json --rate 1000')
# 提取json文件中的端口
with open('masscan.json', 'r') as f:
for line in f:
if line.startswith('{ '):
temp = json.loads(line[:-2])
temp1 = temp["ports"][0]
temp_ports.append(str(temp1["port"]))
if len(temp_ports) > 50:
temp_ports.clear() # 如果端口数量大于50,说明可能存在防火墙,属于误报,清空列表
else:
ports.extend(temp_ports) # 小于50则放到总端口列表里
# 调用nmap识别服务
def Nmapscan(scan_ip):
nm = nmap.PortScanner()
try:
for port in ports:
ret = nm.scan(scan_ip, port, arguments='-sV')
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:
with open('result.txt', 'ab+') as f:
f.writelines(scan_ip + '\t\t' + 'port: ' + str(port) + '\t\t' + service_name + '\n')
except Exception as e:
print e
pass
# 获取网站的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)
actual_encode = r_detectencode['encoding']
response = re.findall(u'<title>(.*?)</title>', r.content, re.S)
if response == []:
with open('result.txt', 'ab+') as f:
f.writelines('[*] Website: ' + scan_url_port + '\t\t' + service_name + '\n')
else:
# 将页面解码为utf-8,获取中文标题
res = response[0].decode(actual_encode).decode('utf-8').encode('utf-8')
banner = r.headers['server']
with open('result.txt', 'ab+') as f:
f.writelines('[*] Website: ' + scan_url_port + '\t\t' + banner + '\t\t' + 'Title: ' + res + '\n')
except Exception as e:
print e
pass
# 扫描结果去重
def Removedup():
if os.path.exists('result.txt'):
for line in open('result.txt', 'rb'):
if line not in final_url:
final_url.append(line)
with open('final_result.txt', 'ab+') as f:
f.writelines(line)
time.sleep(1)
os.remove('result.txt')
for line in open('final_result.txt', 'rb'):
if 'Website' in line:
line = line.strip('\n\r\t').split('\t\t')[0].replace('[*] Website: ', '')
with open('url.txt', 'ab+') as f:
f.writelines(line+'\n')
else:
pass
# 获取子域名对应ip
def Get_domain_ip():
f = open(r'subdomain.txt', 'rb')
for line in f.readlines():
try:
if 'www.' in line:
extract_line = line.replace('www.', '')
print line.strip('\n\r\t'), socket.gethostbyname(extract_line.strip('\n\r\t'))
with open('subdomain-ip.txt', 'ab+') as l:
l.writelines(line.strip('\n\r\t') + '\t\t' + socket.gethostbyname(extract_line.strip('\n\r\t')) + '\n')
else:
print line.strip('\n\r\t'), socket.gethostbyname(line.strip('\n\r\t'))
with open('subdomain-ip.txt', 'ab+') as l:
l.writelines(line.strip('\n\r\t') + '\t\t' + socket.gethostbyname(line.strip('\n\r\t')) + '\n')
except Exception, e:
print e
pass
time.sleep(1)
# 对子域名解析的ip进行去重
ip_temps = []
l = open(r'subdomain-ip.txt', 'rb')
for line in l.readlines():
line = line.strip('\n\t\r').split('\t\t')[-1]
ips.append(line)
for ip_temp in ips:
if ip_temp not in ip_temps:
ip_temps.append(ip_temp)
for ip in ip_temps:
with open('ip.txt', 'ab+') as f:
f.writelines(ip + '\n')
f.close()
l.close()
time.sleep(1)
# 传入ip启用多线程
def Multithreading():
queue = Queue.Queue()
f = open(r'ip.txt', 'rb')
for line in f.readlines():
final_ip = line.strip('\n')
queue.put(final_ip)
threads = []
thread_count = 200
for i in range(thread_count):
threads.append(PortScan(queue))
for t in threads:
t.start()
for t in threads:
t.join()
f.close()
# 判断扫描文件是否存在,存在则直接扫描,不存在则调用域名解析
def main():
try:
if os.path.exists('ip.txt'):
Multithreading()
else:
Get_domain_ip()
Multithreading()
except Exception as e:
print e
pass
if __name__ == '__main__':
start_time = datetime.datetime.now()
main()
Removedup()
spend_time = (datetime.datetime.now() - start_time).seconds
print 'The program is running: ' + str(spend_time) + ' second'