Home > Blog > HCRootkit / Sutersu Linux Rootkit Analysis

HCRootkit / Sutersu Linux Rootkit Analysis

Jared Stroud, Tom Hegel
Cloud Security Researchers – Lacework Labs

Key Points

  • Lacework Labs identified new samples and infrastructure associated with HCRootkit / Sutersu Linux rootkit activity, building-off its recent initial identification from our colleagues at Avast. 
  • Malicious droppers include and deliver additional files, a kernel module, and userland ELF. These files compromise a host with standard rootkit functionality.
  • The main agent uses a unique custom protobuf based protocol for C2 communication. 

Summary

Lacework Labs recently examined a new publicly shared rootkit, identifying its core capabilities and level of threat it represents to Linux hosts. The rootkit was first shared by Avast, triggering us to confirm coverage and investigate further. Our analysis below provides insight into the installer (droppers), in addition to the Kernel module and userland samples dropped. Our objective with this blog is to build on top of the findings from Avast, share our analysis, and provide defenders with detection options in the form of Yara rules and IOCs. 

For more content like this, follow us on Twitter or LinkedIn to keep up with our latest research.

The Dropper

The ELF dropper (602c435834d796943b1e547316c18a9a64c68f032985e7a5a763339d82598915) is a modified version of the coreutils “kill” binary. The majority of the “kill” binary’s core functionality remains the same, but with the addition of writing two ELF files to disk during execution. One of these components is a userland binary and the other a kernel module (10c7e04d12647107e7abf29ae612c1d0e76a79447e03393fa8a44f8a164b723d) identified by Avast as the Sutersu rookit.  Notably, figure – 0 and figure 1 show the the ELF dropper and kernel rootkit had low or non-existent detection rates on VirusTotal. 

 

Figure 0 – VirusTotal for Dropper

 

Figure 1 – Kernel Rootkit

The rootkit is written to disk first after a temporary filename has been generated via the mktemp system call. After writing 20224 bytes (0x4f00) to the temporary file, the file descriptor is closed and then the insmod utility is used to install this kernel module. Errors are subsequently  ignored through stdout/stderr redirection to /dev/null. If secure boot is enabled on the underlying system (which would require signed kernel modules) or the kernel version is not what the kernel module was compiled for, insmod will fail. Finally, the dmesg utility is used to clear the dmesg output (T1070,) which would contain forensic artifacts of a kernel module being installed as well as remove the underlying ELF binary via unlink.

 

Figure 2 – Kernel Module Written to Disk

 

After writing the kernel module to disk, the embedded userland component is written to either /proc/.inl or /tmp/.tmp_XXXXXX depending on whether or not the open command succeeded for /proc/.inl

Given the underlying backdoor coreutils utility is kill, it is not uncommon for the legitimate usage of this utility to be executed via “sudo kill” when terminating privileged processes. Executing with sudo results in appropriate permissions to both install the kernel module and write to the privileged location in /proc/.  After writing the file, the file descriptor is closed and the binary is executed via the system syscall followed by deletion via the unlink syscall. This behavior can be seen in the following figure below.

Figure 3  – Userland ELF Written to Disk

The Rootkit – Sutersu

The kernel module as pointed out by Avast is the open-source rootkit “Sutersu”. This rootkit has wide kernel version support, as well as supporting multiple architectures including x86, x86_64, and ARM. Sutersu supports file, port, and process hiding, as one would expect from a rootkit. Sutersu also supports functionality beyond process and file hiding in the form of additional modules that are specified during compile time.

At the time of this writing, these additional modules include a keylogger, a module to download and execute (DLEXEC) a binary upon a given event, and an ICMP module to monitor for specific “magic bytes” before triggering an event. The DLEXC and ICMP module can be used together to trigger the downloading and execution of a binary when a specific ICMP packet is received. They also can be used independently. Lacework labs identified multiple Sutersu kernel modules with various modules and external IPs. 

One variant of Sutersu identified within a dropper ELF containing the ICMP module that watches for incoming ICMP packets to then trigger further actions is shown as hiding any outbound connections to a given address. Figure – 4 below shows hardcoded IPv4 addresses identified within the Sutersu KO file. The “127.0.0.1” corresponds to a sshd server setup command within the userland ELF binary shown in figure -X. 

 Figure 4 – Embedded IPs of Kernel Module

Figure 5 – sshd Setup from Userland Component

The Userland ELF

The embedded userland ELF file is a dynamically linked file packed via the UPX utility. This is indicative based on string artifacts within the binary, but also the tell-tale sign of the two distinct segments that exist within UPX created binaries (sometimes labeled UPX_0 and UPX_1).

Figure 6 – UPX Segments

Figure 7 – Hexdump of Userland Binary

As mentioned by Avast Research Labs in their tweet, the userland binary contains custom protobuf files for commands. Unique file paths identified within the binary also indicate the usage of Poco (networking libraries), Libboost(verbose set of C++ libraries), and libssh.

Figure 8 – Hardcoded Development Paths

Lacework Labs identified other variants of userland libraries embedded within Sutersu variants (54b1a9338aa7df8a97fea8da863c615352368f3fc67e3caceb6ee65eb71bdbff) that contained Python one-liners. Figure – 9 below shows the embedded Python one-liner that fetches a remote binary over FTP via credentials of “winter1qa2ws” with a username of “vsftp”.

Figure 9 – Python One Liner

Initial Userland Execution Tasks

Upon initial execution of the userland binary, the program attempts to remove any evidence of the dropper by overwriting the install location with junk data (hex value 0xff11). This code snippet below was found in various Sutersu kernel modules as well.

Figure 10 – Overwriting Previously Created Files

Next, the userland binary ensures it has access to the directory of /root/ (variable pathName in Figure – 11), followed by reading in the current executing binary into a local buffer in order to execute the binary and masquerade under the process name “[kthread]” (T1036.005). 

Figure 11 – Re-spawning Userland Binary as Kthread

Finally, the main execution loop involves making HTTP GET requests to several domains on port 65130 for a resource of “/iplist”. Notably, this port is also included in the Sutersu kernel module as a port to hide. Every 180 seconds, the binary attempts to spawn sshd on 127.0.0.1 port 65439 as shown in the sshd Setup from Userland Component image. The userland ELF was executed in an isolated environment where a subset of static domain entries were added to /etc/hosts to observe behavior to domain interaction. The image below shows the ELF attempting to launch SSH and failure messages for domains not specifically listed in /etc/hosts and that are not reachable.

Figure 12 – Main Execution of ELF

Custom Protobuf

As originally mentioned by Avast, the userland component contains a custom protobuf for defining messages to its C2 server. Lacework Labs was able to carve out the protobuf artifacts to identify underlying functionality within the userland component. Additional hardcoded strings in the binary indicated that this was protobuf version 2, which allows for fields to be optional. This is an important consideration when thinking of whether or not a field will always have data in a protobuf message being sent back to the C2 server. Figure-12 below is a pseudo code representation of the extracted protobuf fields and may not represent the exact protobuf definition.

cmd.proto {
    cmd
    SessionInfo
    desc
    hide
    uid
    Init
    key
    sysinfo
    SystemVersion
    version
    system
    RequestVersion
    app_type
    ResponseVersion
    size
    app_type
    RequestUpdateDownload
    size
    app_type
    ResponseUpdateDownload
    off
    data
    app_type
    Upload_Passwd
}

cmd.Upload_Passwd.PasswordInfo{
    PasswordInfo
    address
    port
    username
    password
    Tick
    Show_Msg
    message
    Forward_Data
    src_uid
    dest_uid
    cmd
    data
    Host_List
}

cmd.Host_List.Host_Info {
    Host_Info
    ip
    system
    hide
    version
    nonlinetime
    desc
    Session_Connect
    uid
    Session_DisConnect
    uid
    Verify
    username
    password
    CommonCommand
    cmd
    args
}
cmd.CommonCommand.Command_Info {
    Command_Info
    name
    value
    List_Dir
    files
}

cmd.List_Dir.List_Info {
    dir
    List_Info
    name
    modify_date
    isdir
    size
    executable
    readonly
    writeable
    Fwd_Beg
    code
    message
    Fwd_Ing
    data
    Fwd_End
    code
    message
}

Figure 13 – Extracted Custom Protobuf

Custom Ghidra Scripts

To aid in the analysis and triage of key IoCs from the malware discussed above, Lacework Labs is releasing two Ghidra scripts to aid defenders and researchers alike. The dropper ELF contains multiple embedded ELFs for both the userland and the Suterusu rootkit component. The HC_Dropper_ID Ghidra script identifies the location of these embedded binaries to aid in ELF extraction. 

Figure 14 – Dropper ID

The “HCRootkit_Sutersu” identifies the “vermagic” string that reveals the kernel the Suterusu rootkit has been compiled for. Additionally, the script attempts to identify embedded IPv4 scripts as well as the ICMP module.  Figure – 12 shows the output of the Ghidra script execution.

Figure 15 – HCRootkit_Sutersu

Conclusion

Understanding the open source offensive utility ecosystem and leveraging those resources during analysis can quickly reduce the time it takes to identify critical IoCs for your organization. Lacework Labs continues to track evolving threats and release IoCs as well as Ghidra scripts to help defenders everywhere respond to incidents. For more content like this, follow Lacework Labs on Youtube, Twitter and LinkedIn!

Indicators of Compromise

efbd281cebd62c70e6f5f1910051584da244e56e2a3228673e216f83bdddf0aa
602c435834d796943b1e547316c18a9a64c68f032985e7a5a763339d82598915
6187541be6d2a9d23edaa3b02c50aea644c1ac1a80ff3e4ddd441b0339e0dd1b
19b4ccbd5dedcd355eb6c10eabcf7884a92350717815c4fc02d886bc76ecd917
10c7e04d12647107e7abf29ae612c1d0e76a79447e03393fa8a44f8a164b723d
7e5b97135e9a68000fd3efee51dc5822f623b3183aecc69b42bde6d4b666cfe1
d7ad1bff4c0e6d094af27b4d892b3398b48eab96b64a8f8a2392e26658c63f30
7b48feabd0ffc72833043b14f9e0976511cfde39fd0174a40d1edb5310768db3
2daa5503b7f068ac471330869ccfb1ae617538fecaea69fd6c488d57929f8279
ywbgrcrupasdiqxknwgceatlnbvmezti.com
pdjwebrfgdyzljmwtxcoyomapxtzchvn.com
yhgrffndvzbtoilmundkmvbaxrjtqsew.com
wcmbqxzeuopnvyfmhkstaretfciywdrl.name
ruciplbrxwjscyhtapvlfskoqqgnxevw.name
esnoptdkkiirzewlpgmccbwuynvxjumf.name
nfcomizsdseqiomzqrxwvtprxbljkpgd.name
hkxpqdtgsucylodaejmzmtnkpfvojabe.com
etzndtcvqvyxajpcgwkzsoweaubilflh.com
172.96.231.69
47.112.197.119

Yara Rules 

rule linux_mal_hcrootkit_1 {
	meta:
		description = "Detects Linux HCRootkit, as reported by Avast"
		hash1 = "2daa5503b7f068ac471330869ccfb1ae617538fecaea69fd6c488d57929f8279"
		hash2 = "10c7e04d12647107e7abf29ae612c1d0e76a79447e03393fa8a44f8a164b723d"
		hash3 = "602c435834d796943b1e547316c18a9a64c68f032985e7a5a763339d82598915"
		author = "Lacework Labs"
		ref = "https://www.lacework.com/blog/hcrootkit-sutersu-linux-rootkit-analysis/"
	strings:
		$a1 = "172.96.231."
		$a2 = "/tmp/.tmp_XXXXXX"
		$s1 = "/proc/net/tcp"
		$s2 = "/proc/.inl"
		$s3 = "rootkit"
	condition:
		uint32(0)==0x464c457f and 
		((any of ($a*)) and (any of ($s*)))
}

rule linux_mal_hcrootkit_2 {
	meta:
		description = "Detects Linux HCRootkit Wide, unpacked"
		hash1 = "2daa5503b7f068ac471330869ccfb1ae617538fecaea69fd6c488d57929f8279"
		hash2 = "10c7e04d12647107e7abf29ae612c1d0e76a79447e03393fa8a44f8a164b723d"
		author = "Lacework Labs"
		ref = "https://www.lacework.com/blog/hcrootkit-sutersu-linux-rootkit-analysis/"
	strings:
		$s1 = "s_hide_pids"
		$s2 = "handler_kallsyms_lookup_name"
		$s3 = "s_proc_ino"
		$s4 = "n_filldir"
		$s5 = "s_is_proc_ino"
		$s6 = "n_tcp4_seq_show"
		$s7 = "r_tcp4_seq_show"
		$s8 = "s_hide_tcp4_ports"
		$s9 = "s_proc_open"
		$s10 = "s_proc_show"
		$s11 = "s_passwd_buf"
		$s12 = "s_passwd_buf_len"
		$s13 = "r_sys_write"
		$s14 = "r_sys_mmap"
		$s15 = "r_sys_munmap"
		$s16 = "s_hide_strs"
		$s17 = "s_proc_write"
		$s18 = "s_proc_inl_operations"
		$s19 = "s_inl_entry"
		$s20 = "kp_kallsyms_lookup_name"
		$s21 = "s_sys_call_table"
		$s22 = "kp_do_exit"
		$s23 = "r_sys_getdents"
		$s24 = "s_hook_remote_ip"
		$s25= "s_hook_remote_port"
		$s26 = "s_hook_local_port"
		$s27 = "s_hook_local_ip"
		$s28 = "nf_hook_pre_routing"
	condition:
		uint32(0)==0x464c457f and 10 of them
}

rule linux_mal_suterusu_rootkit {
	meta:
		description = "Detects open source rootkit named suterusu"
		hash1 = "7e5b97135e9a68000fd3efee51dc5822f623b3183aecc69b42bde6d4b666cfe1"
		hash2 = "7b48feabd0ffc72833043b14f9e0976511cfde39fd0174a40d1edb5310768db3"
		author = "Lacework Labs"
		ref = "https://www.lacework.com/blog/hcrootkit-sutersu-linux-rootkit-analysis/"
	strings:
		$a1 = "suterusu"
		$a3 = "srcversion="
		$a4 = "Hiding PID"
		$a5 = "/proc/net/tcp"
	condition:
		uint32(0)==0x464c457f and all of them
}


Share this with your network
FacebookTwitterLinkedInShare