Mayor Malware was scheming, quite full of delight,
To ruin SOC-mas and frighten SOC teams.
But Glitch and McSkidy had spoiled his plan,
By uncovering secrets that exposed the man!
Mayor Malware was scheming, quite full of delight,
To ruin SOC-mas and frighten SOC teams.
But Glitch and McSkidy had spoiled his plan,
By uncovering secrets that exposed the man!
Mayor Malware slammed his hand on the table, his eyes narrowing as the report flashed on his screen. Glitch and McSkidy had uncovered his trail. He took a deep breath, calming himself. "No matter," he muttered, a sinister grin forming. "They may have found me but haven't stopped me." His confidence stemmed from the malware he had crafted—so devious and advanced that it would easily evade detection.
But before unleashing it to wreak havoc on SOC teams and ruin SOC-mas, there was one final step. He needed to test it in a sandbox.
Sandbox adalah lingkungan terisolasi tempat kode (jahat) dijalankan tanpa memengaruhi apa pun di luar sistem. Sering kali, beberapa alat dipasang untuk memantau, merekam, dan menganalisis perilaku kode.
Sebelum malware-nya dijalankan, malware tersebut perlu memeriksa apakah ia berjalan di lingkungan Sandbox. Jika ya, malware tersebut tidak boleh melanjutkan aktivitas jahatnya.
Untuk melakukannya, telah ditetapkan satu teknik, yang memeriksa apakah direktori C:\Program Files ada?. Hal ini dilakukan dengan cara menanyakan jalur Registry HKLM\\Software\\Microsoft\\Windows\\CurrentVersion.
Direktori ini sering kali tidak ada pada sandbox atau lingkungan virtual lainnya, yang dapat mengindikasikan bahwa malware berjalan di sandbox.
void registryCheck() {
const char *registryPath = "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion";
const char *valueName = "ProgramFilesDir";
// Prepare the command string for reg.exe
char command[512];
snprintf(command, sizeof(command), "reg query \"%s\" /v %s", registryPath, valueName);
// Run the command
int result = system(command);
// Check for successful execution
if (result == 0) {
printf("Registry query executed successfully.\n");
} else {
fprintf(stderr, "Failed to execute registry query.\n");
}
}
int main() {
const char *flag = "[REDACTED]";
registryCheck();
return 0;
}
Versi bahasa pemograman C
Fungsi ini dirancang untuk memeriksa registry sistem untuk jalur direktori tertentu (ProgramFilesDir). Ada atau tidaknya jalur ini membantu malware menentukan apakah dirinya berjalan di lingkungan biasa atau virtual, seperti sandbox.
YARA adalah alat yang digunakan untuk mengidentifikasi dan mengklasifikasikan malware berdasarkan pola dalam kodenya. Dengan menulis aturan khusus, analis dapat menentukan karakteristik tertentu yang harus dicari—seperti string tertentu, files header, atau behaviours/perilaku - dan YARA akan scan files atau process untuk menemukan kecocokan, sehingga sangat berguna untuk mendeteksi kode berbahaya.
Untuk melakukannya, akan dibuat Script yang menjalankan aturan deteksi YARA setiap kali peristiwa baru ditambahkan ke System Monitoring Log. Aturan YARA khusus ini mendeteksi perintah apa pun yang mencoba mengakses registry.
rule SANDBOXDETECTED
{
meta:
description = "Detects the sandbox by querying the registry key for Program Path"
author = "TryHackMe"
date = "2024-10-08"
version = "1.1"
strings:
$cmd= "Software\\Microsoft\\Windows\\CurrentVersion\" /v ProgramFilesDir" nocase
condition:
$cmd
}
Penjelasan:
Nama rule ini adalah SANDBOXDETECTED, yang menunjukkan bahwa tujuannya adalah mendeteksi keberadaan sandbox.
strings mendefinisikan string atau pola yang akan dicari. Dalam hal ini: $cmd. Dan String yang ingin dicocokkan, yaitu Software\Microsoft\Windows\CurrentVersion\" /v ProgramFilesDir. String ini menunjukkan sebuah query ke registry Windows untuk membaca nilai dari key ProgramFilesDir dalam CurrentVersion.
nocase: membuat pencocokan string bersifat case-insensitive (tidak membedakan huruf besar/kecil).
condition: Kondisi ini akan terpenuhi jika string $cmd ditemukan dalam file atau proses yang sedang dianalisis.
Untuk pengujiannya, dibuat script yang menjalankan Yara rule & mencatat true positive di C:\Tools\YaraMatches.txt
Script JingleBells.ps1
# Define the YARA rule path
$yaraRulePath = "C:\Tools\YARARULES\CheckRegCommand.yar"
# Define the path to the YARA executable
$yaraExecutable = "C:\ProgramData\chocolatey\lib\yara\tools\yara64.exe"
$logFilePath = "C:\Tools\YaraMatches.txt"
# Function to log event data to a file
function Log-EventDataToFile {
param (
[string]$commandLine,
[string]$yaraResult,
[string]$eventId,
[string]$eventTimeCreated,
[string]$eventRecordID
)
# Prepare log entry
$logEntry = "Event Time: $eventTimeCreated`r`nEvent ID: $eventId`r`nEvent Record ID: $eventRecordID`r`nCommand Line: $commandLine`r`nYARA Result: $yaraResult`r`n"
$logEntry += "--------------------------------------`r`n"
# Debugging output to ensure logging function is called
Write-Host "Logging to file: $logFilePath"
Write-Host $logEntry
# Append the log entry to the file
Add-Content -Path $logFilePath -Value $logEntry
}
# Function to run YARA on the command line and log result only if a match is found
function Run-YaraRule {
param (
[string]$commandLine,
[string]$eventId,
[string]$eventTimeCreated,
[string]$eventRecordId
)
# Create a temporary file to store the command line for YARA processing
$tempFile = [System.IO.Path]::GetTempFileName()
try {
# Write the command line to the temporary file
Set-Content -Path $tempFile -Value $commandLine
# Run YARA on the temporary file
$result = & $yaraExecutable $yaraRulePath $tempFile
# Only log if YARA finds a match (non-empty result)
if ($result) {
#Write-Host "YARA Match Found for Command Line: $commandLine"
Write-Host "YARA Result: $result"
# Log the event data to a file in C:\Tools
Log-EventDataToFile -commandLine $commandLine -yaraResult $result -eventId $eventId -eventTimeCreated $eventTimeCreated -eventRecordID $eventRecordId
# Display warning
$warning = "Malicious command detected!THM{GlitchWasHere}"
Show-MessageBox -Message $warning
}
} finally {
# Clean up the temporary file after processing
Remove-Item -Path $tempFile -Force
}
}
# Function to display Popup
Add-Type -AssemblyName System.Windows.Forms
function Show-MessageBox {
param (
[string]$Message,
[string]$Title = "Notification"
)
# Start a new PowerShell job that runs asynchronously and doesn't block the main flow
Start-Job -ScriptBlock {
param($msg, $ttl)
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show($msg, $ttl)
} -ArgumentList $Message, $Title
}
# Function to handle Sysmon events
function Handle-SysmonEvent {
param (
[System.Diagnostics.Eventing.Reader.EventLogRecord]$event
)
#write-host "handling event"
# Extract Event ID, time created, and relevant properties
$eventID = $event.Id
$eventRecordID = $event.RecordId
$eventTimeCreated = $event.TimeCreated
$commandLine = $null
#write-host "Current event record id: " $event.RecordId
#write-host "Last event record id: " $lastRecordId
if ($eventID -eq 1 -and ($event.Properties[4] -notcontains "C:\ProgramData\chocolatey\lib\yara\tools\yara64.exe") ) {
# Event ID 1: Process Creation
$commandLine = $event.Properties[10].Value # Get the command line used to start the process
#write-host $commandLine
if ($commandLine) {
Run-YaraRule -commandLine $commandLine -eventId $eventID -eventTimeCreated $eventTimeCreated -eventRecordId $eventRecordID
}
}
}
# Poll for new events in the Sysmon log
$logName = "Microsoft-Windows-Sysmon/Operational"
wevtutil cl "Microsoft-Windows-Sysmon/Operational"
# Initialize lastRecordId safely
$lastRecordId = $null
[int[]]$processedEventIds=1
try {
$lastEvent = Get-WinEvent -LogName $logName -MaxEvents 1
if ($lastEvent) {
$lastRecordId = $lastEvent.RecordId
} else {
Write-Host "No events found in Sysmon log."
}
} catch {
Write-Host "Error retrieving last record ID: $_"
exit
}
Write-Host "Monitoring Sysmon events... Press Ctrl+C to exit."
while ($true) {
try {
# Get new events after the last recorded ID
$processedEventIds= $processedEventIds|Sort-Object
#write-host $processedEventIds
$lastRecordId=$processedEventIds[-1]
#write-host $lastRecordId
$newEvents = Get-WinEvent -LogName $logName | Where-Object { $_.RecordId -gt $lastRecordId }
#write-host $newEvents.Count
if ($newEvents.Count -eq 0) {
Write-Host "No new events found."
} else {
foreach ($event in $newEvents) {
# Check if this event ID has already been processed
if ($event.RecordId -in $processedEventId ) {
Write-Host "Record ID $($event.RecordId) has already been processed"
} else {
# Process only new events
Handle-SysmonEvent -event $event
# Add the event ID to the processed set
$processedEventIds+=$event.RecordId
#write-host "processed events: " $processedEventIds
}
# Update the last processed event ID
}
}
} catch {
Write-Host "Log is empty"
}
# Sleep for 5 seconds before checking again
Start-Sleep -Seconds 2
}
Script ini akan menjalankan EDR pada sistem dan terus memantau Event Log yang dihasilkan serta akan memberi tahu jika menemukan aktivitas/peristiwa yang menunjukkan Registry Key yang disebutkan sebelumnya. Hasilnya akan seperti gambar dibawah ini:
Teknik Evasion
Jika sebelumnya terdeteksi oleh Yara maka menggunakan teknik Obfuscation dapat menyembunyikan query yang di encode menggunakan base64 dan menggunakan Powershell untuk execute query tersebut. Jika ingin melihat isi dari string yang di encode, kita dapat melakukan decode untuk melihat query yang disembunyikan. Seperti pada gambar dibawah.
Encoded Version
void registryCheck() {
// Encoded PowerShell command to query the registry
const char *encodedCommand = "RwBlAHQALQBJAHQAZQBtAFAAcgBvAHAAZQByAHQAeQAgAC0AUABhAHQAaAAgACIASABLAEwATQA6AFwAUwBvAGYAdAB3AGEAcgBlAFwATQBpAGMAcgBvAHMAbwBmAHQAXABXAGkAbgBkAG8AdwBzAFwAQwB1AHIAcgBlAG4AdABWAGUAcgBzAGkAbwBuACIAIAAtAE4AYQBtAGUAIABQAHIAbwBnAHIAYQBtAEYAaQBsAGUAcwBEAGkAcgA=";
// Prepare the PowerShell execution command
char command[512];
snprintf(command, sizeof(command), "powershell -EncodedCommand %s", encodedCommand);
// Run the command
int result = system(command);
// Check for successful execution
if (result == 0) {
printf("Registry query executed successfully.\n");
} else {
fprintf(stderr, "Failed to execute registry query.\n");
}
}
Disini saya mencoba menggunakan powershell untuk melakukan decode. Selain itu bisa menggunakan tools online yang tersedia banyak diinternet.
Floss
Meskipun obfuscation itu membantu, terdapat alat yang tersedia yang mengekstrak obfuscated string dari malware binaries. Salah satu alat tersebut adalah FLOSS (FireEye Labs Obfuscated String Solver), alat canggih yang dikembangkan oleh Mandiant yang berfungsi mirip dengan tool string Linux tetapi dioptimalkan untuk analisis malware, sehingga ideal untuk mengungkap detail tersembunyi apa pun.
FLOSS akan digunakan untuk mengekstrak string tersembunyi atau terobfusikasi dari malware bernama MerryChristmas.exe, yang terletak di direktori C:\Tools\Malware. Output dari analisis ini, yaitu daftar string yang diekstrak, kemudian diarahkan (redirected) menggunakan operator |Out-File ke file C:\tools\malstrings.txt, sehingga hasilnya disimpan dalam file teks untuk di analisis, seperti menganalisis pola, indikasi perilaku, atau petunjuk lain yang relevan terkait dengan malware tersebut.
YARA Rules juga dapat digunakan untuk memeriksa log Sysmon untuk mencari artefak yang ditinggalkan oleh malware.
Sysmon adalah alat dari Microsoft Sysinternals Suite yang secara terus-menerus memantau dan mencatat aktivitas sistem, bahkan setelah komputer di-reboot. Layanan Windows ini memberikan data peristiwa yang mendetail terkait pembuatan proses, koneksi jaringan, dan perubahan file, yang sangat berguna dalam melacak perilaku malware.
YARA rules akan mencari peristiwa dengan Event ID 1: Process Created agar dapat berfungsi. Karena terdapat banyak entri di log Sysmon, untuk mempermudah pencarian event yang dibutuhkan, akan digunakan filter khusus menggunakan EventRecordID. ID tersebut dapat ditemukan di log YaraMatches.txt dengan menjalankan command di powershell get-content C:\Tools\YaraMatches.txt
Berikutnya, akan dilihat menggunakan Event Viewer pada path Applications and Services Logs -> Microsoft -> Windows -> Sysmon -> Operational . Filter akan dibuat menggunakan query XML