Task
> A deadly virus was released, can you decipher its contents?>> /!\ Real malware sample, be careful>> Attachment: update.zip
Category: Practical
First things first:
```bash$ unzip update.zip$ file updateupdate: Composite Document File V2 Document, Little Endian, Os: Windows, Version 10.0, Code page: 1252, Title: Repellendus., Template: Normal.dotm, Revision Number: 1, Name of Creating Application: Microsoft Office Word, Create Time/Date: Tue Sep 15 17:11:00 2020, Last Saved Time/Date: Fri Sep 25 13:47:00 2020, Number of Pages: 1, Number of Words: 4, Number of Characters: 24, Security: 0```
Well, malware + Word Document, then probably = macrovirus.
With no Microsoft Office in sight, lets find something else to analyze this sample. [Oletools](https://github.com/decalage2/oletools) is the first result we get on Altavista.
> oletools - python tools to analyze MS OLE2 files (Structured Storage, Compound File Binary Format) and MS Office documents, for malware analysis, forensics and debugging.
Inside [Oletools](https://github.com/decalage2/oletools) we have [olevba](https://github.com/decalage2/oletools/wiki/olevba) that is a...
> ... script to parse OLE and OpenXML files such as MS Office documents (e.g. Word, Excel), to detect VBA Macros, extract their source code in clear text, and detect security-related patterns such as auto-executable macros, suspicious VBA keywords used by malware, anti-sandboxing and anti-virtualization techniques, and potential IOCs (IP addresses, URLs, executable filenames, etc). It also detects and decodes several common obfuscation methods including Hex encoding, StrReverse, Base64, Dridex, VBA expressions, and extracts IOCs from decoded strings.
A command line tool written in python. Lovely!
So here we go...
```bashvirtualenv -p python3 venv. venv/bin/activatepip3 install oletoolsolevba update > olevba.logcat olevba.log```
We get a long report from this tool. Almost 3k lines long:
```olevba 0.56 on Python 3.7.3 - http://decalage.info/python/oletools===============================================================================FILE: updateType: OLE-------------------------------------------------------------------------------VBA MACRO Xhx92_rprjsbz.cls in file: update - OLE stream: 'Macros/VBA/Xhx92_rprjsbz'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Private Sub CheckCreds_Click()    If txtUsername.Text = "admin" And txtPassword.Text = "1234" Then        MsgBox "Great! The flag is EKO{}", vbOKOnly, "Right!"    Else        MsgBox "Oops!", vbCritical, "Wrong!"    End IfEnd Sub-------------------------------------------------------------------------------VBA MACRO Hpsd9g_lf27k5l2ku.frm in file: update - OLE stream: 'Macros/VBA/Hpsd9g_lf27k5l2ku'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Private Sub CheckCreds_Click()    If txtUsername.Text = "admin" And txtPassword.Text = "1234" Then        MsgBox "Great! The flag is EKO{}", vbOKOnly, "Right!"    Else        MsgBox "Oops!", vbCritical, "Wrong!"    End IfEnd Sub-------------------------------------------------------------------------------VBA MACRO VBA_P-code.txt in file: VBA P-code - OLE stream: 'VBA P-code'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ' Processing file: update' ===============================================================================' Module streams:' Macros/VBA/Xhx92_rprjsbz - 2089 bytes' Line #0:'       LineCont 0x0004 02 00 00 00'       FuncDefn (Sub Document_open())' Line #1:'       Ld Vrp7b4xtd7xq1ofe_n '       LitStr 0x002E "Gidy0bs0we474V4k8fu6h59cvq31wn F7pz34r6u5bola5"'       Add 
   ...
-------------------------------------------------------------------------------VBA FORM Variable "b'Jfuz55y9lj1'" IN 'update' - OLE stream: 'Macros/Hpsd9g_lf27k5l2ku'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - b'tu'-------------------------------------------------------------------------------VBA FORM Variable "b'Rwoat0n0ugte3'" IN 'update' - OLE stream: 'Macros/Hpsd9g_lf27k5l2ku'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - b'Wssxu7hazphw'+----------+--------------------+---------------------------------------------+|Type      |Keyword             |Description                                  |+----------+--------------------+---------------------------------------------+|AutoExec  |Document_open       |Runs when the Word or Publisher document is  ||          |                    |opened                                       ||AutoExec  |CheckCreds_Click    |Runs when the file is opened and ActiveX     ||          |                    |objects trigger events                       ||Suspicious|Create              |May execute file or a system command through ||          |                    |WMI                                          ||Suspicious|showwindow          |May hide the application                     ||Suspicious|CreateObject        |May create an OLE object                     ||Suspicious|Chr                 |May attempt to obfuscate specific strings    ||          |                    |(use option --deobf to deobfuscate)          ||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 first parts (`Macros/VBA/Xhx92_rprjsbz`, `Macros/VBA/Hpsd9g_lf27k5l2ku`) are classic VB macros, really easy to understand and we get nothing relevant from them.
We then get a lot of VBA P-Code and a table detailing some things (strings, mostly) that olevba found suspicious.
If the first blocks were easy, then trying to understand the P-Code is another thing. So we go back again to Excit-- err, Altavista in search of something to make thing a little bit easier for us.
Luckily there's [pcode2code](https://pypi.org/project/pcode2code/):
> ... To be able to analyze such "stomped" documents, Dr. Bontchev (@VessOnSecurity) released pcodedmp, a tool printing out the VBA bytecode of a document in a readable manner. However, the output might be still hardly readable and analyzable (please check out macaroni in tests folder). As such, pcode2code decompiles, based on pcodedmp's output, the VBA code.
I'll say kudos to Philippe Lagadec, Nicolas Zilio & Dr. Bontchev for their brave fight against VBA obfuscation.
```bashpip3 install -U pcode2codeolevba --code --show-pcode update > update.pcode   # extract p-code onlypcode2code -p update.pcode -o update.vbsource      # reconvert to source codecat update.vbsource```
Now, this is better.
```stream : ' Macros/VBA/Xhx92_rprjsbz - 2089 bytes########################################
stream : ' Macros/VBA/Hpsd9g_lf27k5l2ku - 21823 bytes########################################
stream : Macros/VBA/Xhx92_rprjsbz - 2089 bytes########################################
Sub Document_open()  Q6mb0h8sd2svvfz = Array(Vrp7b4xtd7xq1ofe_n + "Gidy0bs0we474V4k8fu6h59cvq31wn F7pz34r6u5bola5" + Xv6h65qbofvov1i, Thy9qdbsqlaagqxc36, Hpsd9g_lf27k5l2ku.Ntqlz_4vvxnddx, D3g2pqnlwicj5vbyd + "Wf4tn2t5p70ss S6divrjsc4pkobg D4u271cwophwas C1qu0s4dwdoca")End SubSub Kfgl49jnmfs3()  Md9lkj23nb = Chr(109) & Chr(69) & Chr(125) & Chr(99) & Chr(75) & Chr(48) & Chr(123) & Chr(79) & Chr(52) & Chr(100) & Chr(108)  KLsjnj309nnnf = Mid(Md9lkj23nb, 2, 1)  KLsjnj309nnnf = KLsjnj309nnnf & Mid(Md9lkj23nb, 5, 1)  KLsjnj309nnnf = KLsjnj309nnnf & Mid(Md9lkj23nb, 8, 1)  KLsjnj309nnnf = KLsjnj309nnnf & Mid(Md9lkj23nb, 7, 1)  KLsjnj309nnnf = KLsjnj309nnnf & Mid(Md9lkj23nb, 1, 1)  KLsjnj309nnnf = KLsjnj309nnnf & Mid(Md9lkj23nb, 9, 1)  KLsjnj309nnnf = KLsjnj309nnnf & Mid(Md9lkj23nb, 11, 1)  KLsjnj309nnnf = KLsjnj309nnnf & Mid(Md9lkj23nb, 10, 1)  KLsjnj309nnnf = KLsjnj309nnnf & Mid(Md9lkj23nb, 6, 1)  KLsjnj309nnnf = KLsjnj309nnnf & Mid(Md9lkj23nb, 4, 1)  KLsjnj309nnnf = KLsjnj309nnnf & Mid(Md9lkj23nb, 3, 1)  MsgBox(KLsjnj309nnnf)End Substream : Macros/VBA/Hpsd9g_lf27k5l2ku - 21823 bytes########################################
Function Ntqlz_4vvxnddx(id_FFFE As Variant)  On Error Resume Next  Set O19rsczr9gng = Xhx92_rprjsbz.Signatures  wzWrspw = "jlXBPtd1 f6AkKoQjzwGjCbLvuk73QJc1lSazWAa"  CMPYjuYGVj = Mid(wzWrspw, 21, 1)  ipiirDE = CMPYjuYGVj  mlmaRVf = "v05iZdfKC W47oI0B29OrzT"  nShDLRmDHl = Mid(mlmaRVf, 7, 1)
...```
Function `Ntqlz_4vvxnddx()` is quite long, and after that function there are some more with similar content. The first subprocess `Document_open()` is the one that we think it is executed, well, when the user opens that document. The second subprocess `Kfgl49jnmfs3()` sounds interesting, as it shows a `MsgBox()`.
Lets try to translate this into something more palatable:
- the [`Chr()` function in VBA](https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/chr-function) is similar to Python's own `chr()` function,- the [`&` operator in VBA](https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/ampersand-operator) concatenates strings, as the `+` does in Python,- the [`Mid()` function](https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/mid-function) extracts fragments from string, like the slice operator (but keep in mind that in VBA, indexes start at 1),- finally, we'll replace `MsgBox()` with `print`.
So the whole block turns to be something like
```pythondef Kfgl49jnmfs3():    Md9lkj23nb = chr(109) + chr(69) + chr(125) + chr(99) + chr(75) + chr(48) + chr(123) + chr(79) + chr(52) + chr(100) + chr(108)    KLsjnj309nnnf = Md9lkj23nb[1]                   # one less than in VBA source    KLsjnj309nnnf = KLsjnj309nnnf + Md9lkj23nb[4]   # ibid.    KLsjnj309nnnf = KLsjnj309nnnf + Md9lkj23nb[7]   #   "    KLsjnj309nnnf = KLsjnj309nnnf + Md9lkj23nb[6]    ...```
that, for the sake of brevity, I'll turn into
```pythonMd9lkj23nb = chr(109) + chr(69) + chr(125) + chr(99) + chr(75) + chr(48) + chr(123) + chr(79) + chr(52) + chr(100) + chr(108)KLsjnj309nnnf = ''for i in (2, 5, 8, 7, 1, 9, 11, 10, 6, 4, 3):    KLsjnj309nnnf += Md9lkj23nb[i - 1]print(KLsjnj309nnnf)```
Flag: `EKO{m4ld0c}`