New York Flankees
Can you, the rogue adventurer, break through Stefan's defences to take control of his blog!
Last updated
Can you, the rogue adventurer, break through Stefan's defences to take control of his blog!
Last updated
Let's start with an nmap scan.
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.
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.
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.
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:
With root access to the host, we navigate to /flag.txt
and retrieve the final flag.