Skip to main content

Tryhackme

Squid Game

Disclaimer

I am nowhere near a professional malware analyst, I am doing this for fun. There are for sure better methods, but this is how I did it. Also remember that this is just a walk through to answer the questions from the challenge and not a full malware analysis.

I tried to create this walk through in a way that still needs some interaction and thinking from the reader. Not all answers a provided in a Question?:Answer scheme :)
Thanks THM for this room!

TryHackMe | Squid Game
오징어 게임

Attacker 1

Hashes

Sha256: 2979b5fbb454e2f13d89e58177f8c1f881bd3f0a0bebb1d27da9e189ba9d284e
MD5: 4443840f2870c2cd55062bdcab07e5fd

Analysis

For maldocs I can highly recommend the tools from Didier Stevens which can be found here. The documentation is in the file itself. (oledump.py). Along with oledump I use this from decalage2.

They are already on the THM machine though!

oledump.py attacker1.doc 
Initial oledump output for attacker1

Lets check out the stream which contains the macro (indicated by "M"):

oledump.py attacker1.doc -s <stream> -S -v
Flag Purpose
-s indicating the stream we want to dump
-S dumps the strings
-v decompress the VBA macro sourcecode

The dump shows a lot of string and character manipulation, but there is one specific block that stands out:

VBA.Shell# "CmD /C " + Trim(rjvFRbqzLtkzn) + SKKdjMpgJRQRK + Trim(Replace(pNHbvwXpnbZvS.AlternativeText + "", "[", "A")) + hdNxDVBxCTqQTpB + RJzJQGRzrc + CWflqnrJbKVBj, CInt(351 * 2 + -702)
lFbSwGcXvLj = ZcCmWkkqqB + CBool(3868) + Len(ChrW(10 + 10) + ChrW(7)) + LenB(Trim("GpsfXGHdXPiPBQWm")) + Len(CxtsBzHdKBGmb)
gQVFVamfZLZ = GgRgBdCqvLXk + CBool(260) + Len(ChrW(4 + 5) + ChrW(3)) + LenB(Trim("pSdvPiVsNHZWVbr")) + Len(ZxkaZVpVviNG)

macro output

This is an attempt to use the 'Shell' function to execute a command. There also seems to be a replacement of characters taking place.

Timestamps can be checked with oletimes.

Now lets dump the other streams"

oledump.py attacker1.doc -s <stream> -S

The subject can be found in stream 3 as well as in stream 4 together with the phone number.

Stream 4 also contains something very interesting:

attacker1, stream4 ps command

Followed by what looks like a base 64 string with some "[", which we saw earlier are replacing "A". So lets throw this into cyberchef with this recipe

decoded base64 string

This is where the IP, C2, folder, executable and COM object can be found.

The $path variable contains the folder, but it is not the correct name. Google will tell you. Do not forget the "%" before answering.
The COM object is identified by a GUID.

Attacker 2

Hashes

SHA256: 22fe1b36efa9cb3a8f1e71c1d6730d360977fad6923dcf9cb8a313a975b8aac7
MD5: e599a656599a2680c9392c7329d9d519

Analysis

First lets see what is going on with attacker2.doc:

oledump.py attacker2.doc
oledump output for attacker2

When entering the numbers, add a whitespace behind the comma. This made me nearly question my whole life xD

To find the bytes of the compiled code we can use the -i flag:

oledump.py -i attacker2.doc

oledump.py documentation: "the size of the compiled code (left of the + sign) and the size of de source code (right of the + sign)"

The total bytes can be found in the 3rd column.

For the next questions, we will use olevba.

olevba attacker2.doc | grep fun

This returns the command from the fun field, but you have to reverse it. If you use python, remember to escape the backslashes.

Then run the command again. At the bottom of the output you will see a summary, but for a better overview I recommend scrolling up to the output from stream 9:

attacker2 olevba output

This part of the olevba output should answer the remaining questions.

Attacker 3

Hashes

SHA256: b156c9ad046d0d4b174f7308bd3b965f4425b1dfa38e7dc19e6e1eb54b0b49a1
MD5: 30511605bee5a35ff80fde0de0105bd4

Analysis

oledump.py attacker3.doc
oledump attacker3

Going straight to olevba, we can see that this one is very small.

The most interesting things happen in VBA/T and VBA/d.

In VBA/T we can see an obfuscated string that gets passed into some kind of function, probably a custom deobfuscator. The output is then saved in a variable. Also a new WshShell object being created which does two things:

  • It copies an executable from the System32 folder to the ProgramData folder under a different name
  • It executes the contents from the previously deobfuscated string

In VBA/d the custom deobfuscation function is declared. We only need to split the character codes at the "%" and XOR them with 111. Good ole Shakespeare had a python script to share that helps:

obfu = input("Good morrow to thee, kind sir. Pray, might I entreat thee to bestow upon me the boon of thy counsel?\n")
out = ''
obfu = obfu.split("%")
for i in obfu:
	out += str(chr(int(i)^111))
print("Parting is such sweet sorrow, that I shall say good night till it be morrow.\n")

print(out)

Deobfuscating this string reveals a command that:

  • a file is downloaded and saved under a different name
  • the downloaded file is registered as a DLL with regsvr32 (look)
  • the downloaded file is than executed with the previously copied file from System32

This should allow you to answer all the questions

Attacker 4

Hashes

SHA256: d61aa6195a2da022d16af3694050b51e29bc7ef7a6f3ad735c3a20f81891b601
MD5: 41c4dd8ed6597723155aae653ad6a1e8

Analysis

oledump.py attacker4.doc
oledump attacker4

This does not look to bad, does it?

olevba attacker4.doc

Well...two snippets:

attacker4 obfuscated macro code
attacker4 obfuscated macro code

BUT! There is a nifty tool to analyze obfuscated maldocs:

ViperMonkey

Which is also installed on the box from THM.

vmonkey attacker4.doc

The -s flag can also be used for speedup, you can read about it in the docs. I did not use it for this analysis.

To decode the strings from the maldoc you can:

olevba | grep -i xori

The parameters of the XORI functions are as follows:

XORI(<value>, <key>)

You can use this cyberchef recipe to decode the values.

From the "Recorded Actions" output of vmonkey, the remaining questions can be answered.

Attacker 5

Hashes

SHA256: 55c9ff8f829bf0d5bbec83127570ad149bd18bc0351c59933090af917b4451db
MD5: 4ac3d0835c1650e2ec73c8607d55ed1d

Analysis

oledump.py attacker5.doc
oledump output attacker5
olevba attacker.doc
attacker5 shellobject executing powershell with params

The line following "AutoOpen()" runs powershell with the "-hidden" and "-encoded" flags. The latter
means that the string which gets concatenated (& operator) probably is a base64 encoded string.
Since there was nothing interesting in the output of olevba, we'll switch to oledump and go through the streams.

oledump.py attacker5.doc -S -s <stream>

In stream 6 we find the caption and in stream 7 the base64 string.

Decoding the first string in cyberchef, there is another base64 string. It is always important to further read what happens next with that string. In this case the string is base64 decoded and then gzip decompressed, before it is passed into the invoke expression function:

running the "gunzipped" code

For this string we need base64 decoding and "gunzip". This results in another powershell script:

decoding and xor'ing the byte array

Another base64 string, this one is decoded and saved to a byte array, which is then bitwise-xored byte by byte. Further down in the script, memory is being allocated and the xored bytes are copied into the allocated memory, which can indicate a shellcode injection.

Lets create a python script that does exactly the same.Decode, XOR and write the bytes into a binary, as well as printing the the decoded bytes for some quick views.

import base64


bstring = "<b64 string here>"

decoded_bytes = base64.b64decode(bstring)
xor_bytes = bytearray(b ^ 35 for b in decoded_bytes)
with open('shcode.bin', 'wb') as f:
	f.write(xor_bytes)
out = xor_bytes.decode('utf-8', errors='replace')
print(out)

With some research about the windows api, the next command can answer the remaining questions.

speakeasy -t shcode.bin -r -a x86
Flag Purpose
-t target
-r display a report upon completion
-a x86 specifies the architecture to emulate
connecting to an IP and :)

For a more clear and structured output, you can use scdbg:

scdbg -f shcode.bin -s -1
Flag Purpose
-f the file to use
-s the steps to go through, -1 for infinite

scdbg needs some startup time on the THM box. On the interface tick the "unlimited steps" box

This should leave you with all the questions answered :)