source: final_client.py@ 2058e5c

Last change on this file since 2058e5c was 640ed89, checked in by istevanoska <ilinastevanoska@…>, 7 months ago

Initial commit

  • Property mode set to 100644
File size: 12.4 KB
Line 
1#!/usr/bin/env python3
2"""
3FINAL SYSMON CLIENT - Sends data in correct format
4"""
5
6import socket
7import os
8import platform
9import json
10import requests
11from datetime import datetime
12import psutil
13import time
14import re
15
16
17class FinalSysmonClient:
18 def __init__(self, server_ip="192.168.1.13", port=5555):
19 self.server_ip = server_ip
20 self.port = port
21 self.computer_name = socket.gethostname()
22 self.user = os.getlogin()
23
24 def check_sysmon_installed(self):
25 """Proveri dali Sysmon e instaliran"""
26 try:
27 import win32evtlog
28 hand = win32evtlog.OpenEventLog("localhost", "Microsoft-Windows-Sysmon/Operational")
29 win32evtlog.CloseEventLog(hand)
30 return True
31 except:
32 return False
33
34 def get_system_info(self):
35 """Sobiraј system info"""
36 try:
37 ip_address = "N/A"
38 try:
39 ip_address = socket.gethostbyname(self.computer_name)
40 except:
41 pass
42
43 return {
44 "computer_name": self.computer_name,
45 "user": self.user,
46 "ip_address": ip_address,
47 "os": f"{platform.system()} {platform.release()}",
48 "cpu_usage": psutil.cpu_percent(interval=1),
49 "ram_usage": psutil.virtual_memory().percent,
50 "disk_usage": psutil.disk_usage("C:/").percent if os.name == 'nt' else 0,
51 "collection_time": datetime.now().isoformat()
52 }
53 except Exception as e:
54 return {"error": str(e)}
55
56 def get_running_processes(self):
57 """Sobiraј procesi"""
58 processes = []
59 try:
60 for proc in psutil.process_iter(['pid', 'name', 'username']):
61 try:
62 processes.append({
63 "pid": proc.info['pid'],
64 "name": proc.info['name'],
65 "user": proc.info['username'] or "N/A",
66 "cpu_percent": round(proc.cpu_percent(), 2),
67 "memory_mb": round(proc.memory_info().rss / (1024 ** 2), 2),
68 "cmdline": ' '.join(proc.cmdline())[:200] if proc.cmdline() else ""
69 })
70 except:
71 continue
72
73 if len(processes) >= 20:
74 break
75 except:
76 pass
77 return processes
78
79 def collect_sysmon_events(self, max_events=30):
80 """Sobiraј Sysmon eventi vo pravilen format"""
81 events = []
82
83 if not self.check_sysmon_installed():
84 return events
85
86 try:
87 import win32evtlog
88
89 hand = win32evtlog.OpenEventLog("localhost", "Microsoft-Windows-Sysmon/Operational")
90 flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
91
92 events_collected = 0
93
94 while events_collected < max_events:
95 events_batch = win32evtlog.ReadEventLog(hand, flags, 0)
96 if not events_batch:
97 break
98
99 for event in events_batch:
100 try:
101 event_id = event.EventID
102
103 # Parse event data
104 event_data = {}
105 if event.StringInserts:
106 xml_content = ' '.join([str(s) for s in event.StringInserts])
107 event_data = self.parse_event_xml(xml_content)
108
109 # Create event object
110 event_obj = {
111 "event_id": event_id,
112 "event_type": self.get_event_type(event_id),
113 "timestamp": event.TimeGenerated.Format() if hasattr(event.TimeGenerated,
114 'Format') else str(
115 event.TimeGenerated),
116 "computer": self.computer_name,
117 "data": event_data # OVA E NAJVAZHNO - cela event data
118 }
119
120 events.append(event_obj)
121 events_collected += 1
122
123 if events_collected >= max_events:
124 break
125
126 except Exception as e:
127 continue
128
129 win32evtlog.CloseEventLog(hand)
130
131 except Exception as e:
132 print(f" ⚠️ Greshka pri Sysmon: {e}")
133
134 return events
135
136 def parse_event_xml(self, xml_content):
137 """Parse Sysmon event XML"""
138 data = {}
139
140 # Extract all <Data Name="...">...</Data> pairs
141 pattern = r'<Data Name="([^"]+)"[^>]*>([^<]+)</Data>'
142 matches = re.findall(pattern, xml_content)
143
144 for name, value in matches:
145 data[name] = value.strip()
146
147 return data
148
149 def get_event_type(self, event_id):
150 """Get event type name"""
151 event_types = {
152 1: "Process Creation",
153 2: "File creation time changed",
154 3: "Network Connection",
155 4: "Sysmon service state changed",
156 5: "Process Terminated",
157 6: "Driver Loaded",
158 7: "Image Loaded (DLL)",
159 8: "CreateRemoteThread",
160 10: "Process Access",
161 11: "File Create",
162 12: "Registry Object added/deleted",
163 13: "Registry Value Set",
164 14: "Registry Object Renamed",
165 15: "File Create Stream Hash",
166 17: "Pipe Created",
167 18: "Pipe Connected",
168 19: "WmiEventFilter activity detected",
169 20: "WmiEventConsumer activity detected",
170 21: "WmiConsumerToFilter activity detected",
171 22: "DNS Query",
172 23: "File Delete",
173 24: "Clipboard Changed",
174 25: "Process Tampering",
175 26: "File Delete Detected"
176 }
177 return event_types.get(event_id, f"Event {event_id}")
178
179 def collect_and_send(self):
180 """Sobiraј i ispraќaj podatoci vo PRAVILEN format"""
181 print(f"\n[{datetime.now().strftime('%H:%M:%S')}] 🔍 Sobiranje podatoci...")
182
183 try:
184 sysmon_installed = self.check_sysmon_installed()
185 print(f" 🔍 Sysmon: {'✅ Instaliran' if sysmon_installed else '❌ Ne e instaliran'}")
186
187 # Sobiraј podatoci
188 print(f" 📥 Sobiranje Sysmon eventi...")
189 sysmon_events = self.collect_sysmon_events(max_events=20)
190
191 print(f" 📥 Sobiranje system info...")
192 system_info = self.get_system_info()
193
194 print(f" 📥 Sobiranje procesi...")
195 processes = self.get_running_processes()
196
197 # KREIRAJ GO TOCHNIOT FORMAT ZA SERVEROT
198 data = {
199 "metadata": {
200 "computer": self.computer_name,
201 "user": self.user,
202 "collection_time": datetime.now().isoformat(),
203 "sysmon_installed": sysmon_installed
204 },
205 "system_info": system_info,
206 "sysmon_events": sysmon_events, # OVA E KLUCHNO - sysmon_events
207 "processes": processes
208 }
209
210 # Prikaži statistika
211 print(f"\n 📊 STATISTIKA:")
212 print(f" • Sysmon eventi: {len(sysmon_events)}")
213 print(f" • Procesi: {len(processes)}")
214
215 # Prikaži primerok od eventite
216 if sysmon_events:
217 print(f"\n 📋 PRIMEROK OD EVENTI:")
218 for i, event in enumerate(sysmon_events[:3], 1):
219 event_id = event["event_id"]
220 event_data = event["data"]
221
222 if event_id == 22: # DNS
223 query = event_data.get("QueryName", "")
224 if query:
225 results = event_data.get("QueryResults", "")
226 process = event_data.get("Image", "")
227 print(f" {i}. 🌐 DNS: {query} → {results[:50]}... (Process: {process})")
228
229 elif event_id == 1: # Process
230 process = event_data.get("Image", "")
231 if process:
232 cmd = event_data.get("CommandLine", "")
233 user = event_data.get("User", "")
234 print(f" {i}. 🖥️ Process: {process.split('\\\\')[-1]} | User: {user}")
235
236 elif event_id == 3: # Network
237 dest_ip = event_data.get("DestinationIp", "")
238 if dest_ip:
239 port = event_data.get("DestinationPort", "")
240 process = event_data.get("Image", "")
241 print(
242 f" {i}. 🌐 Network: {process.split('\\\\')[-1] if process else 'Unknown'} → {dest_ip}:{port}")
243
244 # Prati na serverot
245 print(f"\n 📤 Prakanje na serverot...")
246 return self.send_to_server(data)
247
248 except Exception as e:
249 print(f" ❌ Greshka: {e}")
250 import traceback
251 traceback.print_exc()
252 return False
253
254 def send_to_server(self, data):
255 """Prati gi podatocite na serverot"""
256 try:
257 # Proveri dali data e vo pravilen format
258 if "sysmon_events" not in data:
259 print(" ❌ Nema sysmon_events vo podatocite!")
260 return False
261
262 response = requests.post(
263 f"http://{self.server_ip}:{self.port}/receive_data",
264 json=data,
265 timeout=30
266 )
267
268 if response.status_code == 200:
269 result = response.json()
270 print(f" ✅ Uspeshno isprateno!")
271 print(f" 📝 Server: {result.get('message', 'OK')}")
272 print(f" 📊 Eventi vneseni: {result.get('events_inserted', 0)}")
273 return True
274 else:
275 print(f" ❌ Server error: {response.status_code}")
276 print(f" Response: {response.text[:200]}")
277 return False
278
279 except Exception as e:
280 print(f" ❌ Greshka pri prakanje: {e}")
281 return False
282
283
284def main():
285 """Glavna programa"""
286 print("=" * 70)
287 print("🛡️ FINAL SYSMON CLIENT")
288 print("=" * 70)
289 print(f"Computer: {socket.gethostname()}")
290 print(f"User: {os.getlogin()}")
291 print("=" * 70)
292
293 server_ip = input("Enter server IP (default 192.168.1.13): ").strip() or "192.168.1.13"
294
295 client = FinalSysmonClient(server_ip)
296
297 # Test connection
298 print(f"\n🔌 Testiranje na vrska so serverot {server_ip}...")
299 try:
300 response = requests.get(f"http://{server_ip}:5555/ping", timeout=5)
301 if response.status_code == 200:
302 print(" ✅ Serverot e dostapen!")
303 else:
304 print(f" ⚠️ Serverot odgovora so: {response.status_code}")
305 except Exception as e:
306 print(f" ⚠️ Ne moze da se konektira: {e}")
307 confirm = input(" Sakaš li da prodolzhish? (y/n): ").lower()
308 if confirm != 'y':
309 return
310
311 try:
312 count = 1
313 while True:
314 print(f"\n" + "=" * 60)
315 print(f"📤 TRANSMISSION #{count}")
316 print("=" * 60)
317
318 start_time = time.time()
319 success = client.collect_and_send()
320 elapsed = time.time() - start_time
321
322 print(f"\n ⏱️ Vreme: {elapsed:.2f} sekundi")
323
324 count += 1
325
326 if success:
327 wait_time = 60 # 1 minuta
328 else:
329 wait_time = 30 # 30 sekundi na failure
330
331 print(f"\n⏳ Chekam {wait_time} sekundi...")
332 for i in range(wait_time, 0, -1):
333 if i % 10 == 0:
334 print(f"\r Next in: {i // 60:02d}:{i % 60:02d}", end="")
335 time.sleep(1)
336 print("\r" + " " * 30 + "\r", end="")
337
338 except KeyboardInterrupt:
339 print("\n\n🛑 Programata e zaјchana.")
340 print(f"📊 Dashboard: http://{server_ip}:5555/")
341 print("=" * 70)
342
343
344if __name__ == "__main__":
345 try:
346 import psutil
347 import requests
348 except ImportError:
349 print("Instaliraј gi modulite:")
350 print("pip install psutil requests")
351 if os.name == 'nt':
352 print("pip install pywin32")
353 input("Pritisni ENTER za izlez...")
354 exit(1)
355
356 main()
Note: See TracBrowser for help on using the repository browser.