-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
155 lines (135 loc) · 5.12 KB
/
app.py
File metadata and controls
155 lines (135 loc) · 5.12 KB
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
from flask import Flask, render_template, redirect, url_for, request, session, flash, jsonify
from functools import wraps
from flask_pymongo import PyMongo
from bson.objectid import ObjectId
import subprocess
import re
import json
import threading
import socket
import random
app = Flask(__name__)
app.secret_key = 'supersecretkey'
# Configuração do MongoDB
app.config["MONGO_URI"] = "mongodb://mongodb:27017/mydatabase"
mongo = PyMongo(app)
# Dummy user data
users = {
"fernando": "123456"
}
def login_required(f):
@wraps(f)
def wrap(*args, **kwargs):
if 'logged_in' in session:
return f(*args, **kwargs)
else:
flash('You need to login first.')
return redirect(url_for('login'))
return wrap
@app.route('/')
@login_required
def home():
targets = mongo.db.targets.find()
return render_template('dashboard.html', targets=targets)
@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if username in users and users[username] == password:
session['logged_in'] = True
flash('You were logged in.')
return redirect(url_for('home'))
else:
error = 'Invalid Credentials. Please try again.'
return render_template('login.html', error=error)
@app.route('/logout')
@login_required
def logout():
session.pop('logged_in', None)
flash('You were logged out.')
return redirect(url_for('login'))
@app.route('/add_target', methods=['POST'])
@login_required
def add_target():
target = request.form.get('target')
action = request.form.get('action')
if action == 'network_scan':
thread = threading.Thread(target=run_network_scan, args=(target,))
thread.start()
elif action == 'detailed_scan':
thread = threading.Thread(target=run_detailed_scan, args=(target,))
thread.start()
mongo.db.targets.insert_one({'target': target, 'action': action, 'result': None})
return redirect(url_for('home'))
@app.route('/scan_result/<id>', methods=['GET'])
@login_required
def get_scan_result(id):
target = mongo.db.targets.find_one_or_404({'_id': ObjectId(id)})
return jsonify(target)
@app.route('/last_scan', methods=['GET'])
@login_required
def get_last_scan():
last_scan = mongo.db.targets.find().sort('_id', -1).limit(1)
return jsonify({'scan_id': str(last_scan['_id'])})
@app.route('/scan_status/<id>', methods=['GET'])
@login_required
def get_scan_status(id):
target = mongo.db.targets.find_one_or_404({'_id': ObjectId(id)})
status = 'completed' if target['result'] is not None else 'pending'
return jsonify({'status': status})
def run_network_scan(target):
result = subprocess.run(['nmap', '-sn', target], capture_output=True, text=True).stdout
parsed_result = parse_nmap_output(result)
mongo.db.targets.update_one({'target': target}, {'$set': {'result': parsed_result}})
def run_detailed_scan(target):
result = subprocess.run(['nmap','-T4', '-A', target], capture_output=True, text=True).stdout
parsed_result = parse_detailed_nmap_output(result)
mongo.db.targets.update_one({'target': target}, {'$set': {'result': parsed_result}})
def parse_nmap_output(output):
# Parse the nmap output to extract relevant information
# This is a simplified example, adjust it to match your nmap output
devices = []
for line in output.split('\n'):
match = re.search(r'(\d+\.\d+\.\d+\.\d+)', line)
if match:
devices.append({'ip': match.group(1), 'os': 'Unknown'})
return devices
def parse_detailed_nmap_output(output):
# Parse the detailed nmap output to extract relevant information
# This is a simplified example, adjust it to match your nmap output
devices = []
current_device = {}
for line in output.split('\n'):
ip_match = re.search(r'Nmap scan report for (.+)', line)
port_match = re.search(r'(\d+/tcp)\s+(\w+)\s+(\w+)', line)
mac_match = re.search(r'MAC Address: ([0-9A-F:]+)', line)
if ip_match:
if current_device:
devices.append(current_device)
current_device = {'ip': ip_match.group(1), 'ports': [], 'mac': 'Unknown', 'os': 'Unknown'}
elif port_match:
current_device['ports'].append({'port': port_match.group(1), 'state': port_match.group(2), 'service': port_match.group(3)})
elif mac_match:
current_device['mac'] = mac_match.group(1)
if current_device:
devices.append(current_device)
return devices
def find_free_port():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 0))
s.listen(1)
port = s.getsockname()[1]
s.close()
return port
if __name__ == '__main__':
port = 5000
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex(('0.0.0.0', port))
if result == 0:
port = find_free_port()
print(f"Porta 5000 está em uso, usando a porta {port} em vez disso.")
else:
print(f"Usando a porta {port}")
app.run(host='0.0.0.0', port=port)