Writeup: FlareOn 2020: 004 - report
1. TLDR
2. Input data
The challenge file is here. Password: flare.
The subject of the task is the report.xls
spreadsheet. From the content of the task it is known that there is a macro with a flag hidden in it.
3. Inspection of report.xls file
I verified the file using file
tool:
$ file report.xls
report.xls: Composite Document File V2 Document, Little Endian, Os: Windows, Version 10.0, Code page: 1252, 0x17: 1048576CDFV2 Microsoft Excel
Below is the spreadsheet when opened in LibreOffice Calc:
I confirmed the existence of the macro using the oleid
tool:
$ oleid report.xls
oleid 0.54 - http://decalage.info/oletools
THIS IS WORK IN PROGRESS - Check updates regularly!
Please report any issue at https://github.com/decalage2/oletools/issues
Filename: report.xls
Indicator Value
OLE format True
Has SummaryInformation stream False
Application name unknown
Encrypted False
Word Document False
VBA Macros True
Excel Workbook True
PowerPoint Presentation False
Visio Drawing False
ObjectPool False
Flash objects 0
3. Inspection of macro
A macro was actually used in the sheet. In order to perform an initial analysis, I launched the olevba
tool:
$ olevba --analysis report.xls
olevba 0.55.1 on Python 2.7.17 - http://decalage.info/python/oletools
===============================================================================
FILE: report.xls
Type: OLE
-------------------------------------------------------------------------------
VBA MACRO ThisWorkbook.cls
in file: report.xls - OLE stream: u'_VBA_PROJECT_CUR/VBA/ThisWorkbook'
-------------------------------------------------------------------------------
VBA MACRO Sheet1.cls
in file: report.xls - OLE stream: u'_VBA_PROJECT_CUR/VBA/Sheet1'
-------------------------------------------------------------------------------
VBA MACRO F.frm
in file: report.xls - OLE stream: u'_VBA_PROJECT_CUR/VBA/F'
-------------------------------------------------------------------------------
VBA MACRO VBA_P-code.txt
in file: VBA P-code - OLE stream: 'VBA P-code'
-------------------------------------------------------------------------------
VBA FORM STRING IN 'report.xls' - OLE stream: u'_VBA_PROJECT_CUR/F/o'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
�9655B040B64667238524D15D6201.B95D4E01C55CC562C7557405A532D768C55FA12DD074DC697
...
C14B7C4E8F1F8F21CB64
-------------------------------------------------------------------------------
VBA FORM STRING IN 'report.xls' - OLE stream: u'_VBA_PROJECT_CUR/F/o'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
H�,�p
-------------------------------------------------------------------------------
VBA FORM STRING IN 'report.xls' - OLE stream: u'_VBA_PROJECT_CUR/F/o'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
58c7661f00634702555f664b7756884c864edc4fef2d9c48881bac0911082214334e424f552f661
...
4c0046004e00060068000b001600ef000e002600cc
+----------+--------------------+---------------------------------------------+
|Type |Keyword |Description |
+----------+--------------------+---------------------------------------------+
|AutoExec |Auto_Open |Runs when the Excel Workbook is opened |
|AutoExec |Workbook_Open |Runs when the Excel Workbook is opened |
|Suspicious|CreateObject |May create an OLE object |
|Suspicious|Environ |May read system environment variables |
|Suspicious|Write |May write to a file (if combined with Open) |
|Suspicious|Put |May write to a file (if combined with Open) |
|Suspicious|Open |May open a file |
|Suspicious|Lib |May run code from a DLL |
|Suspicious|Chr |May attempt to obfuscate specific strings |
| | |(use option --deobf to deobfuscate) |
|Suspicious|Xor |May attempt to obfuscate specific strings |
| | |(use option --deobf to deobfuscate) |
|Suspicious|Binary |May read or write a binary file (if combined |
| | |with Open) |
|Suspicious|Hex Strings |Hex-encoded strings were detected, may be |
| | |used to obfuscate strings (option --decode to|
| | |see all) |
|IOC |wininet.dll |Executable file name |
|IOC |winmm.dll |Executable file name |
|Suspicious|VBA Stomping |VBA Stomping was detected: the VBA source |
| | |code and P-code are different, this may have |
| | |been used to hide malicious code |
+----------+--------------------+---------------------------------------------+
The tool has enumerated the functions, libraries and methods used, the use of which was classified as suspicious.
Particularly noteworthy is the information on the use of the VBA Stomping method .
3.1 Macro acquisition
I’ve extracted a macro in VBA:
$ olevba --code report.xls | tee report.vbs
Kod VBA zamieściłem poniżej:
olevba 0.55.1 on Python 2.7.17 - http://decalage.info/python/oletools
===============================================================================
FILE: report.xls
Type: OLE
-------------------------------------------------------------------------------
VBA MACRO ThisWorkbook.cls
in file: report.xls - OLE stream: u'_VBA_PROJECT_CUR/VBA/ThisWorkbook'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sub Workbook_Open()
Sheet1.folderol
End Sub
Sub Auto_Open()
Sheet1.folderol
End Sub
-------------------------------------------------------------------------------
VBA MACRO Sheet1.cls
in file: report.xls - OLE stream: u'_VBA_PROJECT_CUR/VBA/Sheet1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
3.2 Macro analysis: VBA
3.2.1 rigmarole function
The rigmarole function was responsible for decoding sequences of bytes:
9655B040B64667238524D15D6201
B95D4E01C55CC562C7557405A532D768C55FA12DD074DC697A06E172992CAF3F8A5C7306B7476B38
C555AC40A7469C234424
853FA85C470699477D3851249A4B9C4E
A855AF40B84695239D24895D2101D05CCA62BE5578055232D568C05F902DDC74D2697406D7724C2CA83FCF5C2606B547A73898246B4BC14E941F9121D464D263B947EB77D36E7F1B8254
853FA85C470699477D3851249A4B9C4E
9A55B240B84692239624
CC55A940B44690238B24CA5D7501CF5C9C62B15561056032C468D15F9C2DE374DD696206B572752C8C3FB25C3806
A8558540924668236724B15D2101AA5CC362C2556A055232AE68B15F7C2DC17489695D06DB729A2C723F8E5C65069747AA389324AE4BB34E921F9421
CB55A240B5469B23
AC559340A94695238D24CD5D75018A5CB062BA557905A932D768D15F982D
D074B6696F06D5729E2CAE3FCF5C7506AD47AC388024C14B7C4E8F1F8F21CB64
to the form:
AppData
\Microsoft\stomp.mp3
play
FLARE-ON
Sorry, this machine is not supported.
FLARE-ON
Error
winmgmts:\\.\root\CIMV2
SELECT Name FROM Win32_Process
vbox
WScript.Network
\Microsoft\v.png
3.2.2 canoodle function
The canoodle function was responsible for decrypting the data string with the Vernam cipher.
3.2.3 folderol function
The folderol function was the main macro function that was automatically run when the sheet was loaded. In addition to implementing the actual intention of the programmer, it was responsible for verifying the presence of a network connection and detecting the virtual runtime environment. The detection mechanism consisted in searching the list of processes to reveal the presence of a process containing the string “vmw”, “vmt” or “vbox”.
The actual functionality realized by the folderol function was:
- correct decryption of the ciphertext contained in the text field of the form defined in the macro:
- writing plaintext to
%AppData%\Microsoft\stomp.mp3
file
3.2.4 Analysis stomp.mp3 file
I played the file stomp.mp3
where I heard a few thumps.
Then I read the metadata using the exiftool
tool:
$ exiftool stomp.mp3
ExifTool Version Number : 12.00
File Name : stomp.mp3
Directory : .
File Size : 165 kB
File Modification Date/Time : 2020:09:21 20:59:31+02:00
File Access Date/Time : 2020:09:21 20:59:31+02:00
File Inode Change Date/Time : 2020:09:21 20:59:31+02:00
File Permissions : rw-r--r--
File Type : MP3
File Type Extension : mp3
MIME Type : audio/mpeg
MPEG Audio Version : 1
Audio Layer : 3
Audio Bitrate : 160 kbps
Sample Rate : 44100
Channel Mode : Joint Stereo
MS Stereo : Off
Intensity Stereo : Off
Copyright Flag : False
Original Media : False
Emphasis : None
ID3 Size : 4096
Publisher : FLARE
Year : 2020
Title : This is not what you should be looking at...
Band : P. Code
Date/Time Original : 2020
Duration : 8.23 s (approx)
If until now you did not notice the use of the VBA Stomping method, at this point can be read two tips:
This is not what you should be looking at…
3.3 Macro analysis: P-code - option no. 1
Knowing that the VBA Stomping method was used, I read the disassembled P-code:
$ pcodedmp report.xls | tee report.pcode
3.3.1 Hidden macro code
Manually performed differential analysis of the P-code and the VBA code revealed the following fragment of the P-code:
Line #53:
SetStmt
LitDI2 0x000A
ArgsLd onzo 0x0001
ArgsLd rigmarole 0x0001
ArgsLd CreateObject 0x0001
Set groke
Line #54:
Ld groke
MemLd UserDomain
St firkin
Line #55:
Ld firkin
LitDI2 0x0003
ArgsLd onzo 0x0001
ArgsLd rigmarole 0x0001
Ne
IfBlock
Line #56:
LitDI2 0x0004
ArgsLd onzo 0x0001
ArgsLd rigmarole 0x0001
Ld vbCritical
LitDI2 0x0006
ArgsLd onzo 0x0001
ArgsLd rigmarole 0x0001
ArgsCall MsgBox 0x0003
Line #57:
End
Line #58:
EndIfBlock
Line #59:
Line #60:
Ld firkin
FnLen
St n
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
Line #64:
Line #65:
Ld F
MemLd T
MemLd Text
LitDI2 0x0002
LitDI4 0x5C21 0x0004
Ld buff
ArgsLd canoodle 0x0004
St wabbit
Line #66:
LitDI2 0x0000
ArgsLd onzo 0x0001
ArgsLd rigmarole 0x0001
ArgsLd Environ 0x0001
LitDI2 0x000B
ArgsLd onzo 0x0001
ArgsLd rigmarole 0x000"FLARE-ON"1
Concat
St mf
3.3.2 Hidden code analysis
P-code analysis allowed to restore possible VBA code:
Set groke = CreateObject("WScript.Network")
Dim firkin As String
firkin = groke.UserDomain
If firkin <> "FLARE-ON" Then
MsgBox rigmarole(onzo(4)), vbCritical, rigmarole(onzo(6))
End
End If
Dim n As Integer
n = Len(firkin)
For i = 1 To n
buff(n - i) = Asc(Mid(firkin, i, 1))
Next
wabbit = canoodle(F.T.Text, 2, 285729, buff)
mf = Environ("AppData") & "\Microsoft\v.png"
3.4 Macro analysis: P-code - option no. 2
Using the pcode2code.py
tool, I obtained the P-code decompiled into VBA:
$ python /home/remnux/.local/lib/python2.7/site-packages/pcode2code/pcode2code.py report.xls | tee report.pcode2vba
The analysis of the VBA code allowed to establish an important fragment responsible for the correct decryption of the ciphertext:
Set groke = CreateObject(rigmarole(onzo(10)))
firkin = groke.UserDomain
If firkin <> rigmarole(onzo(3)) Then
MsgBox rigmarole(onzo(4)), vbCritical, rigmarole(onzo(6))
End
End If
n = Len(firkin)
For i = 1 To n
buff(n - i) = Asc(Mid$(firkin, i, 1))
Next
wabbit = canoodle(F.T.Text, 2, 285729, buff)
mf = Environ(rigmarole(onzo(0))) & rigmarole(onzo(11))
4. Reading the flag
I pay attention to the fact that the key to decrypt was determined from the machine name. Also, the script required it to be “FLARE-ON”.
So I executed the script:
Function folderol()
Dim wabbit() As Byte
Dim fn As Integer: fn = FreeFile
Dim mf As String
Dim buff(0 To 7) As Byte
Dim firkin As String
firkin = "FLARE-ON"
Dim n As Integer
n = Len(firkin)
For i = 1 To n
buff(n - i) = Asc(Mid(firkin, i, 1))
Next
wabbit = canoodle(F.T.Text, 2, 285729, buff)
mf = Environ("AppData") & "\Microsoft\v.png"
Open mf For Binary Lock Read Write As #fn
Put #fn, , wabbit
Close #fn
End Function
As a result of executing the macro, the %AppData%\Microsoft\v.png
file was saved, which contained the flag: