Flare-On 7 2020 Challenge #4: report

When I tried to open the report.xls file I received an error:

After pressing the “OK” button we received the Visual Basic code:

Private Declare Function InternetGetConnectedState Lib "wininet.dll" _
(ByRef dwflags As Long, ByVal dwReserved As Long) As Long
Private Declare PtrSafe Function mciSendString Lib "winmm.dll" Alias _
"mciSendStringA" (ByVal lpstrCommand As String, ByVal _
lpstrReturnString As Any, ByVal uReturnLength As Long, ByVal _
hwndCallback As Long) As Long
Private Declare Function GetShortPathName Lib "kernel32" Alias "GetShortPathNameA" _
(ByVal lpszLongPath As String, ByVal lpszShortPath As String, ByVal lBuffer As Long) As Long
Public Function GetInternetConnectedState() As Boolean
GetInternetConnectedState = InternetGetConnectedState(0&, 0&)
End Function
Function rigmarole(es As String) As String
Dim furphy As String
Dim c As Integer
Dim s As String
Dim cc As Integer
furphy = ""
For i = 1 To Len(es) Step 4
c = CDec("&H" & Mid(es, i, 2))
s = CDec("&H" & Mid(es, i + 2, 2))
cc = c - s
furphy = furphy + Chr(cc)
Next i
rigmarole = furphy
End Function
Function folderol()
Dim wabbit() As Byte
Dim fn As Integer: fn = FreeFile
Dim onzo() As String
Dim mf As String
Dim xertz As Variant

onzo = Split(F.L, ".")

If GetInternetConnectedState = False Then
MsgBox "Cannot establish Internet connection.", vbCritical, "Error"
End
End If
Set fudgel = GetObject(rigmarole(onzo(7)))
Set twattling = fudgel.ExecQuery(rigmarole(onzo(8)), , 48)
For Each p In twattling
Dim pos As Integer
pos = InStr(LCase(p.Name), "vmw") + InStr(LCase(p.Name), "vmt") + InStr(LCase(p.Name), rigmarole(onzo(9)))
If pos > 0 Then
MsgBox rigmarole(onzo(4)), vbCritical, rigmarole(onzo(6))
End
End If
Next

xertz = Array(&H11, &H22, &H33, &H44, &H55, &H66, &H77, &H88, &H99, &HAA, &HBB, &HCC, &HDD, &HEE)
wabbit = canoodle(F.T.Text, 0, 168667, xertz)
mf = Environ(rigmarole(onzo(0))) & rigmarole(onzo(1))
Open mf For Binary Lock Read Write As #fn
Put #fn, , wabbit
Close #fn

mucolerd = mciSendString(rigmarole(onzo(2)) & mf, 0&, 0, 0)
End Function
Function canoodle(panjandrum As String, ardylo As Integer, s As Long, bibble As Variant) As Byte()
Dim quean As Long
Dim cattywampus As Long
Dim kerfuffle() As Byte
ReDim kerfuffle(s)
quean = 0
For cattywampus = 1 To Len(panjandrum) Step 4
kerfuffle(quean) = CByte("&H" & Mid(panjandrum, cattywampus + ardylo, 2)) Xor bibble(quean Mod (UBound(bibble) + 1))
quean = quean + 1
If quean = UBound(kerfuffle) Then
Exit For
End If
Next cattywampus
canoodle = kerfuffle
End Function

We also have something that looks like a key and encrypted message:

Double click on of them shows there function name:

I extracted them to two files in GitHub because of their size:

  1. F.L
  2. F.T

Analyzing the Visual Basic Code

It’s time to understand what the code is doing. The main function is folderol:

It starts by splitting F.L to the array called onzo. Later there are number of calls to rigmarole function with onzo[<nub>] while <num> is being changed. It’s a decoded function, so I converted the code (the interesting parts) to Python code to be able to print some of its variables and understand them. For example, I used it to print all the decoded variables of onzo:

onzo[0]: AppData
onzo[1]: \Microsoft\stomp.mp3
onzo[2]: play
onzo[3]: FLARE-ON
onzo[4]: Sorry, this machine is not supported.
onzo[5]: FLARE-ON
onzo[6]: Error
onzo[7]: winmgmts:\\.\root\CIMV2
onzo[8]: SELECT Name FROM Win32_Process
onzo[9]: vbox
onzo[10]: WScript.Network
onzo[11]: \Microsoft\v.png

Use them as a menu and the code is much more clear. The code is using WMI service to search for vmware process (“vmw” and “vmt”):

Then it writes something to file named “stomp.mp3” (onzo(1)):

Notice that it uses the encrypted text of F.T.Text with the function canoodle which decrypts it.

This is our converted code to Python and it wrote the mp3 file:

with open(r'C:\tmp\flare2020\4\hex_T.txt', 'r') as f:
lines_t = f.read()

with open(r'C:\tmp\flare2020\4\hex_L.txt', 'r') as f:
lines_l = f.read()


def mid(s, offset, amount):
return s[offset:offset+amount]

def rigmarole(es):
furphy = ''

for i in range(0, len(es), 4):
c = int(mid(es, i, 2), 16)
s = int(mid(es, i+2, 2), 16)
cc = c - s
furphy = furphy + chr(cc)

return furphy


def canoodle(panjandrum, ardylo, s, bibble):
kerfuffle = [None]*s
quean = 0
for cattywampus in range(0, len(panjandrum), 4):
a = int(mid(panjandrum, cattywampus + ardylo, 2), 16)
b = bibble[quean % (len(bibble))]

result = a ^ b
kerfuffle[quean] = result
quean += 1
if quean == len(kerfuffle):
break

return
kerfuffle

onzo = lines_l.split(".")
fudgel = rigmarole(onzo[7])


xertz = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]
mp3 = canoodle(lines_t, 0, 168667, xertz)

with open(r'C:\tmp\flare2020\4\stomp2.mp3', 'wb') as f:
f.write(bytes(mp3))

MP3 file

When I played the MP3 file, it played some music, like mini march but that it. I thought maybe this is steganography but look the hint I saw when I played it:

It says something about P. Code.

P-Code

According to Wikipedia, P-Code is:

P-Code is a name for several of Microsoft’s proprietary intermediate languages.

So, I guess we need to see the P-Code of the visual basic code, maybe there is something hiding there.

I found a cool tool that decompile the code:

After installing and running the tool on the report.xls file, it decompiled it and you can view all the decompiled file here.

Finding hiding commands

I followed the code to see if there is something different from the visual basic code we saw in the beginning and I found new commands.

At line #55 I noticed to a new variable called firkin and how it assigns it the name “FLARE-ON”:

Line #55:
Ld firkin
LitDI2 0x0003
ArgsLd onzo 0x0001
ArgsLd rigmarole 0x0001
Ne
IfBlock
// firkin = rigmarole(onzo(3)) // 3 - "FLARE-ON"

At line #60 it calculates it length:

Line #60:
Ld firkin
FnLen
St n
// n = Len(firkin)

At lines #61-#63, there is a loop that reverse the string “FLARE-ON” to “NO-ERALF”:

Line #61:
StartForVariable
Ld i
EndForVariable
LitDI2 0x0001
Ld n
For
Line #62:
Ld firkin
Ld i
LitDI2 0x0001
ArgsLd Mid$ 0x0003
ArgsLd Asc 0x0001
Ld n
Ld i
Sub
ArgsSt buff 0x0001
Line #63:
StartForVariable
Next
for i = 1 To n
buff(n-i) = Asc(Mid(firkin,i,1))
# Print it the opposite:
"NO-ERALF"

The last piece is at line #65 when there is a call to canoodle but with different arguments we saw in the beginning:

Line #65:
Ld F
MemLd T
MemLd Text
LitDI2 0x0002
LitDI4 0x5C21 0x0004
Ld buff
ArgsLd canoodle 0x0004
St wabbit
canoodle(F.T.Text, 2, 0x45C21, buff)

We re-wrote the Python script with these new details:

with open(r'C:\tmp\flare2020\4\hex_T.txt', 'r') as f:
lines_t = f.read()

with open(r'C:\tmp\flare2020\4\hex_L.txt', 'r') as f:
lines_l = f.read()


def mid(s, offset, amount):
return s[offset:offset+amount]

def rigmarole(es):
furphy = ''

for i in range(0, len(es), 4):
c = int(mid(es, i, 2), 16)
s = int(mid(es, i+2, 2), 16)
cc = c - s
furphy = furphy + chr(cc)

return furphy


def canoodle(panjandrum, ardylo, s, bibble):
kerfuffle = [None]*s
quean = 0
for cattywampus in range(0, len(panjandrum), 4):
a = int(mid(panjandrum, cattywampus + ardylo, 2), 16)
b = bibble[quean % (len(bibble))]

result = a ^ b
kerfuffle[quean] = result
quean += 1
if quean == len(kerfuffle):
break

return
kerfuffle


# ASC function returns the ASCII value of a character or the first character in a string
buff = [None]*8
for i in range(0,8):
buff[7-i] = ord(mid('FLARE-ON',i,1))


png = canoodle(lines_t, 2, 0x45C21, buff)
with open(r'C:\tmp\flare2020\4\flag.png', 'wb') as f:
f.write(bytes(png))

The result is a PNG that contains the flag:

flag: thi5_cou1d_h4v3_b33n_b4d@flare-on.com

--

--

--

Security researcher interested in reversing, solving CTFs, malware analysis, penetration testing and DevOps security (docker and Kubernetes)

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

What is yay AUR Helper and How to install it?

Raft Consensus Protocol

Using two’s complement to store integers in memory

Starbucks should really make their APIs public.

Day 3 and I felt like I gave birth.

How to enable TLS1.2 in Rserve

Magic-Hack The Box

Summoners Arena Open Beta: Install Instruction

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Eviatar Gerzi

Eviatar Gerzi

Security researcher interested in reversing, solving CTFs, malware analysis, penetration testing and DevOps security (docker and Kubernetes)

More from Medium

Network Services — Tryhackme

TRYHACKME: EASY PEASY STEP WISE WRITEUP FOR BEGINNERS

TryHackMe: Nmap Basic Port Scans Writeup

TryHackMe: Linux PrivEsc Walkthrough- Part 2(Task 9 to 12)