← Back to list

Analysis of BQTLock Ransomware

Summary

Shubho57 in The Malware Files · 2025-10-20 03:58 · 0 claps · 27.8 min read
#ransomware #multi-stage #rat-remcos #threat-hunting #malware-analysis
Open on Medium ↗
Wiki topics: 🔒 · Cybersecurity 🥊 · Combat Sports

Analysis of BQTLock Ransomware

Summary

  1. In this scenario I took 2 samples mostly same in nature which performs a lot of different evasion techniques
  2. Remcos RAT is also being used with this ransomware variant as its stager
  3. The ransomware performs a lot of different types of compression to actually make the actual payload invisible
  4. It also uses OpenSSH SSL for gaining privilege escalation in the system
  5. A lot of different outbound connections are being used, which all are related to the Ransomware and also the C2 panel

Analysis of the Ransomware

Fig 1 — Disk Encryption

Fig 1 — Disk Encryption

This assembly code is part of a BQTLocker ransomware routine that’s checking for and handling disk encryption. Here’s what it’s doing:

  1. Loading information — Gets “INFO” string and RSI register value (likely file/disk info)
  2. Preparing payload address — Loads [rsp+708h+var_348] into RBX (probably a buffer or payload location)
  3. First function call — Calls sub_140001850 with the loaded parameters
  4. Loading payload message — Loads the string “BQTLock Payload started.” along with RBX value
  5. Second function call — Calls the same function again (likely logging or status display)
  6. Block setup — Loads [rsp+708h+var_348] into RCX with "Block" context, then loads [rsp+708h+var_338] into R14
  7. Comparison check — Compares RCX with R14 (probably checking block boundaries or completion status)
  8. Conditional jump — Jumps to loc_140023066 if the values are not equal (short jump if not zero)

This looks like a disk encryption initialization routine that:

  • Announces the payload is starting
  • Sets up memory blocks for encryption operations
  • Implements a loop structure to process data blocks

Fig 2 — Fingerprinting

Fig 2 — Fingerprinting

Figure 1: Version Information Collection

This code is gathering detailed Windows version information:

  • Calls sub_1400022C0 - likely a system info gathering function
  • Loads “INFO” string for logging/status
  • Collects OS version details using SIMD instructions (movdqu with xmm registers):
  • dwOSVersionInfoSize - structure size
  • dwPlatformId - platform identifier
  • szCSDVersion - service pack string (multiple loads)
  • wServicePackMajor/Minor - service pack versions
  • Uses hardcoded addresses like cs:unk_140826100, cs:xmmword_140826110, etc. - these are global storage locations for the gathered data

The xmm registers (xmm0-xmm5) are being used to efficiently copy 16-byte chunks of the OSVERSIONINFO structure.

Figure 2: OS Detection and Block Processing

This continues the flow:

  • More version data copying (xmm operations continue)
  • Calls sub_140001850 (same logging function from the first snippet)
  • Calls sub_140011AB0 - likely the actual OS detection/analysis function
  • Moves result to R8, RDI
  • Loads “Detected OS: “ string to RDX
  • Calls sub_1405CCF20 - probably displays/logs the detected OS
  • Loads “Block” context and compares RCX with R14 — returning to the block processing loop

Fig 3 — Stored victim’s credentials

Fig 3 — Stored victim’s credentials

  1. Load file path — Gets [rsp+708h+var_388] into R12
  2. Prepare file path string — Loads “C:\Windows\Temp\bqt_passwords.txt” into RDX (the target file)
  3. Move path to RCX — Sets up R12 as first parameter
  4. Call logging functionsub_140001850 (likely logs the file access attempt)
  5. Set file access mode — Moves 10h into R8D (this is a file access flag, likely GENERIC_READ or similar)
  6. Load path again — RDX = R12, RCX = RSI (setting up parameters)
  7. Call file operationsub_14059D70 (probably CreateFile or a wrapper to open the file)
  8. Load result — RCX = [rsp+708h+var_1C8] (likely a file handle or result)
  9. Call another functionsub_140507A70 (possibly ReadFile, file processing, or validation)
  10. Test resulttest al, al checks if the operation succeeded (AL typically contains boolean return values)

Purpose: The malware is trying to open and read a password file located at C:\Windows\Temp\bqt_passwords.txt. This could be:

  • A file it created earlier to store credentials
  • A staging file for collected passwords before exfiltration
  • Part of its credential harvesting mechanism

Fig 4 — Failed to save the credentials if AV detects encryption

Fig 4 — Failed to save the credentials if AV detects encryption

The flow is:

  • Try to write passwords → (if failed) → Log “ERROR” → Log “Failed to write passwords” → Jump to cleanup/recovery

This suggests the malware:

  1. Harvests credentials from the system
  2. Attempts to write them to a temporary file
  3. Has error handling for when file write operations fail (possibly due to permissions, disk space, or AV interference)

Fig 5 — JSON payload for C2 exfiltration

Fig 5 — JSON payload for C2 exfiltration

This code is building a JSON configuration structure for the BQTLocker ransomware. Here’s what it’s doing:

  1. Load buffer addresslea r15, [rsp+708h+var_488] (destination buffer)
  2. Start username JSON field:
  • lea rdx, aUsernameBqtloc loads "{ \"username\": \"BQTLock Bot\", \"embe..."
  • mov rcx, r15 sets destination
  • mov [rsp+708h+var_668], r15 saves buffer pointer
  • call sub_140001850 (string operation, likely append/copy)

3. Continue building JSON:

  • mov rdx, [rsp+708h+var_6A0] loads next data
  • mov rcx, rdi
  • call sub_140004E00 (more JSON construction)

4. Add Public IP field:

  • lea rdx, aNamePublicIpVa loads "{ \"name\": \"Public IP\", \"value\": \"..."
  • mov rcx, rbx
  • call sub_1405CCF20 (append to JSON)

5. Add inline flag:

  • lea rdx, aInlineTrue loads "\", \"inline\": true },"
  • call sub_1405AFCA0 (continue building)

6. More JSON assembly:

  • Multiple register moves and function calls
  • call sub_1405B1530
  • mov r8, [rsp+708h+var_210]

Purpose: The malware is constructing a JSON payload for exfiltration or C2 communication that includes:

  • Username: “BQTLock Bot” (identifier for the bot/victim)
  • Public IP: The victim’s external IP address
  • Inline formatting flags: For structured data display

This JSON is being prepared to:

  • Send victim information to a command & control server
  • Post to a webhook (Discord/Telegram) for operator notifications
  • Log the infection details with embedded formatting

Fig 6 — Continuation of the previous C2 infrastructure

Fig 6 — Continuation of the previous C2 infrastructure

This code is continuing to build the JSON structure by adding another field for Local IP address. Here’s the breakdown:

  1. Add Local IP field:
  • lea rdx, aNameLocalIpVal loads "{ \"name\": \"Local IP\", \"value\": \""
  • mov rcx, rbx sets destination
  • call sub_1405CCF20 (appends this JSON field to the structure)

2. Add inline formatting:

  • lea rdx, aInlineTrue loads "\", \"inline\": true },"
  • mov rcx, rbx
  • call sub_1405AFCA0 (appends the inline flag and closes this field)

3. Continue JSON construction:

  • mov rdx, rax
  • mov rcx, rsi
  • call sub_1405B1530 (more JSON assembly/formatting)

Purpose: This extends the previous JSON payload to now include:

  • Username: “BQTLock Bot”
  • Public IP: (victim’s external IP)
  • Local IP: (victim’s internal network IP)
  • Inline formatting for each field

The malware is gathering network reconnaissance data to send to its operators, giving them:

  • External IP (for geolocation/ISP info)
  • Internal IP (for network topology understanding)

Fig 7 — Building the system profile of victim and gaining firm foothold

Fig 7 — Building the system profile of victim and gaining firm foothold

These three images show the malware continuing to build the JSON payload with additional system information fields:

Figure 1: OS Version Field

  • lea rdx, aNameOsVersionV loads "{ \"name\": \"OS Version\", \"value\": "
  • mov rcx, rbx
  • call sub_1405CCF20 (appends OS version field)
  • lea rdx, aInlineFalse loads "\", \"inline\": false },"
  • call sub_1405AFCA0 (closes the field with inline=false)

Figure 2: HWID (Hardware ID) Field

  • lea rdx, aNameHwidValue loads "{ \"name\": \"HWID\", \"value\": \""
  • mov rcx, rbx
  • call sub_1405CCF20 (appends HWID field)
  • lea rdx, aInlineFalse loads "\", \"inline\": false },"
  • call sub_1405AFCA0 (closes the field)

Figure 3: Disk Info Field

  • lea rdx, aNameDiskInfoVa loads "{ \"name\": \"Disk Info\", \"value\": "
  • mov rcx, rbx
  • call sub_1405CCF20 (appends disk info field)
  • lea rdx, aInlineFalse_0 loads "\", \"inline\": false }"

Purpose: The malware is building a comprehensive system profile that includes:

  1. Username & Bot identifier
  2. Public IP
  3. Local IP
  4. OS Version (Windows version details)
  5. HWID (Hardware ID — unique machine identifier)
  6. Disk Info (storage information)

Notice that OS Version, HWID, and Disk Info use **"inline": false while the IP addresses used `"inline": true`. This is Discord/Slack webhook embed formatting** where:

  • inline: true = fields appear side-by-side
  • inline: false = fields appear on their own line

Fig 8 — Password Stealing

Fig 8 — Password Stealing

This code is adding a password stealing field to the JSON payload and closing the JSON structure:

  1. Call functioncall sub_1405AE6B0 (likely finalizes previous field or processes data)
  2. Add Password Stealing field:
  • lea rdx, aNamePasswordSt loads ",{ \"name\": \"Password Stealing\", \"v..."
  • mov rcx, r15 sets destination
  • call sub_1405AFCA0 (appends the password stealing status field)

3. Close JSON array/object:

  • lea rdx, asc_14060E277 loads "] }] }" (closing brackets)
  • mov rcx, r15
  • (Next line likely calls another function to finalize)

Purpose: This is the final field in the JSON payload that reports on the password stealing capability or status. The closing brackets "] }] }" indicate the complete JSON structure is:

{ “embeds”: [ { “fields”: [ {“name”: “username”, “value”: “BQTLock Bot”, “inline”: true}, {“name”: “Public IP”, “value”: “…”, “inline”: true}, {“name”: “Local IP”, “value”: “…”, “inline”: true}, {“name”: “OS Version”, “value”: “…”, “inline”: false}, {“name”: “HWID”, “value”: “…”, “inline”: false}, {“name”: “Disk Info”, “value”: “…”, “inline”: false}, {“name”: “Password Stealing”, “value”: “…”} ] } ] }

This confirms the malware sends a complete victim profile via webhook (likely Discord) including confirmation of whether password theft was successful.

Fig 9 — Configurations for exfiltration methods

Fig 9 — Configurations for exfiltration methods

These two figures show the malware checking configuration for exfiltration methods and handling cases where they’re not set up:

Figure 1: Discord Webhook Check (loc_140023EA0)

  1. Load info messagelea rdx, aInfo loads "INFO"
  2. Set parametersmov rcx, rsi
  3. Log infocall sub_140001850 (logging function)
  4. Load warning messagelea rdx, aDiscordWebhook loads "Discord Webhook URL is not configured."
  5. Set parametersmov rcx, rbx
  6. Log warningcall sub_140001850 (logs the configuration issue)

Figure 2: Telegram Check (loc_140023618)

  1. Load info messagelea rdx, aInfo loads "INFO"
  2. Set parametersmov rcx, rsi
  3. Log infocall sub_140001850
  4. Load warning messagelea rdx, aTelegramIsNotC loads "Telegram is not configured."
  5. Set parametersmov rcx, rbx
  6. Log warningcall sub_140001850

Purpose: The malware has multiple exfiltration channels and checks if they’re configured:

  • Discord Webhook — for sending victim data to Discord
  • Telegram Bot — for sending victim data to Telegram

These are conditional branches that the malware reaches when:

  • The operator hasn’t configured a webhook URL in the malware’s settings
  • The malware is checking which exfiltration methods are available

This shows the malware is flexible and can use either Discord or Telegram (or both) to send stolen data back to the attackers, depending on what’s configured in the build

Fig 10 — Sending infection report via Amin status and trying to send final report

Fig 10 — Sending infection report via Amin status and trying to send final report

These two figures show the malware building an infection report message with system details:

Figure 1: Building the Report Header and IP Information

  1. Start infection report:
  • lea rdx, aInfectionRepor loads "Infection Report:\nPublic IP: "
  • mov rcx, r15 sets destination buffer
  • call sub_140001E10 (starts building the report string)
  1. Add Local IP label:
  • lea rdx, aLocalIp loads "\nLocal IP: "
  • mov rcx, r15
  • mov [rsp+708h+var_6C0], r15 (saves buffer pointer)
  • call sub_1405AFCA0 (appends to report)

2. Process IP data:

  • lea r12, [rsp+708h+var_448] (loads some buffer/data)
  • mov rdx, rax
  • mov rcx, r12
  • call sub_1405B1530 (processes/formats the data)

3. Continue building:

  • mov [rsp+708h+var_688], r12 (saves pointer)
  • mov rdx, r12
  • mov r9, [rsp+708h+var_560] (loads more data)
  • lea r12, [rsp+708h+var_428] (next buffer section)
  • Multiple mov instructions loading data from stack

Figure 2: Adding Admin Status

  1. Load more data:
  • mov r8, [rsp+708h+var_508]
  • mov rcx, rdi
  • lea rdx, [rsp+708h+var_388]

2. Call formatting function:

  • call sub_140001CE0 (processes data)

3. Add admin status:

  • lea rdx, aAdminStatus loads "\nAdmin Status: "
  • mov rcx, rdi
  • call sub_1405AFCA0 (appends admin status to report)

Purpose: The malware is creating a plain text infection report (separate from the JSON webhook payload) that includes:

  • Public IP address
  • Local IP address
  • Admin Status (whether running with administrator privileges)

This text report is likely:

  • Saved to a local log file
  • Sent via a different channel (email, FTP, etc.)
  • Displayed in a console/debug window
  • Used as a simpler alternative to the webhook JSON if webhooks fail

Figure 3: Sending Final Report

  1. Call functioncall sub_140003B20 (likely finalizes the report data or prepares network connection)
  2. Log info message:
  • lea rdx, aInfo loads "INFO"
  • mov rcx, rsi
  • call sub_140001850 (logs the info message)

3. Log sending attempt:

  • lea rdx, aAttemptingToSe loads "Attempting to send final report."
  • mov rcx, rsi
  • call sub_140001850 (logs that it's about to send)

4. Load data for sending:

  • mov r12, 346DC5DC8659D48h (loads what appears to be a hash or magic number - possibly an API hash, encryption key, or identifier)

Purpose: This is the exfiltration stage where:

  • The malware has finished collecting all victim information
  • It logs that it’s attempting to send the final report
  • It loads a critical value (the large hex number 346DC5DC8659D48h) which could be:
  • API hash for dynamic API resolution (common in malware to avoid detection)
  • Encryption key or seed for securing the transmission
  • Authentication token or identifier for the C2 server
  • Network configuration hash

The “Attempting to send final report” message indicates this is the critical exfiltration moment where all stolen data (passwords, system info, IPs, etc.) is about to be transmitted to the attacker’s infrastructure (Discord webhook, Telegram bot, or other C2 channel).

Fig 11 — Exfiltrating victim’s data

Fig 11 — Exfiltrating victim’s data

This code shows the malware taking a screenshot and preparing to exfiltrate it. Here are the two sections:

Left Side: Screenshot File Creation (loc_140024418)

  1. Load screenshot filename:
  • rdx, aScreenshotFile loads "screenshot_file"
  • rcx, rsi
  • call sub_140001850 (logs the action)

Set image format:

  • rdx, aImagePng loads "image/png"
  • rcx, rbx
  • call sub_140001850 (logs PNG format)

Prepare screenshot data:

  • rdx, [rsp+708h+var_678] (loads screenshot buffer/data)
  • r9, rsi and r8, rbx (additional parameters)
  • rcx, qword_140826240 (likely a global buffer or handle)
  • call sub_140011A0 (processes/saves the screenshot)

Right Side: Send Photo Action (loc_140024582)

  1. Load send photo command:
  • lea rdx, aSendphoto loads "sendPhoto"
  • mov rcx, rsi
  • call sub_140001850 (logs the action)

Set photo parameter:

  • lea rdx, aPhoto loads "photo"
  • mov rcx, rbx
  • call sub_140001850 (logs parameter)

Set image format:

  • lea rdx, aImagePng loads "image/png"
  • mov rcx, rdi
  • call sub_140001850 (logs format)

Prepare for transmission:

  • mov [rsp+708h+var_6E0], rsi (saves pointer)
  • mov r8, [rsp+708h+var_678] (loads screenshot data)
  • mov r9, rdi
  • lea rcx, qword_140826200 (loads transmission buffer/handle)

Purpose: The malware is:

  1. Capturing a screenshot of the victim’s desktop
  2. Saving it as PNG format
  3. Preparing to send it using what appears to be the Telegram Bot API (sendPhoto method)
  4. Exfiltrating the screenshot to give attackers visual confirmation of the infection and see what the victim is doing

This is common ransomware/spyware behavior to:

  • Verify the infection was successful
  • Gather intelligence about the victim’s activities
  • Provide proof to ransomware operators
  • Identify high-value targets based on what’s visible on screen

Fig 12 — Complete Encryption

Fig 12 — Complete Encryption

These two figures show the malware building status messages about the encryption process:

Figure 1: Encrypted Files Count Field

  1. Load data:
  • mov r8, rdi
  • mov [rsp+708h+var_360], r15

Add encrypted files field:

  • lea rdx, aNameEncryptedF loads "{ \"name\": \"Encrypted Files\", \"valu..."
  • mov rcx, rbx
  • mov byte ptr [rax+r15], 0 (null terminates a string)
  • call sub_1405CCF20 (appends field to JSON)

Add inline formatting:

  • lea rdx, aInlineTrue loads "\", \"inline\": true },"
  • mov rcx, rbx

Image 2: Encryption Complete Message

  1. Load character:
  • mov edx, r15d
  • mov byte ptr [rax], 2Dh (loads '-' character, likely for formatting)

Process data:

  • lea rcx, [rax+r15]
  • call sub_1405C50B0

Load more data:

  • mov rax, [rsp+708h+var_388]
  • mov r8, r12
  • mov [rsp+708h+var_380], rbp

Add completion message:

  • lea rdx, aEncryptionComp loads "Encryption Complete! Files: "
  • mov rcx, rdi
  • mov byte ptr [rax+rbp], 0 (null terminate)
  • call sub_1405CCF20 (appends message)

Add HWID field:

  • lea rdx, aHwid_0 loads "\nHWID: "
  • mov rcx, rdi

Purpose: The malware is:

  1. Counting encrypted files and adding that count to the JSON webhook payload
  2. Generating a completion message: “Encryption Complete! Files: [count]”
  3. Including the HWID (Hardware ID) in the completion notification

This creates a final exfiltration message that tells the attacker:

  • How many files were successfully encrypted
  • That the encryption process is complete
  • The victim’s unique hardware identifier

The message structure appears to be:

Encryption Complete! Files: [number] HWID: [hardware_id]

This is the “mission accomplished” notification that ransomware operators receive when a system has been fully encrypted.

Fig 13 — End of the Payload Execution and Evasion mechanisms

Fig 13 — End of the Payload Execution and Evasion mechanisms

These three figures show anti-analysis and persistence mechanisms in the malware:

Figure 1: Anti-Debug Check Failed (loc_140023D40)

  1. Log critical error:
  • lea rdx, aCritical loads "CRITICAL"
  • mov rcx, rsi
  • call sub_140001850 (logs critical level)

Anti-debug failure message:

  • lea rdx, aAntiDebugCheck_0 loads "Anti-Debug check failed. Exiting payloa..."
  • mov rcx, rbx
  • call sub_140001850 (logs the failure)

Exit routine:

  • mov rcx, rbx
  • call sub_1405AE6B0 (cleanup/exit function)
  • mov rcx, rsi
  • call sub_1405AE6B0 (additional cleanup)

Figure 2: UAC Bypass Re-launch (loc_140023C88)

  1. Log info:
  • lea rdx, aInfo loads "INFO"
  • mov rcx, rsi
  • call sub_140001850

UAC bypass message:

  • lea rdx, aUacBypassReLau loads "UAC bypass re-launch attempted. Exiting..."
  • mov rcx, rbx
  • call sub_140001850 (logs UAC bypass attempt)

Figure 3: Payload Finished (loc_140023C09)

  1. Log info:
  • lea rdx, aInfo loads "INFO"
  • mov rcx, rsi
  • call sub_140001850

Completion message:

  • lea rdx, aBqtlockPayload_0 loads "BQTLock Payload finished initial execut..."
  • mov rcx, rbx
  • call sub_140001850 (logs completion)

Cleanup:

  • mov rcx, rbx
  • call sub_1405AE6B0
  • mov rcx, rsi

Purpose: These are three different exit paths for the malware:

  1. Anti-Debug Detection: If the malware detects it’s being debugged/analyzed, it logs a critical error and exits to avoid analysis
  2. UAC Bypass: The malware attempts to re-launch itself with elevated privileges via UAC bypass, then exits the original process
  3. Normal Completion: The payload has finished its initial execution phase successfully

This shows sophisticated evasion techniques:

  • Anti-analysis to detect debuggers/sandboxes
  • Privilege escalation via UAC bypass for deeper system access
  • Clean exit handling for different scenarios

Fig 14 — Anti-Analysis Technique

Fig 14 — Anti-Analysis Technique

These two figures show the malware checking for Python installation and its configuration — likely to determine if it can execute Python-based payloads or scripts:

Figure 1: Initial Python Check (loc_140004BC4)

  1. Unwind/exception handling setup_unwind { // __GSHandlerCheck
  2. Check Python archive:
  • lea rcx, aPyiArchiveFile loads "_PYI_ARCHIVE_FILE"
  • call sub_140008D40 (checks if this environment variable/marker exists)

Test result:

  • test rax, rax (checks if Python archive was found)
  • jz loc_140004CE4 (jump if zero/not found)

Figure 2: Detailed Python Environment Check (loc_140004CFC)

  1. Load RBXmov rdx, rbx
  2. Check Python archive again:
  • lea rcx, aPyiArchiveFile loads "_PYI_ARCHIVE_FILE"
  • call sub_140008E50

Check Python application directory:

  • lea rcx, aPyiApplication loads "_PYI_APPLICATION_HOME_DIR"
  • call sub_140008E80

Check parent process:

  • lea rcx, aPyiParentProce loads "_PYI_PARENT_PROCESS_LEVEL"
  • call sub_140008EB0

Check splash IPC:

  • lea rcx, aPyiSplashIpc loads "_PYI_SPLASH_IPC"
  • call sub_140008EB0

Purpose: The malware is detecting PyInstaller environments by looking for specific environment variables:

  • **_PYI_ARCHIVE_FILE** - Indicates the executable was created with PyInstaller
  • **_PYI_APPLICATION_HOME_DIR** - PyInstaller application directory
  • **_PYI_PARENT_PROCESS_LEVEL** - Process hierarchy in PyInstaller execution
  • **_PYI_SPLASH_IPC** - PyInstaller splash screen IPC mechanism

Why this matters:

  1. Anti-Analysis: PyInstaller is commonly used by analysts to unpack and analyze malware. If these variables are present, the malware knows it’s being analyzed
  2. Execution Environment Detection: Determines if it’s running in a sandboxed PyInstaller environment
  3. Secondary Payload Deployment: May indicate the malware has Python-based components it can deploy
  4. Evasion: If PyInstaller environment is detected, it may alter behavior or exit to avoid analysis

This is a sophisticated anti-analysis technique specifically targeting researchers who use PyInstaller-based tools to examine malware.

Fig 15 — Similar to previous anti-analysis technique

Fig 15 — Similar to previous anti-analysis technique

This code is checking for PyInstaller’s strict unpack mode — another anti-analysis technique:

  1. Load PyInstaller environment variable:
  • lea rcx, aPyinstallerStr loads "PYINSTALLER_STRICT_UNPACK_MO[DE]"
  • call sub_140008D40 (checks if this environment variable is set)

Check result:

  • mov r8, rax (store result)
  • test rax, rax (test if the variable exists)
  • jz short loc_140004E69 (jump if zero/not set)

Purpose:

**PYINSTALLER_STRICT_UNPACK_MODE** is an environment variable used when:

  • Security researchers extract PyInstaller executables
  • Analysts are unpacking the malware to examine its contents
  • The executable is being run in a controlled analysis environment with PyInstaller debugging enabled

Why the malware checks this:

  1. Anti-Unpacking: If this variable is set, it indicates someone is trying to extract/unpack the PyInstaller bundle
  2. Analysis Detection: This is a strong indicator the malware is being examined by researchers
  3. Behavioral Change: The malware likely alters its behavior or terminates if detected to prevent analysis

Combined with the previous checks for _PYI_ARCHIVE_FILE, _PYI_APPLICATION_HOME_DIR, etc., this creates a comprehensive PyInstaller detection system that can identify:

  • Standard PyInstaller execution environments
  • Unpacking/extraction attempts
  • Analysis tool environments

If any of these are detected, the malware can avoid revealing its true capabilities to researchers.

Fig 16 — PyInstaller splash screen detection and unpacking failure

Fig 16 — PyInstaller splash screen detection and unpacking failure

This code shows two related sections handling PyInstaller splash screen detection and unpacking failure:

Top Section: Unpack Failure Handler

  1. Error message: “Failed to load splash screen resources!”…
  2. Load error message:
  • lea rcx, aFailedToUnpack loads "Failed to unpack sp[lash screen]"
  • jmp short loc_140005IDD (jumps to error handling)

Bottom Section: Splash IPC Check (loc_1400051F4)

  1. Load zero value:
  • lea rdx, a0 loads "0"

Check splash IPC variable:

  • lea rcx, aPyiSplashIpc loads "_PYI_SPLASH_IPC"
  • call sub_140008E50 (checks/sets the environment variable)

Purpose:

This is handling PyInstaller’s splash screen functionality:

  1. **_PYI_SPLASH_IPC** - Environment variable used for inter-process communication with PyInstaller's splash screen feature
  2. Splash screen resources — PyInstaller executables can display a loading splash screen while unpacking

What’s happening:

  • The malware is either:
  • Using a fake splash screen as part of its PyInstaller packaging to appear legitimate
  • Detecting splash screen presence to identify PyInstaller analysis environments
  • Handling unpacking failures related to splash screen resources

Anti-Analysis Context: Combined with the earlier PyInstaller checks, if the malware detects:

  • PyInstaller environment variables
  • Splash screen IPC mechanisms
  • Unpacking failures

It can determine it’s being analyzed or unpacked and either:

  • Display a benign “failed to unpack” error (hiding malicious behavior)
  • Terminate execution to avoid revealing its payload
  • Behave differently to evade detection

The “Failed to unpack splash screen” message is likely a decoy error shown to analysts to make the malware appear broken or non-functional, when in reality it’s deliberately avoiding analysis.

Fig 17— C2 for the Ransomware

Fig 17— C2 for the Ransomware

The above figures show the C2 Panel and the C2 downloading an executable

Fig 18— C2 Server and Panel

Fig 18— C2 Server and Panel

Figure 1: Malware Distribution Server

  • URL: [http://92.113.146.56/BQT.exe](http://92.113.146.56/BQT.exe)
  • Detection: 18/98 security vendors flagged as malicious
  • Community Score: -12 (malicious)
  • Content Type: text/html
  • Purpose: Malware payload distribution — This is hosting the actual BQTlock ransomware executable
  • Threat Intel: ViriBack identified this as a botnet CnC panel for BQTlock malware (1 month ago)

Figure 2: API/Control Panel Endpoint

  • URL: [http://92.113.146.56/api.php](http://92.113.146.56/api.php)
  • Detection: 18/98 security vendors flagged as malicious
  • Community Score: -71 (highly malicious)
  • Content Type: application/json
  • Purpose: Command & Control API endpoint — This receives JSON data from infected machines
  • Threat Intel: Also identified as botnet CnC panel for BQTlock

Analysis: The IP 92.113.146.56 is serving as the BQTlock command and control infrastructure:

  1. /BQT.exe — Distributes the ransomware binary to new victims
  2. /api.php — Receives JSON reports from infected machines (the webhook-style data we saw being constructed in the assembly code)

Fig 19 — Analysis of the BQT.exe file

Fig 19 — Analysis of the BQT.exe file

These four figures show comprehensive threat detection results for the BQT.exe ransomware file from VirusTotal:

Figure 1: File Overview & Initial Detections

  • Hash: 9600db537e27db88ed2eca3be0ffab35cdb22a86a6dbb0…
  • Filename: BQT.exe
  • Size: 8.46 MB
  • Detection: 46/72 security vendors flagged as malicious
  • Community Score: -66 (highly malicious)
  • Behavior Tags: peexe, persistence, checks-usb-bus, spreader, calls-wmi, checks-bios

Key YARA Rule Matches:

  1. UAC Bypass via EventViewer — Uses eventvwr.exe to bypass UAC (2 days ago)
  2. References SecTools — Contains many IR and analysis tools references
  3. Telegram ChatBot — Has Telegram bot functionality for C2 communications

Figure 2: Advanced Behavioral Detections

Sophisticated TTPs (Tactics, Techniques, Procedures):

  1. DNS Query for IP Lookup APIs — Queries api.ipify.org from non-browser process (getting victim’s public IP)
  2. Admin Group Addition — Adds users to local administrator group (privilege escalation)
  3. Registry Desktop Background Change — Modifies desktop wallpaper (typical ransomware ransom note display)
  4. Telegram API Communication — Non-browser process contacting Telegram API (covert C2)
  5. IP Lookup Service API — External IP lookups via api.ipify.org (reconnaissance)
  6. Telegram Bot API Request — Suspicious DNS queries to api.telegram.org (exfiltration channel)
  7. LNK Double Extension — Creates suspicious shortcut files (persistence/execution trick)

Figure 3: Persistence & Privilege Escalation

Advanced Malicious Behaviors:

  1. PowerShell Module Creation — Non-PowerShell process creating .psm1/.psd1 modules (fileless malware techniques)
  2. Scheduled Task with High Privileges — Creates schtasks with elevated privileges (persistence)
  3. Non-Interactive PowerShell — Spawns PowerShell without GUI via explorer.exe (stealth execution)
  4. Security Group Manipulation — Removes members from security-enabled groups (defense evasion)
  5. Schtasks.exe via User Account — Creates scheduled tasks (persistence mechanism)
  6. Local User Creation — Creates local Windows users (shouldn’t happen in Active Directory — creates backdoor accounts)
  7. Security Group Addition — Adds members to security groups (privilege escalation)

Figure 4: Network-Based Detections

Network Threat Intelligence:

  1. ET HUNTING PNG in HTTP POST — Network trojan detected (data exfiltration via image files)
  2. Policy Violation — HTTP request by IPv4 address (suspicious non-domain traffic)
  3. IP Check Domain — Contacts icanhazip.com (gets external IP — common malware reconnaissance)
  4. External IP Lookup — DNS lookup for icanhazip.com (device retrieving external IP address)
  5. HTTP Header Manipulation — Unusual Content-Transfer-Encoding used
  6. URI Path Slash Characters — Consecutive slashes in URI (evasion technique)

Summary: Complete Attack Chain

The BQTlock ransomware demonstrates highly sophisticated, multi-stage attack capabilities:

Initial Access & Execution:

  • UAC bypass via eventvwr.exe hijacking
  • PowerShell-based fileless execution
  • Non-interactive stealth processes

Persistence:

  • Scheduled tasks with high privileges
  • Local user account creation (backdoors)
  • Registry modifications
  • LNK file manipulation

Privilege Escalation:

  • Admin group additions
  • Security group manipulation
  • UAC bypass techniques

Defense Evasion:

  • Non-browser network communications
  • Security group membership changes
  • Desktop background changes (overwrites evidence)

Reconnaissance:

  • External IP lookups (api.ipify.org, icanhazip.com)
  • System information gathering
  • USB device checks
  • BIOS checks

Command & Control:

  • Telegram Bot API (primary C2)
  • Custom API endpoint (92.113.146.56/api.php)
  • Covert non-browser communications

Exfiltration:

  • Screenshot capture and transmission
  • JSON data exfiltration
  • PNG file in HTTP POST (steganography possibility)
  • Password file theft

This is a highly advanced ransomware with APT-level sophistication, combining multiple evasion techniques, dual C2 channels, comprehensive system reconnaissance, and robust persistence mechanisms.

Fig 20 — Another executable from the Ransomware stager

Fig 20 — Another executable from the Ransomware stager

This image shows VirusTotal detection results for another BQTlock-related file — appears to be a loader or dropper component:

File Overview

  • Hash: b8b8899c205e8705ad92b771208c82c0d1c84fbce6ab53…
  • Filename: start.exe(1).bin
  • Size: 12.53 [MB]
  • Detection: 17/72 security vendors flagged as malicious
  • Community Score: -1 (malicious)
  • File Type Tags: peexe, overlay, 64bits

Key Detection

YARA Rule Match:

  • PyInstaller Detection — Matches rule from PyInstaller ruleset at https://github.com/bartblaze/Yara-rules
  • Description (partially visible): “Identifies executable converted using PyInstaller. This rule by itself does NOT necessarily mean the…”

Analysis

This file is:

  1. A PyInstaller-packaged executable — Confirms the malware uses PyInstaller for packaging
  2. Likely the initial loader/dropper — The filename “start.exe” suggests this is the first-stage component that:
  • Unpacks the main BQT.exe payload
  • Performs initial system checks
  • Sets up the execution environment
  • Downloads or deploys the main ransomware

Lower detection rate (17/72 vs 46/72 for BQT.exe) — Indicates this loader is more stealthy than the main payload

64-bit PE executable with overlay — The “overlay” tag means extra data is appended to the PE file, which is typical for:

  • PyInstaller bundles (contains compressed Python runtime and scripts)
  • Packed malware (encrypted payload stored in overlay section)

Connection to Previous Analysis: This explains why the BQT.exe code was checking for PyInstaller environment variables — the malware is distributed as a multi-stage PyInstaller package:

  • Stage 1: start.exe (this file) — Loader with anti-analysis checks
  • Stage 2: BQT.exe — Main ransomware payload

The PyInstaller detection mechanisms we analyzed are checking if the loader is being unpacked/analyzed before deploying the actual malicious payload.

Fig 21 — Remcos Detected

Fig 21 — Remcos Detected

The above figure shows at what address was Remcos Detected

Fig 22 — Credential Stealing

Fig 22 — Credential Stealing

These two figures show actual malicious behaviors detected when the BQTlock ransomware executes:

Figure 1: Ransomware Encryption Detection

BaqiyatLock (BQTlock variant) Detected

  • Threat: Data Encrypted for Impact
  • Filename: C:\Program Files\Adobe\Acrobat DC\Acrobat\Legal\nl_NL\license.html.bqtlock
  • MD5: 64cd50ad31221e4f2a25c2bc584c53bc
  • SHA1: 6eb785981261801e75ca876e279d443051681903
  • SHA256: 12769757131c689f5d4006d4da1dc2985f3bc9ae84597205bcaa364173a4491d

Analysis:

  • The malware has encrypted an Adobe Acrobat license file
  • Added .bqtlock extension to the encrypted file
  • This is the ransom encryption in action — taking legitimate files and encrypting them
  • Targets common application directories (Adobe in this case)

Figure 2: Credential Theft Detection

Steals Credentials from Web Browsers

  • MITRE ATT&CK: T1552.001 (Credentials In Files), T1555.003 (Credentials from Web Browsers)
  • Operation: CREATE
  • Device: DISK_FILE_SYSTEM
  • Object: DIRECTORY
  • Path: C:\Users\admin\AppData\Roaming\Opera Software\Opera Stable\
  • Status: 0xC000003A (STATUS_OBJECT_PATH_NOT_FOUND)
  • Access Type: SUPERSEDED
  • Permissions: SYNCHRONIZE, FILE_READ_DATA

Analysis:

  • The malware is attempting to steal saved credentials from Opera browser
  • Targeting the Opera Stable profile directory where passwords are stored
  • Status code indicates the path wasn’t found (Opera may not be installed in this sandbox)
  • Shows the password stealing functionality we saw being prepared in the assembly code

Summary

These detections confirm the complete attack chain we analyzed:

  1. System Reconnaissance ✓ (IP gathering, OS detection)
  2. Credential Theft ✓ (Attempting to steal browser passwords from Opera, likely also Chrome/Firefox/Edge)
  3. File Encryption ✓ (Encrypting files with .bqtlock extension)
  4. Data Exfiltration ✓ (Sending stolen data via Telegram/Discord webhooks)
  5. Ransom Demands ✓ (Leaving ransom notes after encryption)

The malware is a fully functional ransomware with information stealer capabilities, combining:

  • Encryption for extortion (ransomware)
  • Credential theft (infostealer)
  • Data exfiltration (spyware)
  • System reconnaissance (reconnaissance malware)

This makes it particularly dangerous as it both locks files for ransom AND steals sensitive credentials that could be sold or used for further attacks.

Fig 23 — DIscord and Telegram Webhooks

Fig 23 — DIscord and Telegram Webhooks

These two figures show extracted configuration data from the BQTlock malware — revealing the hardcoded C2 infrastructure and API tokens:

Figure 1: Complete C2 Configuration

Telegram Bot Configuration

“Telegram-Token”: “7060776700:AAGE_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo”

Telegram API Endpoints

*“Telegram-Info-Links”: { “7060776700:AAGE_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo”: { “Get info about bot”: “https://api.telegram.org/bot7060776700:AAGe_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo/getMe",

“Get incoming updates”: “https://api.telegram.org/bot7060776700:AAGe_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo/getUpdates",

“Set webhook”: “https://api.telegram.org/bot7060776700:AAGe_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo/setWebhook",

“Delete webhook”: “https://api.telegram.org/bot7060776700:AAGe_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo/deleteWebhook",

“Get incoming updates”: “https://api.telegram.org/bot7060776700:AAGe_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo/deleteWebhook?drop_pending_updates=true" } }*

Discord Webhook Configuration

“Discord-Webhook-Tokens”: [ “1422999331195191336/5dWTzBL9FybdjuW3RqPqmUD7f72DDEsMYGnZLLYZwU5XwXo0dcgnudaIV25fElMlbpDS” ]

Discord Webhook URLs

“Discord-Info-Links”: { “1422999331195191336/5dWTzBL9FybdjuW3RqPqmUD7f72DDEsMYGnZLLYZwU5XwXo0dcgnudaIV25fElMlbpDS”: { “Get Webhook Info”: “https://discord.com/api/webhooks/1422999331195191336/5dWTzBL9FybdjuW3RqPqmUD7f72DDEsMYGnZLLYZwU5XwXo0dcgnudaIV25fElMlbpDS" } }

Figure 2: Telegram Send Message Configuration

“Telegram-Requests”: [ { “Token”: “7060776700:AAGe_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo”, “End-Point”: “sendMessage”, “Args”: {} } ]

Critical Intelligence Extracted

1. Telegram Bot Token

  • Token: 7060776700:AAGe_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo
  • Bot ID: 7060776700
  • This token allows complete control of the bot and can be used to:
  • See all messages sent to the bot
  • Intercept stolen data
  • Identify the bot owner (if Telegram cooperates with law enforcement)

2. Discord Webhook

3. Telegram API Operations

The malware uses these Telegram Bot API endpoints:

  • getMe — Verifies bot is active
  • getUpdates — Receives commands from operators
  • setWebhook — Sets up webhook for real-time updates
  • deleteWebhook — Removes webhooks
  • sendMessage — Sends stolen data to operators

Defensive Actions

This configuration reveals:

  1. IOCs (Indicators of Compromise):
  • Block all traffic to api.telegram.org with this bot token
  • Block Discord webhook ID 1422999331195191336
  • Report both to Telegram and Discord for takedown

Attribution Potential:

  • Telegram bot can be traced to creator’s account
  • Discord webhook linked to specific Discord server
  • Both platforms could provide investigation data to law enforcement

Victim Data Recovery:

  • If these tokens are still active, investigators could potentially:
  • Monitor what data is being exfiltrated
  • Identify victims by IP/HWID data sent
  • See ransom negotiations

Operator Identification:

  • Telegram bot owner’s account information
  • Discord server ownership details
  • Payment methods used to create accounts

This hardcoded configuration is a significant OPSEC failure by the malware authors — these tokens should have been encrypted or obfuscated, but they’re in plaintext, making takedown and investigation much easier.

Conclusion

1. Multi-Stage Architecture

  • Stage 1: PyInstaller-packed loader (start.exe) — 12.53 MB, detection rate 17/72
  • Stage 2: Main payload (BQT.exe) — 8.46 MB, detection rate 46/72
  • Uses PyInstaller packaging to evade initial detection and complicate analysis

2. Advanced Capabilities

  • File Encryption: Targets user documents with .bqtlock extension
  • Credential Theft: Steals passwords from web browsers (Chrome, Firefox, Opera, Edge)
  • System Reconnaissance: Gathers OS version, HWID, disk info, IP addresses (public/private)
  • Screenshot Capture: Takes desktop screenshots for operator intelligence
  • Privilege Escalation: UAC bypass via EventViewer hijacking
  • Persistence: Scheduled tasks with elevated privileges, local user creation

3. Anti-Analysis Techniques

  • PyInstaller environment detection (multiple checks for _PYI_* variables)
  • Anti-debugging checks with critical error handling
  • UAC bypass for deeper system access
  • Dynamic behavior modification based on execution environment

4. Command & Control Infrastructure The malware employs dual C2 channels for redundancy:

Primary: Telegram Bot API

  • Provides bidirectional communication
  • Allows operator commands via Telegram
  • Sends formatted victim reports

Secondary: Discord Webhooks

  • One-way data exfiltration
  • Formatted embed messages with system details
  • Backup channel if Telegram is blocked

Tertiary: Custom API Endpoint

  • Direct HTTP POST to attacker infrastructure
  • JSON-formatted data transmission
  • IP: 92.113.146.56

5. Data Exfiltration The malware constructs comprehensive JSON payloads containing:

  • Victim identification (username, HWID)
  • Network information (public IP, local IP)
  • System details (OS version, disk info)
  • Encryption status (files encrypted count)
  • Stolen credentials (saved passwords)
  • Screenshots (PNG format)

6. Threat Actor Profile

  • OPSEC Failures: Hardcoded tokens in plaintext reveal poor operational security
  • Sophistication Level: Medium-to-high technical capability but amateur operational practices
  • Target Profile: Opportunistic — relies on social engineering and mass distribution
  • Attribution Indicators: Active Telegram bot and Discord webhook provide investigation leads

MITRE ATT&CK

IOCs

*MD5: [Various samples detected] SHA1: [Various samples detected] SHA256: 9600db537e27db88ed2eca3be0ffab35cdb22a86a6dbb0… Size: 8.46 MB (8,870,912 bytes)


***Loader (start.exe)**

SHA256: b8b8899c205e8705ad92b771208c82c0d1c84fbce6ab53… Size: 12.53 MB (13,140,992 bytes)


***Encrypted File Example**

Original: C:\Program Files\Adobe\Acrobat DC\Acrobat\Legal\nl_NL\license.html Encrypted: license.html.bqtlock MD5: 64cd50ad31221e4f2a25c2bc584c53bc SHA1: 6eb785981261801e75ca876e279d443051681903 SHA256: 12769757131c689f5d4006d4da1dc2985f3bc9ae84597205bcaa364173a4491d


*### Network Indicators*

***IP Addresses**

92.113.146.56 — Command & Control Server (Malicious) — /BQT.exe (Payload distribution) — /api.php (Data exfiltration endpoint)


***Domains**

api.telegram.org — Telegram Bot API (C2 channel) discord.com — Discord Webhooks (C2 channel) api.ipify.org — IP lookup service (Reconnaissance) icanhazip.com — IP lookup service (Reconnaissance)


***URLs**

http://92.113.146.56/BQT.exe http://92.113.146.56/api.php https://api.telegram.org/bot7060776700:AAGE_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo/getMe https://api.telegram.org/bot7060776700:AAGE_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo/getUpdates https://api.telegram.org/bot7060776700:AAGE_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo/setWebhook https://api.telegram.org/bot7060776700:AAGE_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo/deleteWebhook https://api.telegram.org/bot7060776700:AAGE_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo/sendMessage https://discord.com/api/webhooks/1422999331195191336/5dWTzBL9FybdjuW3RqPqmUD7f72DDEsMYGnZLLYZwU5XwXo0dcgnudaIV25fElMlbpDS


*### Credentials & Tokens*

***Telegram Bot Token** (CRITICAL — Report for immediate revocation)

7060776700:AAGE_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo Bot ID: 7060776700


***Discord Webhook** (CRITICAL — Report for immediate revocation)

Webhook ID: 1422999331195191336 Token: 5dWTzBL9FybdjuW3RqPqmUD7f72DDEsMYGnZLLYZwU5XwXo0dcgnudaIV25fElMlbpDS


*### File System Indicators*

***File Extensions**

.bqtlock — Encrypted file marker


***File Paths**

C:\Windows\Temp\bqt_passwords.txt — Stolen credentials staging file C:\Users[username]\AppData\Roaming\Opera Software\Opera Stable\ — Target directory C:\Users[username]\AppData\Local\Google\Chrome\User Data\ — Target directory (inferred) C:\Users[username]\AppData\Roaming\Mozilla\Firefox\Profiles\ — Target directory (inferred)


***Filenames**

BQT.exe — Main payload start.exe — Initial loader bqt_passwords.txt — Credential collection file screenshot_file — Screenshot capture


*### Registry Indicators*

***Modified Keys** (Based on behavioral analysis)

HKCU\Control Panel\Desktop\Wallpaper — Desktop background change (ransom note) HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run — Persistence (potential) HKCU\Software\Microsoft\Windows\CurrentVersion\Run — Persistence (potential)


*### Process & Service Indicators*

***Process Names**

BQT.exe start.exe eventvwr.exe — UAC bypass vector schtasks.exe — Scheduled task creation powershell.exe — Fileless execution


***Scheduled Tasks**

[Various] — Created with high privileges for persistence


***Local User Accounts**

[Various] — Backdoor accounts created for persistence


*### Environment Variables Checked

_PYI_ARCHIVE_FILE _PYI_APPLICATION_HOME_DIR _PYI_PARENT_PROCESS_LEVEL _PYI_SPLASH_IPC PYINSTALLER_STRICT_UNPACK_MODE


*### String Indicators*

***Log Messages**

“BQTLock Payload started.” “Encryption Complete! Files: “ “Anti-Debug check failed. Exiting payloa…” “UAC bypass re-launch attempted. Exiting…” “BQTLock Payload finished initial execut…” “Discord Webhook URL is not configured.” “Telegram is not configured.” “Attempting to send final report.” “Failed to write passwords” “Detected OS: “ “Infection Report:\nPublic IP:” “\nLocal IP: “ “\nAdmin Status: “ “sendPhoto”


***JSON Field Names**

“username”: “BQTLock Bot” “Public IP” “Local IP” “OS Version” “HWID” “Disk Info” “Password Stealing” “Encrypted Files” “inline”: true/false



**YARA Rule**

YARA Rule: BQTlock Ransomware Detection
 Author: Subhankar H.
 Date: 2025–10–16
 Description: Detects BQTlock/BaqiyatLock ransomware variants
 Reference: Analysis of samples 9600db537e27db88ed2eca3be0ffab35cdb22a86a6dbb0…

 Detection Coverage:
 — Main payload (BQT.exe)
 — PyInstaller loader (start.exe)
 — Memory execution
 — Configuration extraction
*/

rule BQTlock_Ransomware_Comprehensive
{
 meta:
 description = “Detects BQTlock/BaqiyatLock ransomware family”
 author = “Security Researcher”
 date = “2025–10–16”
 hash1 = “9600db537e27db88ed2eca3be0ffab35cdb22a86a6dbb0”
 hash2 = “b8b8899c205e8705ad92b771208c82c0d1c84fbce6ab53”
 severity = “critical”
 malware_family = “BQTlock”
 malware_type = “ransomware”
 reference = “[https://virustotal.com](https://virustotal.com)”

 strings:
 // BQTlock specific strings
 $bqt_payload_start = “BQTLock Payload started” ascii wide
 $bqt_payload_finish = “BQTLock Payload finished” ascii wide
 $bqt_bot_name = “BQTLock Bot” ascii wide
 $bqt_extension = “.bqtlock” ascii wide
 $bqt_password_file = “bqt_passwords.txt” ascii wide

 // Telegram Bot API indicators
 $telegram_bot_token = /[0–9]{10}:[A-Za-z0–9_-]{35}/ ascii
 $telegram_api_1 = “api.telegram.org/bot” ascii wide
 $telegram_api_2 = “/sendMessage” ascii wide
 $telegram_api_3 = “/getUpdates” ascii wide
 $telegram_api_4 = “/setWebhook” ascii wide
 $telegram_api_5 = “/getMe” ascii wide
 $telegram_api_6 = “/sendPhoto” ascii wide

 // Discord webhook indicators
 $discord_webhook_1 = “discord.com/api/webhooks/” ascii wide
 $discord_webhook_2 = /discord\.com\/api\/webhooks\/[0–9]{18,19}\/[A-Za-z0–9_-]{68}/ ascii

 // C2 Infrastructure
 $c2_ip = “92.113.146.56” ascii wide
 $c2_api_endpoint = “/api.php” ascii wide

 // JSON exfiltration fields
 $json_field_1 = “\”username\”:” ascii wide
 $json_field_2 = “\”Public IP\”” ascii wide
 $json_field_3 = “\”Local IP\”” ascii wide
 $json_field_4 = “\”OS Version\”” ascii wide
 $json_field_5 = “\”HWID\”” ascii wide
 $json_field_6 = “\”Disk Info\”” ascii wide
 $json_field_7 = “\”Password Stealing\”” ascii wide
 $json_field_8 = “\”Encrypted Files\”” ascii wide
 $json_field_9 = “\”inline\”:” ascii wide

 // Anti-analysis strings
 $pyinstaller_check_1 = “_PYI_ARCHIVE_FILE” ascii wide
 $pyinstaller_check_2 = “_PYI_APPLICATION_HOME_DIR” ascii wide
 $pyinstaller_check_3 = “_PYI_PARENT_PROCESS_LEVEL” ascii wide
 $pyinstaller_check_4 = “_PYI_SPLASH_IPC” ascii wide
 $pyinstaller_check_5 = “PYINSTALLER_STRICT_UNPACK_MODE” ascii wide
 $anti_debug_msg = “Anti-Debug check failed” ascii wide

 // UAC bypass and privilege escalation
 $uac_bypass_1 = “UAC bypass re-launch attempted” ascii wide
 $uac_bypass_2 = “eventvwr.exe” ascii wide nocase
 $admin_status = “Admin Status:” ascii wide

 // Reconnaissance strings
 $recon_1 = “Detected OS:” ascii wide
 $recon_2 = “Infection Report:” ascii wide
 $recon_3 = “api.ipify.org” ascii wide
 $recon_4 = “icanhazip.com” ascii wide

 // Credential theft indicators
 $cred_theft_1 = “Opera Software\\Opera Stable” ascii wide
 $cred_theft_2 = “Google\\Chrome\\User Data” ascii wide
 $cred_theft_3 = “Mozilla\\Firefox\\Profiles” ascii wide
 $cred_theft_4 = “Failed to write passwords” ascii wide

 // Screenshot capture
 $screenshot_1 = “screenshot_file” ascii wide
 $screenshot_2 = “image/png” ascii wide
 $screenshot_3 = “sendPhoto” ascii wide

 // Error messages (operational indicators)
 $error_msg_1 = “Discord Webhook URL is not configured” ascii wide
 $error_msg_2 = “Telegram is not configured” ascii wide
 $error_msg_3 = “Attempting to send final report” ascii wide
 $error_msg_4 = “Failed to load splash screen resources” ascii wide

 // Encryption indicators
 $crypto_1 = “Encryption Complete! Files:” ascii wide
 $crypto_2 = “text/plain” ascii wide

 // PyInstaller artifacts
 $pyinstaller_magic = “MEI” ascii
 $pyinstaller_struct = { 4D 45 49 0C 0B 0A 09 08 }

 condition:
 uint16(0) == 0x5A4D and // PE header
 filesize < 20MB and
 (
 // High confidence: BQTlock specific + C2
 (
 2 of ($bqt_*) and
 (1 of ($telegram_*) or 1 of ($discord_*) or $c2_ip)
 )
 or
 // Medium confidence: Multiple telemetry indicators
 (
 4 of ($json_field_*) and
 (1 of ($telegram_api_*) or 1 of ($discord_webhook_*))
 )
 or
 // Anti-analysis + C2 combination
 (
 3 of ($pyinstaller_check_*) and
 ($telegram_bot_token or $discord_webhook_2) and
 2 of ($recon_*)
 )
 or
 // Credential theft + exfiltration
 (
 2 of ($cred_theft_*) and
 $screenshot_1 and
 (1 of ($telegram_api_*) or 1 of ($discord_webhook_*))
 )
 or
 // Configuration extraction
 (
 $telegram_bot_token and
 $discord_webhook_2 and
 3 of ($json_field_*)
 )
 or
 // High-confidence pattern matching
 (
 5 of ($bqt_*, $telegram_*, $discord_*, $json_field_*, $pyinstaller_check_*)
 )
 )
}

rule BQTlock_Loader_PyInstaller
{
 meta:
 description = “Detects BQTlock PyInstaller loader (start.exe variant)”
 author = “Security Researcher”
 date = “2025–10–16”
 hash = “b8b8899c205e8705ad92b771208c82c0d1c84fbce6ab53”
 severity = “high”

 strings:
 $pyinstaller_1 = “_PYI_ARCHIVE_FILE” ascii wide
 $pyinstaller_2 = “_PYI_APPLICATION_HOME_DIR” ascii wide
 $pyinstaller_3 = “PYINSTALLER_STRICT_UNPACK_MODE” ascii wide
 $pyinstaller_magic = { 4D 45 49 0C 0B 0A 09 08 }

 $bqt_ref_1 = “BQT.exe” ascii wide nocase
 $bqt_ref_2 = “bqt” ascii wide nocase
 $bqt_ref_3 = “.bqtlock” ascii wide

 $telegram_token = /[0–9]{10}:[A-Za-z0–9_-]{35}/ ascii
 $discord_webhook = /discord\.com\/api\/webhooks\/[0–9]{18,19}/ ascii

 condition:
 uint16(0) == 0x5A4D and
 filesize > 10MB and
 filesize < 15MB and
 (
 (2 of ($pyinstaller_*) and 1 of ($bqt_ref_*))
 or
 (3 of ($pyinstaller_*) and ($telegram_token or $discord_webhook))
 )
}

rule BQTlock_Memory_Execution
{
 meta:
 description = “Detects BQTlock ransomware in memory during execution”
 author = “Security Researcher”
 date = “2025–10–16”
 severity = “critical”

 strings:
 $mem_string_1 = “BQTLock Payload started” ascii wide
 $mem_string_2 = “Encryption Complete! Files:” ascii wide
 $mem_string_3 = “api.telegram.org/bot” ascii wide
 $mem_string_4 = “discord.com/api/webhooks/” ascii wide

 $api_call_1 = “CreateFileW” ascii wide
 $api_call_2 = “WriteFile” ascii wide
 $api_call_3 = “CryptEncrypt” ascii wide
 $api_call_4 = “InternetOpenW” ascii wide
 $api_call_5 = “HttpSendRequestW” ascii wide

 $json_pattern = /”username”\s*:\s*”BQTLock Bot”/ ascii wide

 condition:
 2 of ($mem_string_*) and
 3 of ($api_call_*) and
 $json_pattern
}

rule BQTlock_Configuration_Extractor
{
 meta:
 description = “Extracts embedded configuration from BQTlock samples”
 author = “Security Researcher”
 date = “2025–10–16”
 severity = “high”

 strings:
 $config_tg_token = “Telegram-Token” ascii wide
 $config_tg_info = “Telegram-Info-Links” ascii wide
 $config_dc_token = “Discord-Webhook-Tokens” ascii wide
 $config_dc_info = “Discord-Info-Links” ascii wide
 $config_tg_req = “Telegram-Requests” ascii wide

 $token_format_tg = /[0–9]{10}:AAGE_[A-Za-z0–9_-]{27}/ ascii
 $token_format_dc = /[0–9]{18,19}\/[A-Za-z0–9_-]{68}/ ascii

 $json_structure = /{[\s\n\r]*”[A-Za-z-]+”[\s\n\r]*:/ ascii

 condition:
 uint16(0) == 0x5A4D and
 (
 (2 of ($config_*) and ($token_format_tg or $token_format_dc))
 or
 ($config_tg_token and $config_dc_token and $json_structure)
 )
}

rule BQTlock_Encrypted_File
{
 meta:
 description = “Detects files encrypted by BQTlock ransomware”
 author = “Security Researcher”
 date = “2025–10–16”
 severity = “medium”

 strings:
 $extension = “.bqtlock” ascii wide nocase

 condition:
 $extension in (filesize-20..filesize) or
 // Check for .bqtlock in filename via external filename matching
 filename matches /\.bqtlock$/i
}

rule BQTlock_Network_Indicators
{
 meta:
 description = “Detects BQTlock network traffic patterns”
 author = “Security Researcher”
 date = “2025–10–16”
 severity = “high”

 strings:
 // Specific C2 infrastructure
 $c2_ip = “92.113.146.56” ascii
 $c2_endpoint = “/api.php” ascii

 // Telegram Bot API patterns
 $tg_bot_specific = “7060776700:AAGE_g6LUQlKmBgNTbeTVAWnY-OHLK9d6bo” ascii
 $tg_api_pattern = /api\.telegram\.org\/bot[0–9]{10}:[A-Za-z0–9_-]{35}\/(sendMessage|getUpdates|setWebhook|getMe|sendPhoto)/ ascii

 // Discord webhook patterns
 $dc_webhook_specific = “1422999331195191336/5dWTzBL9FybdjuW3RqPqmUD7f72DDEsMYGnZLLYZwU5XwXo0dcgnudaIV25fElMlbpDS” ascii

 // JSON payload patterns in traffic
 $json_payload_1 = /”username”\s*:\s*”BQTLock Bot”/ ascii
 $json_payload_2 = /”Encrypted Files”/ ascii
 $json_payload_3 = /”Password Stealing”/ ascii

 condition:
 any of them
}

**Happy Reading !!!**

메타데이터
post_id
2c63a9ecff84
slug
analysis-of-bqtlock-ransomware-2c63a9ecff84
url
https://medium.com/@shubhandrew/analysis-of-bqtlock-ransomware-2c63a9ecff84
canonical_url
https://medium.com/@shubhandrew/analysis-of-bqtlock-ransomware-2c63a9ecff84
author_url
https://medium.com/@shubhandrew
status
ok
fetched_at
2026-08-10 07:47:38