Bandit
You’ve been asked to exploit all the vulnerabilities on multiple systems. - by l4m3r8 and andrea526
Last updated
You’ve been asked to exploit all the vulnerabilities on multiple systems. - by l4m3r8 and andrea526
Last updated
The following post by 0xb0b is licensed under CC BY 4.0
Scanning our first target, the Linux machine with Nmap we can discover four open ports, of which on each of them runs a different service. On Port 22 SSH, on 80 an Apache Traffic Server, on 631 CUPS and on 8002 a web server.
Next, we head directly to the windows machine. Notable ports are Microsoft Windows RPC (port 135 and multiple 49xxx ports), Microsoft Windows file sharing (port 139 and 445), port 3389 for remote desktop and last but least port 5985 used by WinRM.
After scanning our targets with Nmap, we enumerate the available web services. We start with our main target bandit.escape
on port 80. This time we use FFuF to fuzz all possible directories.
A scan with Gobuster would also be possible by excluding the length.
We exclude results with a size of 3302
to filter false positives redirected to the index page.
After having enumerated the first layer of directories, we run a second scan to enumerate all possible PHP pages on the page, since we know that PHP 7.3.4 is used from the response headers. We see there is a login implemented, and a file upload seems also possible.
An interesting finding from the FFuF scan is a license, owned by the person ricnish
. On looking that person up, we are able to find a GitHub repository with a PHP authentication example. It looks like it was used to build this room. So here we have partly access to the sources of the login page with the assumption that this could have been slightly altered.
After having inspected the source and scans, we visit the hosted website of the Linux machine. We are able to search something, a slideshow of pictures is shown, and a login page is accessible. Using the login page with default credentials admin:admin
- found in the source - did not work. But the PHPSESSID
cookie was set. By trying to access the upload page /upload.php
we get redirected to the login page.
Looking at the source of the index page, we are able to spot the images' location. Also, the images have an MD5 hash as filename.
By requesting a search, we see that the input is passed via the filter parameter. The input gets reflected, so it stays in the input field. Nothing gets return with that search, the pictures are missing. By providing the search with a part of an image filename, it gets returned. The first tries here were to look for LFI, but weren't successful.
With a brief look at the source again, we see that reflected cross-site scripting should be possible.
Next, we test our assumption with an alert, but terminating the value field before.
And we are able to sneak our little script in. At this point, we can't do much with it except to mock ourselves.
Let's move on.
Back to the Nmap results, we see that the Apache Traffic Server is used in the version 7.1.1. A quick lookup shows that Apache Traffic Server is an open-source web proxy and caching server that acts as a reverse proxy, enhancing web server performance and content delivery. After researching for known vulnerabilities, a CVE can be found regarding HTTP Request Smuggling here:
So what is HTTP Request Smuggling exactly?
HTTP request smuggling is a technique for interfering with the way a web site processes sequences of HTTP requests that are received from one or more users. Request smuggling vulnerabilities are often critical in nature, allowing an attacker to bypass security controls, gain unauthorized access to sensitive data, and directly compromise other application users.
Request smuggling is primarily associated with HTTP/1 requests. However, websites that support HTTP/2 may be vulnerable, depending on their back-end architecture.
Resources for further Reading can be found here:
After researching on how to exploit the vulnerability on that specific version two blog post with a detailed explanation of the topic were found:
So in short it is possible to craft a request, that gets prepended to the request of another user. For example to nullify the first line of the request to smuggle our own. Since the search is implemented via a query string, we have an option to smuggle our XSS payload to another user.
From the Medium Blog Post, we find a working solution of triggering the vulnerability with a space in between the Content-Length
parameter and the colon of the request parameter.
Lets look at the following attacker request:
This would lead to the following victim request afterwards, if the victim request GET / HTTP/1.1
:
For this to work correctly the Content-Length
has to be the correct value. So we input the requests in Burp, send it the first time with our encoded payload to let Burp calculate the correct length. After that we place the space between the parameter and the colon. We have to disable Burp's option to update the Content-Length
parameter, so it won't insert a working parameter.
Here we placed a small JavaScript to fetch to our machine to disclose information of the user making the request. Next, we set up a listener and have to submit the request several times until we see a shorter Content-Length
of the response indicating that not pictures were found and the JavaScript placed.
We see, we were able to transmit the data 'Hello World'
via a user requesting from bandit.escape
10.200.135.107
.
The simplest thing we can do now is to steal the user's PHPSESSID
cookie in the hope of hijacking a privileged session.
Let's first try to steal our own cookie by accessing the page by our own. It worked.
Now lets steal the other user's cookie.
Keep in mind of encoding the payload and calculating the correct length before.
And we'll receive a session cookie after some time.
Let's place the cookie in our browsers' storage.
Now we are able to reach http://bandit.escape/upload.php
.
First, we inspect the source and see a simple JavaScript file upload restriction, only allowing images with a specific size. This can easily be bypassed by uploading a valid image and intercepting the request with Burp Suite to manipulate the file to our desire.
Again, we are able to spot some hints to find the original sources of the image upload page at GitHub. With the search of the value of the description we are able to locate a Github respository.
Before heading to Burp we try to upload the same picture that is already been available on the website. We get a warning that the file size is too big.
Ok, lets check that with a really small image, just a PNG pixel.
Also this time the image is too big.
Let's reduce the number of character. It is actually possible to upload something, but it has to be really tiny. The smallest possible PHP web shell comes into mind, that might work. But first we have to validate that the upload was successful.
The 'image' is there and got renamed to an MD5 hash. After uploading a file with .php
as ending, it does not get displayed. That might be an issue.
So next, let's try to figure out how the file name for the images gets created. Hopefully it isn't completely randomized. After hashing the content of the file, the filename without the file ending and the complete filename, we can see that the complete filename gets hashed and the file ending appended.
Since we are able now to calculate the correct file name, we should be able to access it directly at /uploads
.
We place the smallest possible PHP web shell as content <?=`$_GET[0]`?>,
choose the file name shell.php
and upload the file.
Next, we get the file name using CyberChef.
Lets test our web shell at http://bandit.escape/uploads/25a452927110e39a345a2511c57647f2.php
with a simple id command and we get a response.
Now, that we have a working web shell, we set up a listener and issue a reverse shell. We get a connection and are the user www-data
with a restricted shell.
From there, we are able to look at the actual source of auth.php
, in which we find the credentials of the user safeadmin
. We are able to use those to log in to the web application.
Now that we have gathered some credentials, let's move on. We were not able to find anything more of interest as the user www-data
. So recalling the Nmap scan, we remember that SSH is running and available on the machine. Let's check if the credentials are being reused.
We are able to log in via as SSH as the user safeadmin
with the found credentials. From there we have a checkpoint and are able to retrieve the first flag in the user's home directory.
The first thing that was immediately obvious is that the user is allowed to run everything with sudo
without a password. So we are able to directly switch to the root user.
We are able to spot the docker images running for the challenge and the user ubuntu
, which firstly just seems to be there to set up the challenge. In the /etc/hosts
file, we spot the entry for 10.200.XX.10
, it's bandit.corp
. Browsing through the file system, we are able to spot a PowerShell binary, and the modules PSWSMan
and PSReadLine
. That is interesting, maybe we are able to gain access to the Windows machine via the specific module through a PSSession
.
Now we know that the module PSWSMan
might haven been used, we look for possible credentials or hints in the command history.
And we get a hit.
This file might not have been generated on your network if you noticed the message 'connection lost' while registering to the challenge via SSH. If that happens, you should reset or switch the network and re-register again. We fell into a rabbit-hole searching the entire system for vulnerabilities and looking at different stuff and ignoring PowerShell and the user Ubuntu under the assumption the user was just there to set up the challenge.
We run /opt/microsoft/powershell/7/./pwsh
to start a PowerShell instance, and reuse the commands to enter the PowerShell session.
Now we reached the bandit.corp
10.200.XXX.10
machine.
Being in the PowerShell session, we spot that we are not able to use the full set of commands.
We are facing Just Enough Administration (JEA):
Just Enough Administration (JEA) is a security technology that enables delegated administration for anything managed by PowerShell. With JEA, you can:
Reduce the number of administrators on your machines using virtual accounts or group-managed service accounts to perform privileged actions on behalf of regular users.
Limit what users can do by specifying which cmdlets, functions, and external commands they can run.
Better understand what your users are doing with transcripts and logs that show you exactly which commands a user executed during their session.
Let's see what we are allowed to do with the Get-Command
.
We are also in no-language mode
, so we aren't able to run any scripts or use any variables.
NoLanguage modePowerShell
NoLanguage
mode disables PowerShell scripting language completely. You can't run scripts or use variables. You can only run native commands and cmdlets.Beginning in PowerShell 7.2, the
New-Object
cmdlet is disabled inNoLanguage
mode when system lockdown is configured.
Recalling the list of available commands via Get-Command
, the Get-ServicesApplication
command stands out. It looks like a custom function. Maybe there lies a vulnerability in it. By checking out the CommandInfo
via Get-Command -ShowCommandInfo
, we see that it is build by using the CMDlets as follows:
Get-Service | Select-Object -Property name,$Filter
This get invoked by Invoke-Expression
, that allows to execute code. See:
An insightful resource about bypassing JEA can be found here:
Using "(command)"
as a parameter for -Filter
we are able to get code execution. Now we should be able to escape.
We issue the command whoami
and get the command evaluated.
To escape, we make use of the Nishang
reverse shell.
After applying IP and port, we encode the payload in base64
to avoid strange behaviors in our bypass. We set up a listener on 443.
But we got a miss. AV detection is still on.
When trying to turn off the AV, there was an error while executing it and the rev shell did not connect this time too.
Thus we encode it in base64
.
This time we do not have any errors.
And our reverse shell connects.
We successfully escape the restricted PowerShell session by bypassing JEA and disabling AV to get a reverse shell. We are able to reach the Administrators Desktop where the final flag is present.