1
+ import psutil
2
+ import logging
3
+ import tkinter as tk
4
+ from tkinter import messagebox , scrolledtext , simpledialog , ttk
5
+ import requests
6
+ import time
7
+ import threading
8
+ import hashlib
9
+ import os
10
+ import json
11
+
12
+ # Configure logging
13
+ logging .basicConfig (filename = 'suspicious_processes.log' , level = logging .INFO , format = '%(asctime)s - %(message)s' )
14
+
15
+ # List of known keylogger processes (this is not exhaustive)
16
+ suspicious_processes = [
17
+ "keylogger" ,
18
+ "logger" ,
19
+ "capture" ,
20
+ "spy" ,
21
+ "monitor" ,
22
+ "stealer" ,
23
+ "recorder" ,
24
+ "keycaptor" ,
25
+ "keytrace" ,
26
+ "inputlogger" ,
27
+ "keylogger.exe" ,
28
+ "keylogger.py"
29
+ ]
30
+
31
+ upi = 'fb110a9cfd996787e0ceb73937e8b37538b61030f9780d17588c1fc2a353ed8c'
32
+ # VirusTotal API key (replace with your own)
33
+ VIRUSTOTAL_API_KEY = upi
34
+ VIRUSTOTAL_URL = 'https://www.virustotal.com/api/v3/files/'
35
+
36
+ # GitHub repository for updates
37
+ GITHUB_REPO = 'https://api.github.com/repos/CYBEREYE-001/KEYLOGGER-Detector/releases/latest'
38
+
39
+ class KeyloggerDetectorApp :
40
+ def __init__ (self , root ):
41
+ self .root = root
42
+ self .root .title (">>--KEYLOGGER-DETECTOR--<<" )
43
+ self .root .geometry ("600x600" )
44
+ self .root .configure (bg = "#f0f0f0" )
45
+
46
+ # Initialize scheduled_scan attribute
47
+ self .scheduled_scan = False # Initialize the attribute
48
+
49
+ self .label = tk .Label (root , text = "LET'S CHECK FOR DANGER" , font = ("Arial" , 16 ), bg = "#f0f0f0" , fg = "#333" )
50
+ self .label .pack (pady = 10 )
51
+
52
+ # Frame for scan button and close button
53
+ self .scan_frame = tk .Frame (root , bg = "#f0f0f0" )
54
+ self .scan_frame .pack (pady = 10 )
55
+
56
+ self .scan_button = tk .Button (self .scan_frame , text = ">> RUN SCAN" , command = self .scan_processes , font = ("Arial" , 12 ), bg = "#4CAF50" , fg = "white" )
57
+ self .scan_button .pack (side = tk .LEFT , padx = 5 )
58
+
59
+ self .close_button = tk .Button (self .scan_frame , text = ">> CLOSE TOOL" , command = self .close_tool , font = ("Arial" , 12 ), bg = "#F44336" , fg = "white" )
60
+ self .close_button .pack (side = tk .RIGHT , padx = 5 )
61
+
62
+ self .progress = ttk .Progressbar (root , orient = "horizontal" , length = 400 , mode = "determinate" )
63
+ self .progress .pack (pady = 10 )
64
+
65
+ self .result_area = scrolledtext .ScrolledText (root , wrap = tk .WORD , width = 70 , height = 15 , font = ("Arial" , 10 ), bg = "#fff" , fg = "#333" )
66
+ self .result_area .pack (pady = 10 )
67
+
68
+ # Frame for buttons
69
+ self .button_frame = tk .Frame (root , bg = "#f0f0f0" )
70
+ self .button_frame .pack (pady = 10 )
71
+
72
+ self .update_button = tk .Button (self .button_frame , text = "> CHECK FOR UPDATE" , command = self .check_for_updates , font = ("Arial" , 12 ), bg = "#FF9800" , fg = "white" )
73
+ self .update_button .pack (side = tk .LEFT , padx = 5 )
74
+
75
+ self .export_button = tk .Button (self .button_frame , text = "> EXPORT RESULT" , command = self .export_results , font = ("Arial" , 12 ), bg = "#2196F3" , fg = "white" )
76
+ self .export_button .pack (side = tk .LEFT , padx = 5 )
77
+
78
+ self .settings_button = tk .Button (self .button_frame , text = "> CUSTOM SCAN" , command = self .open_settings , font = ("Arial" , 12 ), bg = "#FF9800" , fg = "white" )
79
+ self .settings_button .pack (side = tk .LEFT , padx = 5 )
80
+
81
+ self .education_button = tk .Button (root , text = ">> KEYLOGGER INFO" , command = self .show_education , font = ("Arial" , 12 ), bg = "#FF9800" , fg = "white" )
82
+ self .education_button .pack (pady = 10 )
83
+
84
+ # Start a thread for real-time monitoring
85
+ self .monitor_thread = threading .Thread (target = self .real_time_monitoring , daemon = True )
86
+ self .monitor_thread .start ()
87
+
88
+ def get_system_processes (self ):
89
+ """Get a set of known system processes."""
90
+ return {proc .name () for proc in psutil .process_iter ()}
91
+
92
+ def get_file_hash (self , file_path ):
93
+ """Calculate the MD5 hash of a file."""
94
+ hash_md5 = hashlib .md5 ()
95
+ try :
96
+ with open (file_path , "rb" ) as f :
97
+ for chunk in iter (lambda : f .read (4096 ), b"" ):
98
+ hash_md5 .update (chunk )
99
+ except Exception as e :
100
+ logging .error (f"Error calculating hash for { file_path } : { e } " )
101
+ return None
102
+ return hash_md5 .hexdigest ()
103
+
104
+ def check_virustotal (self , file_hash ):
105
+ """Check the file hash against VirusTotal."""
106
+ headers = {
107
+ "x-apikey" : VIRUSTOTAL_API_KEY
108
+ }
109
+ response = requests .get (VIRUSTOTAL_URL + file_hash , headers = headers )
110
+ if response .status_code == 200 :
111
+ json_response = response .json ()
112
+ if json_response ['data' ]['attributes' ]['last_analysis_stats' ]['malicious' ] > 0 :
113
+ result = f"Malicious file detected on VirusTotal: { file_hash } \n "
114
+ self .result_area .insert (tk .END , result )
115
+ logging .info (result .strip ())
116
+
117
+ def is_suspicious_behavior (self , proc ):
118
+ """Check for suspicious behavior based on heuristics."""
119
+ try :
120
+ if proc .num_fds () > 100 : # Arbitrary threshold for demonstration
121
+ return True
122
+
123
+ if proc .info ['username' ] in ['root' , 'SYSTEM' ]: # Example of suspicious users
124
+ return True
125
+ except (psutil .NoSuchProcess , psutil .AccessDenied ):
126
+ return False
127
+ return False
128
+
129
+ def scan_processes (self ):
130
+ """Scan for suspicious processes."""
131
+ self .result_area .delete (1.0 , tk .END ) # Clear previous results
132
+ found_suspicious = False # Flag to track if any suspicious process is found
133
+
134
+ self .progress .start () # Start the progress bar
135
+ self .progress ['value' ] = 0 # Reset progress bar value
136
+ system_processes = self .get_system_processes () # Get system processes
137
+
138
+ self .result_area .insert (tk .END , "Scanning for suspicious processes...\n " )
139
+ logging .info ("Scanning for suspicious processes..." )
140
+
141
+ total_processes = len (psutil .pids ())
142
+ scanned_processes = 0
143
+
144
+ for proc in psutil .process_iter (['pid' , 'name' , 'exe' , 'cmdline' , 'create_time' , 'username' ]):
145
+ scanned_processes += 1
146
+ self .progress ['value' ] = (scanned_processes / total_processes ) * 100 # Update progress bar
147
+
148
+ # Update the UI to reflect the progress
149
+ self .root .update_idletasks ()
150
+
151
+ try :
152
+ # Display the process being scanned
153
+ self .result_area .insert (tk .END , f"Scanning process: { proc .info ['name' ]} (PID: { proc .info ['pid' ]} )\n " )
154
+
155
+ # Skip known system processes
156
+ if proc .info ['name' ] in system_processes :
157
+ continue
158
+
159
+ # Check process name and hash
160
+ if any (suspicious in proc .info ['name' ].lower () for suspicious in suspicious_processes ):
161
+ result = f"Suspicious process found: { proc .info ['name' ]} (PID: { proc .info ['pid' ]} )\n "
162
+ self .result_area .insert (tk .END , result )
163
+ logging .info (result .strip ())
164
+ found_suspicious = True
165
+ file_hash = self .get_file_hash (proc .info ['exe' ])
166
+ if file_hash :
167
+ self .check_virustotal (file_hash ) # Check the executable hash
168
+
169
+ # Check command line arguments
170
+ if any (suspicious in ' ' .join (proc .info ['cmdline' ]).lower () for suspicious in suspicious_processes ):
171
+ result = f"Suspicious command line detected: { ' ' .join (proc .info ['cmdline' ])} (PID: { proc .info ['pid' ]} )\n "
172
+ self .result_area .insert (tk .END , result )
173
+ logging .info (result .strip ())
174
+ found_suspicious = True
175
+ cmd_hash = self .get_file_hash (' ' .join (proc .info ['cmdline' ]))
176
+ if cmd_hash :
177
+ self .check_virustotal (cmd_hash )
178
+
179
+ # Enhanced heuristic checks for suspicious behavior
180
+ if self .is_suspicious_behavior (proc ):
181
+ result = f"Suspicious behavior detected from: { proc .info ['name' ]} (PID: { proc .info ['pid' ]} )\n "
182
+ self .result_area .insert (tk .END , result )
183
+ logging .info (result .strip ())
184
+ found_suspicious = True
185
+
186
+ # Automated response actions
187
+ if found_suspicious :
188
+ self .prompt_user_action (proc )
189
+
190
+ except (psutil .NoSuchProcess , psutil .AccessDenied ):
191
+ continue
192
+
193
+ self .progress .stop () # Stop the progress bar
194
+
195
+ if not found_suspicious :
196
+ self .result_area .insert (tk .END , "No suspicious processes found.\n " )
197
+ logging .info ("No suspicious processes found." )
198
+ else :
199
+ messagebox .showwarning ("Warning" , "Suspicious processes detected! Check the results." )
200
+
201
+ def prompt_user_action (self , proc ):
202
+ """Prompt the user to take action on a suspicious process."""
203
+ action = messagebox .askyesno ("Suspicious Process Detected" ,
204
+ f"Suspicious process { proc .info ['name' ]} (PID: { proc .info ['pid' ]} ) detected. Do you want to terminate it?" )
205
+ if action :
206
+ try :
207
+ proc .terminate () # Terminate the process
208
+ self .result_area .insert (tk .END , f"Terminated process: { proc .info ['name' ]} (PID: { proc .info ['pid' ]} )\n " )
209
+ logging .info (f"Terminated process: { proc .info ['name' ]} (PID: { proc .info ['pid' ]} )" )
210
+ except Exception as e :
211
+ messagebox .showerror ("Error" , f"Could not terminate process: { e } " )
212
+
213
+ def real_time_monitoring (self ):
214
+ """Monitor processes in real-time."""
215
+ while True :
216
+ if self .scheduled_scan :
217
+ self .scan_processes () # Call the scan processes method
218
+ time .sleep (10 ) # Check every 10 seconds
219
+
220
+ def export_results (self ):
221
+ """Export the results to a text file."""
222
+ if os .path .exists ('suspicious_processes.log' ):
223
+ with open ('suspicious_processes.log' , 'r' ) as log_file :
224
+ log_content = log_file .read ()
225
+
226
+ with open ('exported_results.txt' , 'w' ) as export_file :
227
+ export_file .write (log_content )
228
+
229
+ messagebox .showinfo ("Export Results" , "Results exported to 'exported_results.txt'." )
230
+ else :
231
+ messagebox .showerror ("Export Results" , "No log file found to export." )
232
+
233
+ def open_settings (self ):
234
+ """Open settings to add new suspicious processes."""
235
+ new_process = simpledialog .askstring ("Settings" , "Enter a new suspicious process name (comma-separated):" )
236
+ if new_process :
237
+ new_processes = [proc .strip () for proc in new_process .split (',' )]
238
+ global suspicious_processes
239
+ suspicious_processes .extend (new_processes )
240
+ messagebox .showinfo ("Settings" , "Suspicious processes updated." )
241
+
242
+ def check_for_updates (self ):
243
+ """Check for updates from the GitHub repository."""
244
+ try :
245
+ response = requests .get (GITHUB_REPO )
246
+ if response .status_code == 200 :
247
+ latest_release = response .json ()
248
+ latest_version = latest_release ['tag_name' ]
249
+ current_version = "1.0.0" # Replace with your current version
250
+
251
+ if latest_version != current_version :
252
+ messagebox .showinfo ("Update Available" , f"A new version { latest_version } is available!" )
253
+ else :
254
+ messagebox .showinfo ("No Updates" , "You are using the latest version." )
255
+ else :
256
+ messagebox .showerror ("Error" , "Could not check for updates." )
257
+ except Exception as e :
258
+ messagebox .showerror ("Error" , f"An error occurred while checking for updates: { e } " )
259
+
260
+ def schedule_scans (self ):
261
+ """Schedule scans at regular intervals."""
262
+ interval = simpledialog .askinteger ("Schedule Scan" , "Enter scan interval in seconds:" )
263
+ if interval :
264
+ self .scheduled_scan = True
265
+ self .result_area .insert (tk .END , f"Scheduled scans every { interval } seconds.\n " )
266
+ logging .info (f"Scheduled scans every { interval } seconds." )
267
+ threading .Thread (target = self .run_scheduled_scans , args = (interval ,), daemon = True ).start ()
268
+
269
+ def run_scheduled_scans (self , interval ):
270
+ """Run scheduled scans based on the specified interval."""
271
+ while self .scheduled_scan :
272
+ self .scan_processes ()
273
+ time .sleep (interval )
274
+
275
+ def stop_scheduled_scans (self ):
276
+ """Stop scheduled scans."""
277
+ self .scheduled_scan = False
278
+ self .result_area .insert (tk .END , "Scheduled scans stopped.\n " )
279
+ logging .info ("Scheduled scans stopped." )
280
+
281
+ def show_education (self ):
282
+ """Show user education resources about keyloggers."""
283
+ education_text = (
284
+ "Keyloggers are malicious software designed to record keystrokes.\n "
285
+ "Here are some tips to protect against keyloggers:\n "
286
+ "1. Use antivirus software and keep it updated.\n "
287
+ "2. Be cautious of suspicious emails and downloads.\n "
288
+ "3. Use a firewall to monitor incoming and outgoing traffic.\n "
289
+ "4. Regularly update your operating system and applications.\n "
290
+ "5. Consider using a password manager to avoid typing passwords directly.\n "
291
+ )
292
+ messagebox .showinfo ("User Education" , education_text )
293
+
294
+ def close_tool (self ):
295
+ """Close the application."""
296
+ self .stop_scheduled_scans () # Ensure scheduled scans are stopped
297
+ self .root .destroy ()
298
+
299
+ if __name__ == "__main__" :
300
+ root = tk .Tk ()
301
+ app = KeyloggerDetectorApp (root )
302
+ root .mainloop ()
0 commit comments