Flash CTF – Email From Krampus

Enumeration

We are supplied 2 files: powershell.DMP and challenge.pcap

Since we are provided with the powershell process minidump, we will first find the powershell scripts that are being run in a number of ways: Using power_dump to retrieve the powershell script blocks and variables from memory or simply using strings and skimming for suspicious code.

I will use power_dump to dump the script blocks:

alt text

By this way we can restore all suspicious scripts, which looks like a ransomware.

Ransomware analyst

1. Encryption Functionality

Function Invoke-AESEncryption:

  • Utilizes AES in CBC mode with PKCS7 padding.
  • Hashes the provided encryption key using SHA-256 to derive the 256-bit AES key.
  • Encrypts either plain text or file content, including the file’s initialization vector (IV) at the start of the encrypted data.

=> This function is used to encrypt a file, making it inaccessible without the encryption key.

2. File Operations

Harvesting Files:

  • Moves files from a source directory (C:\Users\longnte\Documents) to a destination (C:\Users\longnte\Desktop\harvest), filtering for specific file types: .txt, .pdf, .xlsx, .docx, .png, .jpg, .jpeg, .rar.
  • Uses robocopy to handle file operations efficiently.

Compression and Encryption:

  • Compresses the harvested files into a .zip archive using 7-Zip (7z.exe).
  • Protects the archive with a random password generated via System.Web.Security.Membership::GeneratePassword.
  • Encrypts the .zip file using Invoke-AESEncryption with a randomly generated 24-character key. ($ins8012h = -join ( (48..57) + (65..90) + (97..122) | Get-Random -Count 24 | % {[char]$_}))

3. Exfiltration

Email Setup:

  • Configures an SMTP client to send the encrypted file via email:
  • SMTP server: mail.metactf.com
  • Sender email: kietbl@metactf.com
  • Receiver email: hungtmc@metactf.com
  • Subject includes a timestamp of when the script was run.

Attachment and Delivery:

  • Attaches the encrypted .zip file (harvest.zip.enc) to the email.
  • Sends the email with the encrypted file as an attachment.
  • Deletes both the original zip and the encrypted file after the email is sent.

4. User Interaction

MessageBox Ransom Note displays a GUI message box via System.Windows.Forms to the victim with a ransom demand:

  • States that “Krampus” has taken the victim’s files.
  • Requests a ransom payment of 2,500 “SantaCoins”
  • Threatens further consequences if the victim does not comply.

Blocking User Input:

  • Uses BlockInput API to temporarily block user interaction with the computer during critical operations, making it harder to interrupt the script.

Solution

Once you understand the full functionality of ransomware, you can follow these steps to get the data back:

  1. Using wireshark to filter packets with SMTP protocol and extract havest.zip.enc attachment from email
alt text

Next, take all the attachment content, decode base64 and save it with the name harvest.zip.enc

  1. Using regex to search for 24 bytes long encryption key in powershell minidump file
$ strings -el powershell.DMP | grep -E "^[a-zA-Z0-9]{24}$" | sort | uniq
1NyEcYfKLvdTR2e5ktPUS9CD
AccessibleActionCollapse
AddPropertyValueAtAction
AesCryptoServiceProvider
AllCentralAccessPolicies
AllocateAndInitializeSid
AllowASTAToASTACallChain
AllowConsentToStealFocus
AllowLogonPhonebookEdits
AllowSearchToUseLocation
AlreadyPresentInTypesXml
AppContainerNamedObjects
AppContainerUserCertRead
AppDomainIsBeingUnloaded
ApplicationFileThumbnail
ApplicationSearchHistory
........................

Luckily the key is right at the top after being sorted => 1NyEcYfKLvdTR2e5ktPUS9CD

  1. Decrypt havest.zip.enc with the key found above
import os
import hashlib
from Crypto.Cipher import AES

def process_file(file_path):
    with open(file_path, 'rb') as file:
        data = file.read()
    # AES key
    key = hashlib.sha256(b'1NyEcYfKLvdTR2e5ktPUS9CD').digest()
    # Extract IV and encrypted data
    iv = data[:16]
    encrypted_data = data[16:]
    
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted_data = cipher.decrypt(encrypted_data)
    padding_length = decrypted_data[-1]
    decrypted_data = decrypted_data[:-padding_length]
    
    return decrypted_data

file_to_decrypt = 'harvest.zip.enc'
if os.path.exists(file_to_decrypt):
    decrypted_data = process_file(file_to_decrypt)
    
    output_file = file_to_decrypt.replace('.enc', '')
    
    with open(output_file, 'wb') as file:
        file.write(decrypted_data)

Now we have havest.zip but it is protected with password, so we need to find the password.

alt text
  1. Search for the compress harvested folder command to get the archive file password or continue using regex as we did to get the key
$ strings -el powershell.DMP | grep "a -tzip"
$arguments = "a -tzip ""$Destination"" ""$Destination"" -mx9 -p$randomPassword"
a -tzip "$Destination" "$Destination" -mx9 -p$randomPassword
a -tzip "{0}" "{1}" -mx9 -p{2}
a -tzip "C:\Users\longnte\Desktop\harvest" "C:\Users\longnte\Desktop\harvest" -mx9 -pmBJ/m(aC
a -tzip "C:\Users\longnte\Desktop\harvest" "C:\Users\longnte\Desktop\harvest" -mx9 -pmBJ/m(aC
$arguments = "a -tzip ""$Destination"" ""$Destination"" -mx9 -p$randomPassword"
a -tzip "C:\Users\longnte\Desktop\harvest" "C:\Users\longnte\Desktop\harvest" -mx9 -pmBJ/m(aC
a -tzip "C:\Users\longnte\Desktop\harvest" "C:\Users\longnte\Desktop\harvest" -mx9 -pmBJ/m(aC
.........................

=> The password for the havest.zip file is mBJ/m(aC

  1. Extract the archive with the found password to get the flag from QR code
alt text