Cyber Apocalypse HTB 2022
Last updated
Last updated
When we first visit the URL we see this lovely page :
We can see the word BACKEND
at the top and it redirects us to a login page , but since we don't know yet any credentials we will let go off it . also we have report issue functionality , when i type any issue we get this response :
When i saw it i immediately went to blind xss , because we know that an admin will review our issue right ? so we can send an xss payload that will retrieve us the cookie and login as admin .
To do this i used a simple payload from xsshunter
:
The payload was accepted and no restrictions are applied to our input . Going to our xsshunter
result we see :
Moving further in our report we can see the cookies got , not just that we can also see a revealed page called settings :
Now we can easily take this session and replace it with our current one, by doing this nothing happened , but when i went to the /settings
page :
Now we are logged in as moderator with update password functionality we also can see the tickets section , by heading to it :
Nothing really interesting here, so let's return to the update password section and intercept the request with burp to see what is happening :
We can see that it takes the uid
which is obviously stands for user id and we know that we are logged in as moderator , so let's try to change the uid
from 100 to 1 since most of the web developers assigns the uid
of 1 to the admin
We changed the admin password , now let's try to login as admin:password
:
When we open the URL we found this page :
A simple page that allows us to add invoices , before we proceed we are given the source code , so let's take look at the important snippets :
Function called listInvoices()
that lists all of them in descending order but without our control and all of the other functions uses prepared statements so no place for sql injection here .
When we tend to add an invoice a post request iss sent to /api/invoice/add
with markdown_content
as a parameter and then it converts this markdown content to a PDF using makePDF
function , let's try this feature :
So here i typed some text and saved it
We have 2 actions for every invoice which is exporting and deleting , we know that our created one is the first because they are arranged descending . Now i wanted to know what library they used to convert the markdown to PDF , we can know this easily from package.json
file as it contains all the dependcies used .
The thing here that when i tested the library locally i found that it is not required to open or export the PDF file in order to execute the code , I then typed this payload but with replacing the system code as follow :
When i created the invoice using the web interface i didn't connection , so i thought of looking at the PDF to see what's going on :
We can see that the new lines didn't get processed , so i thought of sending the payload using burpsuite
And boom i got a connection , from the docker file we know that the flag is i /flag.txt
so let's upload it to our server using curl
as follow :
When we open the web page we see a pretty cool torch effect that was fun to play with
When we click this flying plate icon it takes an image and tries to change it's background color through a color palette , so this is the basic feature of the web app , we also are given a source code so let's take a look on the important snippets :
We see that the web app has an api with /alphafy
that accepts an image in the JSON request with 'image' parameter and it calls the make_alpha()
image with the provided image , so let's see what does this function do .
We can see that it tries to open the image and if it can't it catches and exception with 400 code , but if it can't it sets the color using the function ImageMath.eval
and we can notice that there is a color array which gets reflected inside this eval statement , fortunately we can control the elements of the color array through a parameter called background
, let's upload an image and intercept the request :
And we got the connection !! . From the docker file we know that the flag is in /flag.txt
there are multiple ways to retrieve it but i chose to be simple by using this payload :
This simply executes cat /flag.txt
and passes the result to a GET parameter called flag :
This time we are not provided with the source code , when we open the URL we find a registration page :
It takes UUID
which would be very hard to brute force , instead we can register as a normal user .
When we register we see this page . we also notice that we must be admin to view the sensitive records which will probaply be the flag .
Under every graph we see the export function , when we click export it export the current case of the graph and display it to us
Let's intercept the request to see what happens when i click export :
A post request to /api/export
is made with svg
parameter , we also can see session
and session.sig
but we will return to them later .
This was the response , and when we open this image we will see like the first image we saw .
When i saw the svg parameter an initial scenario came to my mind and it was to create stored xss via that svg parameter to get admin session but i failed to achieve that , the second scenario is to read local files using iframe
as follow :
This will simply read the /etc/passwd
file , when we go to the image from the response :
Amazing , so now we can read local files ... now what ?
Since the web app is based on node we can read files from the app directory /app/
like /app/index.js
or /app/routes/index.js
. So let's try to read them :
This file revealed the location of the session secret key => /app/.env
And finally
Let's connect the leads, we got the session secret key from the second image , we know that we should be admin in order to get the flag from the third image , remember the session we had ? if we base64 decoded it we get :
Now when i ran the web app i got the session and the signed one with the username admin :
Let's now replace the generated session with the current one :
We are given an IP and Port , by connecting to them we see this prompt :
By choosing any choice we get the same choices which are :
To eliminate my exploitation process i dealt only with the options that deals with user input which are number 1 3 4 5
[+] Number 1
I tried to create to create multiple of suspicious file names so when i read them using number 3 it would execute commands but i always got :
[+] Number 3
Choice number 3 was taking file name and tries to read it , so i thought of reading /etc/passwd
but i got :
We can pass our name as ../../../../../etc/passwd
:
Nice , we can try to read the flag.txt now :
By climbing another directory up :
We got our flag , but that was not the only solution i figured because the moment i saw the zip
option i knew that we need to escape that shell using zip
with the help of GTFOBins.
The compressing process here takes from us a file name (Existing one) and then compresses it , if we looked at GTFOBins :
We can escape shell by providing the following options : -T -TT 'sh #'
So now we know what to do , first we will create file using option number 1 and let's call it exploit
Next let's compress it by using option number 4 and provide our options to escape the shell
Now we can easily read the flag.
That was the most shorthand solution ever , we are given an IP and Port to connect to :
We see 2 options , I choose to insert password and with sense of default credentials i entered 1234
and i was surprized with the result :
md-to-pdf
with version 4.1.0 , when i searched for this library i found that it is vulnerable to RCE according to this article which uses this payload to achieve command execution :
Now time for the exploit , when i searched for the function ImageMath.eval
it appeared to be vulnerable to RCE according to this issue it states that the library Pillow
is vulnerable to code execution . Now we know that every element in the color array is reflected in the eval statement we can inject the payload in the first element as follow :
But we can't simply change the username to admin because this is a signed session and when we change the original session we should also have the signed one for it , and here comes the role of the session secret key . I searched for online session/cookie generator but i failed to find one so i had to write simple node web app that utilizes the login system and gives me the signed cookie with the secret key . This web app can be found here :