It is common for threat actors to evolve their Linux malware. BlackTech with their new ELF_PLEAD malware and Winnti’s PWNLNX tool are recent examples. On par with this trend, we have discovered a new version of a Linux proxy trojan related to Stantinko group. The malware has just one detection in VirusTotal at the time of this publication.
Stantinko group is known for targeting Windows operating systems with ongoing campaigns dating back to 2012. The group’s malware mainly consists of coin-miners and adware botnets.
In a 2017 white paper summarizing Stantinko’s operations, researchers at ESET analyzed a Linux trojan proxy. Up until now, this was the only known Linux malware belonging to Stantinko.
We have identified a new version of this Linux trojan masqueraded as httpd. httpd is Apache Hypertext Transfer Protocol Server, a commonly used program on Linux servers. The sample’s version is 2.17, and the older version is 1.2*.
We believe this malware is part of a broader campaign that takes advantage of compromised Linux servers. Below we provide a technical analysis of the malware and compare it to its previous version.
The new proxy version file name is httpd and it has only one detection in VirusTotal at the time of this writing. Figure 1 below depicts the result from VirusTotal. The sample was uploaded on November 7, 2020 from Russia, one of Stantinko’s main target countries. The sample is an unstripped 64-bit ELF binary.
Figure 1: The sample’s detection report in VirusTotal (7d2a840048f32e487f8a61d7fc1a0c39).
Upon execution, the malware will validate a configuration file which is delivered together with the malware on the infected machine. The malware expects the configuration file to be located at “/etc/pd.d/proxy.conf”. If the configuration file does not exist, or if it lacks the required structure, the malware exits without conducting any additional malicious activity. Figure 2 below is a snippet from the configuration parsing logic. The configurations are stored as key/value pairs.
Figure 2: ParseConfigElement function is used to parse the configuration file.
The configuration file is expected to have the following keys: proxy_ip, port, redirect_url, localhost, ip_header and request_header_log_files.
After validating and parsing the configuration file structure, the start_demon function is called and the proxy daemonizes itself. Then, it creates a socket and a listener to accept connections from a client. We believe the clients who interact with this Trojan are other infected machines that are part of the campaign. Figure 3 is a snippet taken from the main function, showing the general code flow described above.
Figure 3: Main function flow snippet
Once a client connects to the listener, the program calls the on_client_connect function. First, it checks if the request method is GET, POST or NOTIFY.
If the request method is GET, the program will reply with a 301 redirect HTTP response containing the redirect_url parameter from the configuration file. This means that if the C&C IP is simply searched, using a browser for instance, the response could be misleading by redirecting to a benign website, leaving no trace of an extra payload that is used in the attack. If the request method is POST or NOTIFY, the malware will build a POST request to send to the C&C server based on the client’s HTTP request headers and content, using the create_post_data function. The program will then call the mysql_server_do_request function which is in charge of sending the POST request to the C&C. Figure 4 shows a snippet from the on_client_connect function.
Figure 4: Snippet from on_client_connect function
The POST request is sent to one of the following paths on the C&C server:
The path is selected in the detect_proxy_script function based on the data sent from the client. We believe that each path delivers a different payload as part of the campaign’s attack chain. The C&C IP address is stored as the proxy_ip parameter in the config file. Finally, the proxy forwards the C&C response back to the client. Figure 5 emphasizes the attack flow at a high level.
Figure 5: Attack Flow
- An infected client sends a POST or NOTIFY HTTP request to the proxy
- The proxy parses the request and passes on a POST request to the attacker’s server
- The attacker’s server replies to the proxy and the proxy passes on the response to the client
- A non-infected machine sends a GET request to the proxy
- The proxy replies with a 301 Redirect to a preconfigured URL
With a nearly three year difference between the two versions, the trojan proxies have similar purpose but they are not identical. In this section we will compare version 1.2* and 2.17 based on three criteria: Parameters, functionality, and ELF structure.
The new version (2.17) uses a configuration file that is dropped on the victim’s machine together with the malware. The configuration file contains the C&C IP address together with other parameters. In the old version (1.2*) the C&C is hardcoded in the binary, making it easier to block the campaign’s traffic once the binary is detected.
In addition to the proxy functionality, the old version receives files and self update commands from the C&C. The new version is more simple in that it only functions as a proxy.
Both versions 1.2* and 2.17 are unstripped and include debug symbols. The old version is statically linked, whereas the new version is dynamically linked.
The Stantinko Connection
After uploading the file to Intezer Analyze we noticed that the new variant shares several function names with the old one. These functions, such as get_binary_full_path and read_variable_string, are not called statically in the new version. We are almost certain these functions are leftover from the previous variant.
Figure 6: String reuse between the Linux versions
Interestingly, the C&C paths hint at some of Stantinko’s earlier campaigns based on ESET’s research. An example of the hard coded paths is shown in Figure 7. The root directory name is kbdmai. “KDBMAI.dll” is a malware filename used by Stantinko in 2012. Also, the malware’s C&C was hosted on kdbmai[.]net. Another interesting directory is DRTIPROV. DRTIPROV is part of a Program Database (pdb) path from one of the group’s Windows malware.
Figure 7: Path hard coded in the detect_proxy_script function
The code from the new Stantinko sample is now indexed in Intezer’s Genome Database. Sign up for the Intezer Protect community edition to defend your Linux cloud servers in runtime against the latest Linux threats.
I want to thank Nicole Fishbein and Joakim Kennedy for their contributions to this analysis.
New version: 2.17
Old version: 1.2*