Analysis of BQTLock Ransomware
Summary
Analysis of BQTLock Ransomware

Summary
- In this scenario I took 2 samples mostly same in nature which performs a lot of different evasion techniques
- Remcos RAT is also being used with this ransomware variant as its stager
- The ransomware performs a lot of different types of compression to actually make the actual payload invisible
- It also uses OpenSSH SSL for gaining privilege escalation in the system
- 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
This assembly code is part of a BQTLocker ransomware routine that’s checking for and handling disk encryption. Here’s what it’s doing:
- Loading information — Gets “INFO” string and RSI register value (likely file/disk info)
- Preparing payload address — Loads
[rsp+708h+var_348]into RBX (probably a buffer or payload location) - First function call — Calls
sub_140001850with the loaded parameters - Loading payload message — Loads the string “BQTLock Payload started.” along with RBX value
- Second function call — Calls the same function again (likely logging or status display)
- Block setup — Loads
[rsp+708h+var_348]into RCX with "Block" context, then loads[rsp+708h+var_338]into R14 - Comparison check — Compares RCX with R14 (probably checking block boundaries or completion status)
- Conditional jump — Jumps to
loc_140023066if 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
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 sizedwPlatformId- platform identifierszCSDVersion- 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
- Load file path — Gets
[rsp+708h+var_388]into R12 - Prepare file path string — Loads “C:\Windows\Temp\bqt_passwords.txt” into RDX (the target file)
- Move path to RCX — Sets up R12 as first parameter
- Call logging function —
sub_140001850(likely logs the file access attempt) - Set file access mode — Moves
10hinto R8D (this is a file access flag, likelyGENERIC_READor similar) - Load path again — RDX = R12, RCX = RSI (setting up parameters)
- Call file operation —
sub_14059D70(probablyCreateFileor a wrapper to open the file) - Load result — RCX =
[rsp+708h+var_1C8](likely a file handle or result) - Call another function —
sub_140507A70(possiblyReadFile, file processing, or validation) - Test result —
test al, alchecks 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
The flow is:
- Try to write passwords → (if failed) → Log “ERROR” → Log “Failed to write passwords” → Jump to cleanup/recovery
This suggests the malware:
- Harvests credentials from the system
- Attempts to write them to a temporary file
- 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
This code is building a JSON configuration structure for the BQTLocker ransomware. Here’s what it’s doing:
- Load buffer address —
lea r15, [rsp+708h+var_488](destination buffer) - Start username JSON field:
lea rdx, aUsernameBqtlocloads"{ \"username\": \"BQTLock Bot\", \"embe..."mov rcx, r15sets destinationmov [rsp+708h+var_668], r15saves buffer pointercall sub_140001850(string operation, likely append/copy)
3. Continue building JSON:
mov rdx, [rsp+708h+var_6A0]loads next datamov rcx, rdicall sub_140004E00(more JSON construction)
4. Add Public IP field:
lea rdx, aNamePublicIpValoads"{ \"name\": \"Public IP\", \"value\": \"..."mov rcx, rbxcall sub_1405CCF20(append to JSON)
5. Add inline flag:
lea rdx, aInlineTrueloads"\", \"inline\": true },"call sub_1405AFCA0(continue building)
6. More JSON assembly:
- Multiple register moves and function calls
call sub_1405B1530mov 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
This code is continuing to build the JSON structure by adding another field for Local IP address. Here’s the breakdown:
- Add Local IP field:
lea rdx, aNameLocalIpValloads"{ \"name\": \"Local IP\", \"value\": \""mov rcx, rbxsets destinationcall sub_1405CCF20(appends this JSON field to the structure)
2. Add inline formatting:
lea rdx, aInlineTrueloads"\", \"inline\": true },"mov rcx, rbxcall sub_1405AFCA0(appends the inline flag and closes this field)
3. Continue JSON construction:
mov rdx, raxmov rcx, rsicall 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
These three images show the malware continuing to build the JSON payload with additional system information fields:
Figure 1: OS Version Field
lea rdx, aNameOsVersionVloads"{ \"name\": \"OS Version\", \"value\": "mov rcx, rbxcall sub_1405CCF20(appends OS version field)lea rdx, aInlineFalseloads"\", \"inline\": false },"call sub_1405AFCA0(closes the field with inline=false)
Figure 2: HWID (Hardware ID) Field
lea rdx, aNameHwidValueloads"{ \"name\": \"HWID\", \"value\": \""mov rcx, rbxcall sub_1405CCF20(appends HWID field)lea rdx, aInlineFalseloads"\", \"inline\": false },"call sub_1405AFCA0(closes the field)
Figure 3: Disk Info Field
lea rdx, aNameDiskInfoValoads"{ \"name\": \"Disk Info\", \"value\": "mov rcx, rbxcall sub_1405CCF20(appends disk info field)lea rdx, aInlineFalse_0loads"\", \"inline\": false }"
Purpose: The malware is building a comprehensive system profile that includes:
- Username & Bot identifier
- Public IP
- Local IP
- OS Version (Windows version details)
- HWID (Hardware ID — unique machine identifier)
- 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-sideinline: false= fields appear on their own line

Fig 8 — Password Stealing
This code is adding a password stealing field to the JSON payload and closing the JSON structure:
- Call function —
call sub_1405AE6B0(likely finalizes previous field or processes data) - Add Password Stealing field:
lea rdx, aNamePasswordStloads",{ \"name\": \"Password Stealing\", \"v..."mov rcx, r15sets destinationcall sub_1405AFCA0(appends the password stealing status field)
3. Close JSON array/object:
lea rdx, asc_14060E277loads"] }] }"(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
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)
- Load info message —
lea rdx, aInfoloads "INFO" - Set parameters —
mov rcx, rsi - Log info —
call sub_140001850(logging function) - Load warning message —
lea rdx, aDiscordWebhookloads "Discord Webhook URL is not configured." - Set parameters —
mov rcx, rbx - Log warning —
call sub_140001850(logs the configuration issue)
Figure 2: Telegram Check (loc_140023618)
- Load info message —
lea rdx, aInfoloads "INFO" - Set parameters —
mov rcx, rsi - Log info —
call sub_140001850 - Load warning message —
lea rdx, aTelegramIsNotCloads "Telegram is not configured." - Set parameters —
mov rcx, rbx - Log warning —
call 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
These two figures show the malware building an infection report message with system details:
Figure 1: Building the Report Header and IP Information
- Start infection report:
lea rdx, aInfectionReporloads "Infection Report:\nPublic IP: "mov rcx, r15sets destination buffercall sub_140001E10(starts building the report string)
- Add Local IP label:
lea rdx, aLocalIploads "\nLocal IP: "mov rcx, r15mov [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, raxmov rcx, r12call sub_1405B1530(processes/formats the data)
3. Continue building:
mov [rsp+708h+var_688], r12(saves pointer)mov rdx, r12mov r9, [rsp+708h+var_560](loads more data)lea r12, [rsp+708h+var_428](next buffer section)- Multiple
movinstructions loading data from stack
Figure 2: Adding Admin Status
- Load more data:
mov r8, [rsp+708h+var_508]mov rcx, rdilea rdx, [rsp+708h+var_388]
2. Call formatting function:
call sub_140001CE0(processes data)
3. Add admin status:
lea rdx, aAdminStatusloads "\nAdmin Status: "mov rcx, rdicall 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
- Call function —
call sub_140003B20(likely finalizes the report data or prepares network connection) - Log info message:
lea rdx, aInfoloads "INFO"mov rcx, rsicall sub_140001850(logs the info message)
3. Log sending attempt:
lea rdx, aAttemptingToSeloads "Attempting to send final report."mov rcx, rsicall 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
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)
- Load screenshot filename:
rdx, aScreenshotFileloads "screenshot_file"rcx, rsicall sub_140001850(logs the action)
Set image format:
rdx, aImagePngloads "image/png"rcx, rbxcall sub_140001850(logs PNG format)
Prepare screenshot data:
rdx, [rsp+708h+var_678](loads screenshot buffer/data)r9, rsiandr8, 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)
- Load send photo command:
lea rdx, aSendphotoloads "sendPhoto"mov rcx, rsicall sub_140001850(logs the action)
Set photo parameter:
lea rdx, aPhotoloads "photo"mov rcx, rbxcall sub_140001850(logs parameter)
Set image format:
lea rdx, aImagePngloads "image/png"mov rcx, rdicall 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, rdilea rcx, qword_140826200(loads transmission buffer/handle)
Purpose: The malware is:
- Capturing a screenshot of the victim’s desktop
- Saving it as PNG format
- Preparing to send it using what appears to be the Telegram Bot API (
sendPhotomethod) - 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
These two figures show the malware building status messages about the encryption process:
Figure 1: Encrypted Files Count Field
- Load data:
mov r8, rdimov [rsp+708h+var_360], r15
Add encrypted files field:
lea rdx, aNameEncryptedFloads"{ \"name\": \"Encrypted Files\", \"valu..."mov rcx, rbxmov byte ptr [rax+r15], 0(null terminates a string)call sub_1405CCF20(appends field to JSON)
Add inline formatting:
lea rdx, aInlineTrueloads"\", \"inline\": true },"mov rcx, rbx
Image 2: Encryption Complete Message
- Load character:
mov edx, r15dmov 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, r12mov [rsp+708h+var_380], rbp
Add completion message:
lea rdx, aEncryptionComploads "Encryption Complete! Files: "mov rcx, rdimov byte ptr [rax+rbp], 0(null terminate)call sub_1405CCF20(appends message)
Add HWID field:
lea rdx, aHwid_0loads"\nHWID: "mov rcx, rdi
Purpose: The malware is:
- Counting encrypted files and adding that count to the JSON webhook payload
- Generating a completion message: “Encryption Complete! Files: [count]”
- 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
These three figures show anti-analysis and persistence mechanisms in the malware:
Figure 1: Anti-Debug Check Failed (loc_140023D40)
- Log critical error:
lea rdx, aCriticalloads "CRITICAL"mov rcx, rsicall sub_140001850(logs critical level)
Anti-debug failure message:
lea rdx, aAntiDebugCheck_0loads "Anti-Debug check failed. Exiting payloa..."mov rcx, rbxcall sub_140001850(logs the failure)
Exit routine:
mov rcx, rbxcall sub_1405AE6B0(cleanup/exit function)mov rcx, rsicall sub_1405AE6B0(additional cleanup)
Figure 2: UAC Bypass Re-launch (loc_140023C88)
- Log info:
lea rdx, aInfoloads "INFO"mov rcx, rsicall sub_140001850
UAC bypass message:
lea rdx, aUacBypassReLauloads "UAC bypass re-launch attempted. Exiting..."mov rcx, rbxcall sub_140001850(logs UAC bypass attempt)
Figure 3: Payload Finished (loc_140023C09)
- Log info:
lea rdx, aInfoloads "INFO"mov rcx, rsicall sub_140001850
Completion message:
lea rdx, aBqtlockPayload_0loads "BQTLock Payload finished initial execut..."mov rcx, rbxcall sub_140001850(logs completion)
Cleanup:
mov rcx, rbxcall sub_1405AE6B0mov rcx, rsi
Purpose: These are three different exit paths for the malware:
- Anti-Debug Detection: If the malware detects it’s being debugged/analyzed, it logs a critical error and exits to avoid analysis
- UAC Bypass: The malware attempts to re-launch itself with elevated privileges via UAC bypass, then exits the original process
- 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
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)
- Unwind/exception handling setup —
_unwind { // __GSHandlerCheck - Check Python archive:
lea rcx, aPyiArchiveFileloads "_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)
- Load RBX —
mov rdx, rbx - Check Python archive again:
lea rcx, aPyiArchiveFileloads "_PYI_ARCHIVE_FILE"call sub_140008E50
Check Python application directory:
lea rcx, aPyiApplicationloads "_PYI_APPLICATION_HOME_DIR"call sub_140008E80
Check parent process:
lea rcx, aPyiParentProceloads "_PYI_PARENT_PROCESS_LEVEL"call sub_140008EB0
Check splash IPC:
lea rcx, aPyiSplashIpcloads "_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:
- 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
- Execution Environment Detection: Determines if it’s running in a sandboxed PyInstaller environment
- Secondary Payload Deployment: May indicate the malware has Python-based components it can deploy
- 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
This code is checking for PyInstaller’s strict unpack mode — another anti-analysis technique:
- Load PyInstaller environment variable:
lea rcx, aPyinstallerStrloads "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:
- Anti-Unpacking: If this variable is set, it indicates someone is trying to extract/unpack the PyInstaller bundle
- Analysis Detection: This is a strong indicator the malware is being examined by researchers
- 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
This code shows two related sections handling PyInstaller splash screen detection and unpacking failure:
Top Section: Unpack Failure Handler
- Error message: “Failed to load splash screen resources!”…
- Load error message:
lea rcx, aFailedToUnpackloads "Failed to unpack sp[lash screen]"jmp short loc_140005IDD(jumps to error handling)
Bottom Section: Splash IPC Check (loc_1400051F4)
- Load zero value:
lea rdx, a0loads "0"
Check splash IPC variable:
lea rcx, aPyiSplashIpcloads "_PYI_SPLASH_IPC"call sub_140008E50(checks/sets the environment variable)
Purpose:
This is handling PyInstaller’s splash screen functionality:
**_PYI_SPLASH_IPC** - Environment variable used for inter-process communication with PyInstaller's splash screen feature- 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
The above figures show the C2 Panel and the C2 downloading an executable


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:
- /BQT.exe — Distributes the ransomware binary to new victims
- /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
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:
- UAC Bypass via EventViewer — Uses eventvwr.exe to bypass UAC (2 days ago)
- References SecTools — Contains many IR and analysis tools references
- Telegram ChatBot — Has Telegram bot functionality for C2 communications
Figure 2: Advanced Behavioral Detections
Sophisticated TTPs (Tactics, Techniques, Procedures):
- DNS Query for IP Lookup APIs — Queries api.ipify.org from non-browser process (getting victim’s public IP)
- Admin Group Addition — Adds users to local administrator group (privilege escalation)
- Registry Desktop Background Change — Modifies desktop wallpaper (typical ransomware ransom note display)
- Telegram API Communication — Non-browser process contacting Telegram API (covert C2)
- IP Lookup Service API — External IP lookups via api.ipify.org (reconnaissance)
- Telegram Bot API Request — Suspicious DNS queries to api.telegram.org (exfiltration channel)
- LNK Double Extension — Creates suspicious shortcut files (persistence/execution trick)
Figure 3: Persistence & Privilege Escalation
Advanced Malicious Behaviors:
- PowerShell Module Creation — Non-PowerShell process creating .psm1/.psd1 modules (fileless malware techniques)
- Scheduled Task with High Privileges — Creates schtasks with elevated privileges (persistence)
- Non-Interactive PowerShell — Spawns PowerShell without GUI via explorer.exe (stealth execution)
- Security Group Manipulation — Removes members from security-enabled groups (defense evasion)
- Schtasks.exe via User Account — Creates scheduled tasks (persistence mechanism)
- Local User Creation — Creates local Windows users (shouldn’t happen in Active Directory — creates backdoor accounts)
- Security Group Addition — Adds members to security groups (privilege escalation)
Figure 4: Network-Based Detections
Network Threat Intelligence:
- ET HUNTING PNG in HTTP POST — Network trojan detected (data exfiltration via image files)
- Policy Violation — HTTP request by IPv4 address (suspicious non-domain traffic)
- IP Check Domain — Contacts icanhazip.com (gets external IP — common malware reconnaissance)
- External IP Lookup — DNS lookup for icanhazip.com (device retrieving external IP address)
- HTTP Header Manipulation — Unusual Content-Transfer-Encoding used
- 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
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:
- A PyInstaller-packaged executable — Confirms the malware uses PyInstaller for packaging
- 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
The above figure shows at what address was Remcos Detected


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:
- System Reconnaissance ✓ (IP gathering, OS detection)
- Credential Theft ✓ (Attempting to steal browser passwords from Opera, likely also Chrome/Firefox/Edge)
- File Encryption ✓ (Encrypting files with .bqtlock extension)
- Data Exfiltration ✓ (Sending stolen data via Telegram/Discord webhooks)
- 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
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
- Webhook ID: 1422999331195191336
- Webhook Token: 5dWTzBL9FybdjuW3RqPqmUD7f72DDEsMYGnZLLYZwU5XwXo0dcgnudaIV25fElMlbpDS
- Full URL:
[https://discord.com/api/webhooks/1422999331195191336/5dWTzBL9FybdjuW3RqPqmUD7f72DDEsMYGnZLLYZwU5XwXo0dcgnudaIV25fElMlbpDS](https://discord.com/api/webhooks/1422999331195191336/5dWTzBL9FybdjuW3RqPqmUD7f72DDEsMYGnZLLYZwU5XwXo0dcgnudaIV25fElMlbpDS)
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:
- IOCs (Indicators of Compromise):
- Block all traffic to
api.telegram.orgwith 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