Malware-analysis Sunshuttle Malware
Post
Cancel

Sunshuttle Malware

Four days ago, FireEye posted an article on the Sunshuttle malware

I started my analysis on the next day. This is a backdoor written entirely in Go.

MD5 Hash: 9466c865f7498a35e4e1a8f48ef1dffd

Entry Point:

1
2
3
4
5
6
7
8
9
interfaces, err := net.Interfaces()
if err != nil {
    os.Exit(0)
}
for _, iface := range interfaces {
    if iface.HardwareAddr.String() == "c8:27:cc:c2:37:5a" {
        os.Exit(0)
    }
}

If there exists a interface with the mac c8:27:cc:c2:37:5a, the malware exits. It then proceeds to setup a config by calling define_internal_settings

The malware uses AES with CFB chaining to encrypt/decrypt data.

Config File

The key for the config file (config.dat.tmp) is hz8l2fnpvp71ujfy8rht6b0smouvp9k8. The format is:

"a|b-c|d|e|f"

where

1
2
3
4
5
6
a = the md5 of the creation time of the config
b = minimum sleep time (in seconds), default 5
c = maximum sleep time (in seconds), default 15
d = waste time ? (1 => waste time, useless requests)
e = start time (the malware proceeds if current time is ahead of start time)
f = user agent

The default user agent is Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0

Every request uses a referer from one of the following

1
2
3
4
www.google.com
www.bing.com
www.facebook.com
www.yahoo.com

if the waste time flag is set, the malware calls false_requesting to generate some useless https requests. The useless requests are made to one of these servers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
https://code.jquery.com/
https://cdn.cloudflare.com/
https://cdn.google.com/
https://cdn.jquery.com/
https://cdn.mxpnl.com/
https://ssl.gstatic.com/ui/v3/icons
https://reyweb.com/style.css
https://reyweb.com/script.js
https://reyweb.com/icon.ico
https://reyweb.com/ic/assets/img/2021/malware-analysis/sunshuttle/on.png
https://reyweb.com/scripts/jquery.js
https://reyweb.com/scripts/bootstrap.js
https://reyweb.com/css/style.css
https://reyweb.com/css/bootstrap.css

C&C Url: https://reyweb.com/assets/index.php

Session Key

The malware uses the function request_session_key to indicate that it needs to fetch a session key using another function retrieve_session_key. If request_session_key returns HuLjdQwyCH, it means the session key can be fetched using retrieve_session_key

request_session_key

Method: GET

Cookies Used:

1
2
3
4
"HjELmFxKJc" => The MD5 of the config creation time
"P5hCrabkKf" => "gZLXIeKI",
"iN678zYrXMJZ" => "i4zICToyI70Yeidf1f7rWjm5foKX2Usx"
"b7XCoFSvs1YRW" => "78"

Expected Response: HuLjdQwyCH

retrieve_session_key

Method: GET

Cookies Used:

1
2
3
4
"HjELmFxKJc" => The MD5 of the config creation time
"P5hCrabkKf" => "cIHiqD5p4da6OeB",
"iN678zYrXMJZ" => "i4zICToyI70Yeidf1f7rWjm5foKX2Usx"
"b7XCoFSvs1YRW" => "78"

Expected Response: 32 byte key (encrypted with RSA)

Private Key used to decrypt the session key

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
-----BEGIN PRIVATE KEY-----
MIIEowIBAAKCAQEA0Aj/3K3m/rKNESwUfHC9qAhnsNYA9bJ4HQ30DPsfPDvbbHZm
Uj5nyp2abjYZYMQbWa2+ZO4Ixgfdm0FzsAH/haKIN4sSkbw+YRESYW35MnMI3Adf
mj/eK/yKNblyoe/7iWP3nz+y4Q/QI0L6BrF7VodTaDYtDup3iI+B5zjmhElf9Fmg
S1JiDUgydz5VXJR/esv6hB7GMfEb/3sIAzv5qcwEvGK5HH1EzQ7zjauyhbsF9pHR
zCFYlvW4OtaU0o3xjVufo5UwYRS5p/EFpof45zuJGLJ02cKUmxc0OX53t3Bn9WXY
aDDhYp/RPzywG8N9gTBv8rKxRIsFxxKu+8wK+QIDAQABAoIBAGe4hPDe13OXTBQK
uTAN+dEkV6ZoHFRjpdU+lrY+IiWi5lSed4d7y73OdCeM23xOaiB9KpchwsgRNeDp
cieH54EWNvoSYbC9fRBiNZrT/NG1Xu5s0rKSM1AU+kes7UVl5DBs4hHI7YOeobRi
+UuLA6ZxlBk6IZ71MaGpgyfoS64aDMvZDtcaTEGzw6dRQAU9255DTIc2YYbq8MqL
zSafD5eBDH3Izmblg0kXiidec1A1sytz5u8xW4XckHfp4xePLVw/RvLJGqNJMK5M
7tXAFwPzg+u4k7ce7uNw9VWW7n28T9xznUux1gtPQj1N6goDaBaOqY+h0ia9F1RP
wu6ZtG0CgYEA8vCFmAGmMz4vjO04ELyPnvnaS6CReYCVzmvNugIDlxBLDGCnKBVx
et7qEk3gMkbtcDUOZpXQAIVCWQNupAhI0t5bb/Pfw3HtH3Xt5NRUYmwxTgNRe06D
i4ICsg2+8TDinjne9hzsEe9DYE2WRrtLMJ+IPD+QE94J3Sei03k1wpMCgYEA2zga
Tff6jQeNn9G0ipHa1DvJmi98px51o0r7TUfZRxJfgg4ckyMsZUHKALrZszKAnxP7
MXYrJuOHpsp0EZc1e3uTjFzrKyKRTQ78c7MNGv07w1PlZuNLtkoqepUjkQzdxKZO
g9gG0O4lC5jjnSg8jUSChhZn+jrU8Vx7ByOP98MCgYAWi5+6RZzo8IJ1L6aeVwF1
HXbWweX+QqKkb3i+JGW05Twxv96DZ8oKPxm17Sg7Qj3Sxfm6J3kQM02++QSRkHtB
poUR1K4Vc0MwQj97lwDlyWih9sjfCqBGmCAr6f6oX4MIcBJzAKgf2faEv26MzeDi
eEuqW7PBRD/iGEWSHpOQpQKBgQDRgV+aTjk0mRhfugHKQLSbCnyUj3eZG8IfiiR7
agQcKVH/sE7cy8u9Bc/xPKGb4dMMtQLm9WEuLFtTKr8cpJ8nYSXVCmRx9/pXY9Af
HuqSdZutBDwERYvxLhZEys2P7XTwYGQ/GrEA8eeTms1FP9QGyofXcAh1G86w0Mp/
Oxx3EwKBgHXxgQa4/ngTlMNhWP+IvHOlOVAxDK2GL3XQdr8fudZe9c1d7VzIbYj6
gbwLT9qi0wG5FAWqH163XucAirT6WCtAJ3tK0lfbS7oWJ7L/Vh1+vOe6jfS/nQna
Ao2QPbN8RiltHeaAq0ZfrgwrQuP5fmigmBa5lOWID/eU2OLlvJGi
-----END PRIVATE KEY-----

C&C

Once the session key is fetched, it runs in an infinite loop the following. It retrieves the command to be executed using beaconing() and passes this to resolve_command() to complete the task. It then uses debug.FreeOSMemory() to force garbage collection and sleeps for a random interval in [gSleepLo, gSleepHi)
Requests and Responses are encrypted with AES using the key returned by retrieve_session_key.

p1

Fetching the command

The function beaconing() is used to get the command from the C&C server

beaconing

Method: GET

Cookies Used:

1
2
"HjELmFxKJc" => The MD5 of the config creation time
"iN678zYrXMJZ" => "i4zICToyI70Yeidf1f7rWjm5foKX2Usx"

Format of the command: marker*command
where marker is a string (maybe used to uniquely identify the command string following it)

resolve_command

It decrypts the command, executes it, and sends the result to the C&C server

List of Commands

  1. 13QTR5pC1R

    Kill the malware

  2. zSsP2TSJJm3a

    Get the sleep duration (gSleepLo, and gSleepHi) and save it to config Format: zSsP2TSJJm3a | lo | hi (spaces are not present, just for readability)

  3. aQJmWJzXdYK721mGBI3U

    Gets the parameter whether to waste time (using false_requesting) Format: aQJmWJzXdYK721mGBI3U val (space is present)

  4. W5VYP9Iu2uyHK

    Get the user agent Format: W5VYP9Iu2uyHK user-agent (space is present)

  5. 3487wD9t2OZkvqdwRpqPeE

    Get the current time in the format yyyymmddhhmmssMST

  6. ubFxROBRwfswVRWNjLC

    Get the activation time of the malware in the format yyyymmddhhmmssMST Format: ubFxROBRwfswVRWNjLC timeString (space is present)

  7. Download File

    Downloads file1, file2, … fileN from the C&C server and saves it to dest_file. Uses wget_file() to download the file data (base64) and then calls clean_file (probably to mark the file has been downloaded). The data from the n files are concatenated and stored into dest_file

    Format: dest_file | file1 <> file2 <> ... <fileN>

  8. TMuhGdA9EHY (Upload File)

    Uses send_file_part() to upload file in chunks of 256000 bytes. The return values (probably tokens) of send_file_part is concatenated and sent to the C&C server.

    Format: TMuhGdA9EHY file

  9. 1kG4NaRX83BCMgLo38Bjq (Execute Command)

    Executes a command without waiting for it to complete. Sends EXECED (doesn’t check if the status is successful or not)

    Format: 1kG4NaRX83BCMgLo38Bjq cmd

  10. hB0upT6CUmdRaR2KVBvxrJ (Get Command Output)

    Executes a command and sends its output. If the command fails to execute, the string "Some error in exec" is sent

    Format: 1kG4NaRX83BCMgLo38Bjq cmd

  11. Execute Shell Command (uses cmd.exe)

    Runs cmd with a list of arguments using cmd.exe and sends its output.
    Executes the command: cmd.exe /c args

    Format: ‘arg1 arg2 …’ (space separated list of args)

The malware sends payload using cookies to avoid detection.

send_file_part

POST Params:

1
"i9tL7syTtS" => base64 encoded encrypted data to send

Cookies used:

1
"P5hCrabkKf" => "xpjQVt3bJzWuv"

send_command_result

POST Params:

1
2
"KFy8AlFS0Q3M" => marker
"Dp3jaZ7if" => base64 encoded encrypted data to send

Cookies used:

1
2
3
"HjELmFxKJc" => the md5 of the creation time of the config
"P5hCrabkKf" => "S4rgG1WifHU"
"iN678zYrXMJZ" => "i4zICToyI70Yeidf1f7rWjm5foKX2Usx"

wget_file

Cookies used:

1
2
"TjZIpGWvg" => fileName
"P5hCrabkKf" => "t5UITQ2PdFg5"

clean_file

Cookies used:

1
2
"TjZIpGWvg" => fileName
"P5hCrabkKf" => "do1KiqzhQ"

Yara Rule

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
rule Sunshuttle
{
    meta:
        description = "Rule for detecting Sunshuttle"
        author = "x0r19x91"
        date = "2021-03-09"
        reference = "reference"
        hash = "9466c865f7498a35e4e1a8f48ef1dffd"
    strings:
        $name1 = "main_beaconing"
        $name2 = "main_resolve_command"
        $name3 = "HuLjdQwyCH"
        $url1 = "reyweb.com"
    condition:
        (($name1 and $name2) or $name3) and $url1
}

I would also like to point out two typos in the FireEye’s article on Sunshuttle

p2

The string is not in little endian

p3

It should be 13QTR5pC1R instead of Cp5RTQ31R1 Also, this command “13QTR5pC1R” kills the malware.

p5

p6

And secondly

p4

The string should be HuLjdQwyCH instead of ywQdjLuHHC

p7

This post is licensed under CC BY 4.0 by the author.