rkihacker commited on
Commit
49d98a7
·
verified ·
1 Parent(s): 6fd2d7f

Create main.py

Browse files
Files changed (1) hide show
  1. main.py +194 -0
main.py ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import socket
2
+ from queue import Queue
3
+ import threading
4
+ from flask import Flask, render_template_string, request
5
+ import time
6
+
7
+ # --- HTML Templates ---
8
+ # For simplicity, we embed the HTML directly in the Python file.
9
+
10
+ HTML_FORM = """
11
+ <!DOCTYPE html>
12
+ <html lang="en">
13
+ <head>
14
+ <meta charset="UTF-8">
15
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
16
+ <title>High-Speed Port Scanner</title>
17
+ <style>
18
+ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; background-color: #121212; color: #e0e0e0; margin: 0; padding: 2em; display: flex; justify-content: center; align-items: center; min-height: 100vh; }
19
+ .container { background-color: #1e1e1e; padding: 2em; border-radius: 8px; box-shadow: 0 4px 15px rgba(0,0,0,0.5); width: 100%; max-width: 600px; }
20
+ h1 { color: #00bcd4; text-align: center; }
21
+ form { display: flex; flex-direction: column; gap: 1em; }
22
+ label { font-weight: bold; }
23
+ input[type="text"], input[type="number"] { padding: 0.8em; border-radius: 4px; border: 1px solid #444; background-color: #2c2c2c; color: #e0e0e0; font-size: 1em; }
24
+ button { padding: 1em; border-radius: 4px; border: none; background-color: #00bcd4; color: #121212; font-size: 1em; font-weight: bold; cursor: pointer; transition: background-color 0.3s; }
25
+ button:hover { background-color: #0097a7; }
26
+ .disclaimer { font-size: 0.8em; color: #ffeb3b; text-align: center; margin-top: 1.5em; border: 1px dashed #ffeb3b; padding: 0.5em; border-radius: 4px; }
27
+ </style>
28
+ </head>
29
+ <body>
30
+ <div class="container">
31
+ <h1>High-Speed Port Scanner</h1>
32
+ <form action="/scan" method="post">
33
+ <label for="target">Target IP Address or Hostname:</label>
34
+ <input type="text" id="target" name="target" value="127.0.0.1" required>
35
+
36
+ <label for="start_port">Start Port:</label>
37
+ <input type="number" id="start_port" name="start_port" value="1" min="1" max="65535" required>
38
+
39
+ <label for="end_port">End Port:</label>
40
+ <input type="number" id="end_port" name="end_port" value="1024" min="1" max="65535" required>
41
+
42
+ <label for="threads">Number of Threads (Concurrency):</label>
43
+ <input type="number" id="threads" name="threads" value="200" min="1" max="1000" required>
44
+
45
+ <button type="submit">Start Scan</button>
46
+ </form>
47
+ <div class="disclaimer">
48
+ <strong>Warning:</strong> Use only on networks you own or have explicit permission to scan. Unauthorized scanning is illegal.
49
+ </div>
50
+ </div>
51
+ </body>
52
+ </html>
53
+ """
54
+
55
+ HTML_RESULTS = """
56
+ <!DOCTYPE html>
57
+ <html lang="en">
58
+ <head>
59
+ <meta charset="UTF-8">
60
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
61
+ <title>Scan Results</title>
62
+ <style>
63
+ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; background-color: #121212; color: #e0e0e0; margin: 0; padding: 2em; }
64
+ .container { background-color: #1e1e1e; padding: 2em; border-radius: 8px; box-shadow: 0 4px 15px rgba(0,0,0,0.5); max-width: 800px; margin: auto; }
65
+ h1 { color: #00bcd4; }
66
+ h2 { border-bottom: 2px solid #00bcd4; padding-bottom: 0.3em; }
67
+ p { font-size: 1.1em; }
68
+ .results-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2em; }
69
+ ul { list-style-type: none; padding: 0; }
70
+ li { background-color: #2c2c2c; margin-bottom: 0.5em; padding: 0.5em; border-radius: 4px; }
71
+ .open { color: #4caf50; font-weight: bold; }
72
+ .closed { color: #f44336; }
73
+ a { color: #00bcd4; text-decoration: none; display: inline-block; margin-top: 1.5em; }
74
+ a:hover { text-decoration: underline; }
75
+ </style>
76
+ </head>
77
+ <body>
78
+ <div class="container">
79
+ <h1>Scan Results</h1>
80
+ <p><strong>Target:</strong> {{ target }}</p>
81
+ <p><strong>Port Range:</strong> {{ start_port }} - {{ end_port }}</p>
82
+ <p><strong>Time Taken:</strong> {{ duration | round(2) }} seconds</p>
83
+
84
+ <div class="results-grid">
85
+ <div>
86
+ <h2>Open Ports ({{ open_ports | length }})</h2>
87
+ <ul>
88
+ {% for port in open_ports %}
89
+ <li class="open">{{ port }}</li>
90
+ {% else %}
91
+ <li>No open ports found.</li>
92
+ {% endfor %}
93
+ </ul>
94
+ </div>
95
+ </div>
96
+ <a href="/">Scan Another Target</a>
97
+ </div>
98
+ </body>
99
+ </html>
100
+ """
101
+
102
+ # --- Scanner Logic ---
103
+ q = Queue()
104
+ open_ports = []
105
+ thread_lock = threading.Lock()
106
+
107
+ def scan_port(target):
108
+ """Worker function for threads. Scans a single port."""
109
+ while not q.empty():
110
+ port = q.get()
111
+ # Create a new socket for each thread
112
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
113
+ # Set a short timeout to speed up scanning
114
+ s.settimeout(0.5)
115
+ try:
116
+ # connect_ex returns 0 if connection succeeds, otherwise an error code
117
+ conn_status = s.connect_ex((target, port))
118
+ if conn_status == 0:
119
+ with thread_lock:
120
+ open_ports.append(port)
121
+ except (socket.timeout, ConnectionRefusedError):
122
+ pass
123
+ finally:
124
+ s.close()
125
+ q.task_done()
126
+
127
+ def run_scanner(target, start_port, end_port, num_threads):
128
+ """Main function to set up and run the scan."""
129
+ global open_ports
130
+ open_ports = [] # Reset for each scan
131
+
132
+ # Populate the queue with ports to scan
133
+ for port in range(start_port, end_port + 1):
134
+ q.put(port)
135
+
136
+ # Create and start threads
137
+ threads = []
138
+ for _ in range(num_threads):
139
+ thread = threading.Thread(target=scan_port, args=(target,), daemon=True)
140
+ thread.start()
141
+ threads.append(thread)
142
+
143
+ # Wait for the queue to be empty (all ports scanned)
144
+ q.join()
145
+
146
+ open_ports.sort()
147
+ return open_ports
148
+
149
+ # --- Flask Web App ---
150
+ app = Flask(__name__)
151
+
152
+ @app.route('/')
153
+ def index():
154
+ return render_template_string(HTML_FORM)
155
+
156
+ @app.route('/scan', methods=['POST'])
157
+ def scan():
158
+ try:
159
+ target = request.form['target']
160
+ start_port = int(request.form['start_port'])
161
+ end_port = int(request.form['end_port'])
162
+ threads = int(request.form['threads'])
163
+
164
+ # Basic input validation
165
+ if start_port > end_port or start_port < 1 or end_port > 65535:
166
+ return "Invalid port range.", 400
167
+ if threads < 1 or threads > 1000:
168
+ return "Thread count must be between 1 and 1000.", 400
169
+
170
+ # Resolve hostname to IP address once
171
+ try:
172
+ target_ip = socket.gethostbyname(target)
173
+ except socket.gaierror:
174
+ return f"Error: Could not resolve hostname '{target}'", 400
175
+
176
+ start_time = time.time()
177
+ found_open_ports = run_scanner(target_ip, start_port, end_port, threads)
178
+ duration = time.time() - start_time
179
+
180
+ return render_template_string(
181
+ HTML_RESULTS,
182
+ target=f"{target} ({target_ip})",
183
+ start_port=start_port,
184
+ end_port=end_port,
185
+ open_ports=found_open_ports,
186
+ duration=duration
187
+ )
188
+
189
+ except (ValueError, KeyError) as e:
190
+ return f"Invalid form data submitted: {e}", 400
191
+
192
+ if __name__ == '__main__':
193
+ # Listen on 0.0.0.0 to be accessible from outside the Docker container
194
+ app.run(host='0.0.0.0', port=5000)