-
Notifications
You must be signed in to change notification settings - Fork 0
/
distributed_scan.py
131 lines (100 loc) · 3.6 KB
/
distributed_scan.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
#!flask/bin/python
from flask import Flask, jsonify, request
import random
import os
import string
import subprocess
import json
import validator
import xmltodict
import parser
app = Flask(__name__)
validator = validator.Validator()
parser = parser.PortScanResultParser()
@app.route('/masscan', methods=['POST'])
def masscan():
try:
if os.path.exists('masscan.lock'):
return jsonify({"error": "Scan already running"})
else:
os.system('touch masscan.lock')
content = request.get_json(silent=True)
valid = validator.validate_request(content)
if valid is not None:
os.remove('masscan.lock')
return valid
fn = 'masscan_{0}.json'.format(''.join(random.choice(string.ascii_letters) for i in range(8)))
command = "masscan "
if 'host' in content:
command += content['host']
else:
command += content['cidr']
command += ' -p '
if 'start_port' in content and 'end_port' in content:
command += '{0}-{1}'.format(content['start_port'], content['end_port'])
else:
command += ','.join([str(i) for i in content['ports']])
command += ' -oJ {0} --rate=100'.format(fn)
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
process.wait()
results = open(fn, 'r').read()
os.remove(fn)
json_data = json.loads(results[:-4] + ']')
if results != '':
try:
os.remove('masscan.lock')
return (jsonify(parser.parse_masscan_results(json_data)))
except:
os.remove('masscan.lock')
return (jsonify({'error': "bad_results_json"}))
else:
return jsonify({})
except Exception as e:
os.remove('nmap.lock')
return jsonify({"error": e})
@app.route('/nmap', methods=['POST'])
def nmap():
try:
if os.path.exists('nmap.lock'):
return jsonify({"error": "Scan already running"})
else:
os.system('touch nmap.lock')
content = request.get_json(silent=True)
valid = validator.validate_request(content)
if valid is not None:
os.remove('nmap.lock')
return valid
fn = 'nmap_{0}.xml'.format(''.join(random.choice(string.ascii_letters) for i in range(8)))
command = "nmap "
if 'host' in content:
command += content['host']
else:
command += content['cidr']
command += ' -p '
if 'start_port' in content and 'end_port' in content:
command += '{0}-{1}'.format(content['start_port'], content['end_port'])
else:
command += ','.join([str(i) for i in content['ports']])
command += ' -oX {0} -T3 -Pn'.format(fn)
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
process.wait()
results = open(fn, 'r').read()
os.remove(fn)
if results != '':
try:
os.remove('nmap.lock')
return (jsonify(parser.parse_nmap_results(xmltodict.parse(results))))
except:
os.remove('nmap.lock')
return (jsonify({'error': "bad_results_json"}))
else:
os.remove('nmap.lock')
return jsonify({})
except Exception as e:
os.remove('nmap.lock')
return jsonify({"error":e})
@app.route('/status', methods=['GET'])
def get_status(self):
return jsonify({'masscan': True, 'nmap': True})
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')