It is not often that you see a botnet’s tooling written from scratch. The Internet of things (IoT) botnet ecosystem is relatively well-documented by security specialists. New threat actors are generally discovered quickly due to the inherent noise caused by DDoS operations, both in terms of infecting new machines and conducting operations. Simply, it is difficult to hide such overt activities. Most DDoS actors do not invest resources in creating custom tooling, unless they require specific capabilities, and resort to using well-known botnet implants (e.g. Mirai, BillGates).
In late April we identified a new botnet campaign with definitive Chinese origins, targeting servers and IoT devices via SSH brute forcing. While most attackers derive their implants from popular and well-tested sources such as open source (e.g., Mirai) or blackmarket toolsets (e.g., BillGates), this botnet utilizes its own custom implant, which MalwareMustDie named Kaiji based on one of the function names. The botnet was built from scratch using the Golang programming language, which is rare in the IoT botnet landscape.
Kaiji spreads exclusively via SSH brute forcing by targeting the root user only. Accessing root is important to its operation since some DDoS attacks are only available via crafting custom network packets. In Linux, custom network packets are only given to a privileged user such as root.
Once a SSH connection is established, a bash script is executed which sets up the environment for the malware:
A /usr/bin/lib directory is created and then Kaiji is installed under the filename ‘netstat’, ‘ps’, ‘ls’, or some other system tool name.
Kaiji has simple features. It consists of an arsenal of multiple DDoS attacks such as ipspoof and synack attacks, an ssh bruteforcer module to continue the spread, and another ssh spreader which relies on hijacking local SSH keys to infect known hosts which the server has connected to in the past.
Despite the Kaiji file being stripped, we were able to restore function names using IDAGolangHelper. This technique works by retrieving function definitions embedded within the Golang binary which are not removed by the strip command.
Once the malware is executed, it copies itself to /tmp/seeintlog and launches a second instance which commences its malicious operations. Each operation is implemented within its own goroutine:
There exist 13 central goroutines which are important for the implant’s operation. Many of these functions are named in an English representation of Chinese words. We have highlighted the most interesting functions and added a translation from Chinese to relevant functions:
Decrypt C2 addresses, register the newly infected server to one of the command servers and launch the doTask and RotKit goroutines.
Incidentally, some of the C2 addresses are decrypted through a chain of three encryption schemes, while another C2 address is simply encoded in base64:
On the left, C2 base64 decoding. On the right, C2 decryption.
The binary contained four command server hostnames, two of which were resolved to localhost since they were registered. The only hostname which worked was operational for two weeks before failing to respond.
Fetches commands from the C2. These include:
• DDoS instructions
• SSH bruteforce instructions, including host range and a password to attempt login
• Run shell command
• Replace C2 servers
• Delete itself and remove all persistence
For DDoS operations, a target and an attack technique are retrieved.
• Two TCPFlood implementations (one with raw sockets)
• Two UDPFlood implementations (one with raw sockets)
• IPSpoof attack
• SYNACK attack
• SYN attack
• ACK attack
Tries to connect to known hosts through existing SSH RSA keys or IPs found in bash history:
Install persistence through rc.d and Systemd services:
main_runghost: Install persistence through /etc/profile.d (/etc/profile.d/linux.sh)
main_rundingshi (漢字: run timing): Install persistence through crontab
main_runganran (漢字: run infection): Another persistence technique, backdoor the SSH init script /etc/init.d/ssh to call the rootkit on startup
main_runshouhu (漢字: run surgery): Copy the rootkit to /etc/32679 and run it every 30 seconds
main_runkaiji (漢字: run boot): Install more persistence init.d files, e.g.: /etc/init.d/boot.local
ddos_rdemokill: Check the CPU usage machine periodically and kill if CPU usage exceeds 85%. This can inadvertently kill unrelated processes. Interestingly, this function refers to the rootkit as a demo
In our own sandbox we observed that the rootkit tends to invoke itself too many times, leaving the machine gasping for memory:
This, together with the fact that the C2 was operational only temporarily, and the presence of a ‘demo’ string, led us to believe that this is an early version still in testing.
It is rare to see a botnet written from scratch, considering the tools readily available to attackers in blackmarket forums and open source projects. In this post we have uncovered a new DDoS operation in its early stages that was written from scratch. This is another confirmation of an interesting trajectory noted by vendors such as Palo Alto that malware developers are turning to modern languages such as Golang for their operations.
The Kaiji samples are now indexed in Intezer Analyze. Powered by our new Golang cross platform code connections, users will be able to easily spot if this threat actor switches to Windows.
Protect your Linux and cloud servers
Threats targeting Linux are on the rise. Learn more about our runtime solution that protects your Linux cloud servers against cyber attacks.