Intro
Since Redis is becoming increasingly popular around the world, we decided to investigate attacks against Redis instances. We did not have to wait long for the first honeypot results. The trap caught activity that is not often discussed in the West while analysing SkidMap. More importantly, this variant turned out to be a new, improved and dangerous variation of the malware. Its level of sophistication surprised us quite a bit.
Malware
While analysing the latest logs from our Central European honeypot, we found an interesting entry that repeated less than two weeks later. Our western honeypot did not record the same activity. SkidMap targets open Redis instances, the so-called NO AUTH ones. We did not observe brute-force activity from the address that started the main attack.

Figure 00 is a simplified model of the malware. During analysis, we found at least two important execution paths that strongly affect the infection process. They follow two Linux families: Debian/Ubuntu and RedHat/CentOS.
The malware adapts to the system where it runs. The important part for us was to unpack and describe the key elements of the rogue application, then hopefully cut off a large part of the earnings from this criminal activity.
Infection - Redis stage
The attack starts by connecting to an unsecured Redis instance and setting variables that contain cron tasks hidden in a base64 string. The name HA may indicate targeting of high-availability clusters, which has been seen in other Redis malware campaigns.
We recorded two identical entries from the same address within roughly two weeks.

The two cron tasks alternate between curl and wget every ten minutes to download and run the dropper script. The host enumeration found two other names for the same script: c and f.
Using two download tools and retrying on a timer is not complicated, but it makes the first stage more resilient. The attacker only needs one fetch method to work once.
Infection - OS stage

The main job of the script is to download the ELF binary named gif into /var/lib/. A previous version used jpeg instead. The script checks that the backdoor is in the destination directory and that its MD5 hash matches the expected signature. If not, it removes the immutable flag and the old file, then makes room for the correct binary.
Picture of the Trojan - gif or jpeg?
The gif binary is now active on the system. One of its first steps is to add SSH keys in standard root SSH locations, leaving a backdoor for the attackers. This happens on every Linux system where the binary runs.
It then checks the status of SELinux and disables it permanently. The next step is persistence through changes to the host operating system.

The interesting part is the cron entry that creates a reverse shell to an attacker-controlled server every hour on TCP port 8443. The initial Redis foothold is only the start. The added key, disabled security control and scheduled callback give the operator several ways back into the host.

/etc/*-release is the standard file format containing basic Linux distribution information. A different action is performed for each distribution. The analysed gif binary targets Alibaba, Anolis, openEuler, EulerOS, Steam, CentOS, RedHat and Rock Linux.


There are more gif variants, so it is fair to assume that many popular Linux distributions can be targeted. For each variant, meaning distribution plus kernel version, the attackers prepared slightly different infection options by downloading one of three packages.

The other package names were gold, euler and stream. Enumeration found versions such as gold16.tar.gz, gold18.tar.gz, gold20.tar.gz, stream9.tar.gz, euler21.tar.gz and euler22.tar.gz.
This approach makes the malware easy to deploy and update for newly released Linux distributions and kernels. This is where SkidMap stops looking like a generic miner and starts looking maintained for a moving set of targets.
Encrypted packages - gold, stream, euler
At this stage, the running gif downloads one of the encoded packages into a directory under /usr/include/, decodes it and starts shell scripts. Those scripts install kernel modules, place other binaries and finally clean logs through clear.sh.



For another attack using the jpeg variant, the package password was different. One of the older gold packages remained encrypted because its password was not found during the research.
The shell scripts are quite self-explanatory by name. They prepare the OS for rootkits, kernel modules and binaries. The log-cleaning script and the bin/wtmp binary wipe traces of activity. Timestamp gaps in logs are worth monitoring because they can be a sign of this kind of compromise.


Other version.txt files contained values such as 0.0.6, 0.0.8.0 and 0.0.8.3. The pre-installation script changes security components including privilege attributes, SELinux and auditd. Some of those actions are tightly connected to a particular Linux distribution.
The old guys - gold18, gold20

This older variant has a different file layout, so it is not covered in depth here. Information about it can still be found online, mostly in Chinese sources. The first discovered SkidMap version had a package name with the number 8. The old packages later became 18 and 20, which may show the evolution of the malware.
The bot
The ELF executable named bot was one of the more interesting parts of the analysis. It contains several nested binary files. Right after execution, it downloads extra files. For the Debian/Ubuntu variant, we observed a connection to official Canonical resources to download files needed by the infection process.



Extracting the binaries required fixing malformed UPX headers. It is a known obfuscation trick used to slow down analysis. The binary had several extraction stages before reaching the last embedded file. One extracted component contained two kernel modules with different purposes. Static analysis of a memory dump confirmed both hidden modules.
Extracted module - mcpuinfo.ko
This module is one of the key components of the malware. It has functions that affect the host OS heavily. The function names needed for compilation gave us useful clues during analysis.



The fake_loading_proc_show function appears to hide real system load by displaying normal-looking values. The obvious reason is to hide mining activity. High CPU use on an otherwise quiet server is what gets many miner infections noticed, so making the machine lie about its load is a useful part of the concealment.
Some listed functions are only for local program use, while others are exported for other malware components.
Extracted module - kmeminfo.ko
This module monitors the network with Netfilter hooks. The nf_register_net_hook function belongs to the Linux Netfilter framework, which supports networking operations such as those used by iptables. This gives the malicious module the ability to analyse, modify or drop network packets.
For a miner, hiding or controlling pool traffic would be an obvious use. But a kernel module in the packet path is a more general capability, so it should be treated as one during incident response.

Kernel module - mzoneinfo.ko (?)
Signs of another possible module were found in one analysed binary, but the module itself was not recovered. mzoneinfo.ko could have been used in previous attacks and may appear in future ones. Other parts of the malware structure were not fully updated.
It is not an official kernel module. Its name follows the same pattern as the other ones and can look ordinary during a quick look at loaded modules.

The miner - Debian and Ubuntu variant
The miner binary is downloaded to /tmp/.miner, with another observed name .mimer, then run as several hidden processes. At each step, the MD5 hash is checked to make sure the binary is the expected one. Many other MD5 sums were hardcoded in the binaries during the analysis.


These processes are spawned after the gif binary runs from /var/lib. They are hidden from common system tools such as ps, pstree and top.
The miner - RedHat and CentOS variant
Another variant skips the separate miner download and uses a miner embedded in the extracted gif binary. In that case, /tmp/.miner does not exist.



Static analysis of the OS memory dump found the hidden processes, and dynamic analysis confirmed the result. The attackers also appeared to block a popular hidden-process tool, unhide, causing an execution error. Keeping the tool in memory before infection made the workaround easier.
This variant uses a spawn-execute-remove approach, which makes discovery harder for scanners and researchers. The memory-dump evidence shows that the RedHat/CentOS miners came through encrypted packages. The Debian/Ubuntu variant downloaded the miner to /tmp/.miner instead.
The miner's networking
Miner analysis itself was not the main target of this research, so the connection resets seen at first were not fully clear. We did confirm that, after the initial infection, the miner was eventually able to connect to its mining pool.



Even when a rootkit hides the process locally, a miner still needs to talk to a pool. That network connection is often a more reliable place to look during triage. Outbound connection logging and egress controls can catch things that a compromised ps output will not.
Scanning tools
We tested four popular Linux antimalware and antivirus scanners, all updated before the scan. ClamAV and Rkhunter reported no findings. Lynis found some kernel-hardening indicators and Chkrootkit found malicious LKM indicators.
A clean result from one scanner is not proof of a clean host, especially with a loadable kernel module involved. It is worth using several tools and taking warnings seriously. If this kind of compromise is suspected, examining the host from outside itself is safer than trusting tools running under the rootkit.
Summary
Previous SkidMap analyses existed, but we did not use them during the work so that they would not influence the result. The analysis showed a new and dangerous variant. At the beginning, many pieces did not fit together. Static and dynamic analysis made the most important parts clear.
The malware is advanced and can be hard to detect, especially in larger server infrastructure. On home systems, excessive fan activity and a hot laptop case were sometimes the only obvious signs. Reviewing logs for timestamp gaps and using a host-based intrusion detection system can help catch this type of activity.
And Redis? Exploiting an unprotected instance is not complicated. Redis was designed for a closed environment, and security features came later. An exposed instance without authentication can be used to write arbitrary files and reach remote code execution.
Protected mode, available from Redis 3.2.0, helps with the default configuration but it is not a complete solution. It can be disabled, and manually binding all interfaces can leave the service exposed again. Use a strong password and limit Redis network access to trusted clients on a restricted network.
IoCs
| File | MD5 | SHA-1 | SHA-256 |
|---|---|---|---|
| b, c, f | 000916c60b2ab828ba8cea914c308999 | 9970809e1dedce286888f7d25790b4dcca1e704b | 969e10e4a61cc5f80c414259c4d90c74bcf43ccd5678910700bdc14cd60f9725 |
| gif | e23b3c7eb5d68e3cd43e9e61a3055fe8 | 940f45f8a5dfb16281a35cd8303cd98c1ab1fabd | f77c4b704b20affdd737af44cabd3d7b56d8987924f2179137bbeef0e4be0367 |
| jpeg | e23b3c7eb5d68e3cd43e9e61a3055fe8 | 940f45f8a5dfb16281a35cd8303cd98c1ab1fabd | f77c4b704b20affdd737af44cabd3d7b56d8987924f2179137bbeef0e4be0367 |
| .miner | 44de739950eb4a8a3552b4e1987e8ec2 | 0ae049aab363fb8d2e164150dffbafd332725e00 | 9b81bad2111312e669697b69b9f121a1f9519da61cd5d37689e38381c1ffad28 |
| bot | 49ad1db4b61bb1f23cdcaeb546c6d154 | 47afaf89bb98705bb0b6eb2b14bdb8eaf84694fa | 1395201601e80b6f0733feb5bc6dee2d5d2b853fb157185486810457b329d712 |