Web Exploitation: Medium PicoCTF Challenges

September 29, 2024

Introduction

This past year, I have been spending most of my time completing HTB challenges and in particular, progressing through their CPTS academy path.
This includes areas such as Web Exploitation, Network Security, Secure Coding Practices and Exploit and Script Development among other interesting topics.
This writeup consists of four PicoCTF challenges which I have completed over this past weekend to explore some other "CTF" sites, and to just gain some more experience in Web Exploitation.
I will be going through the challenges from Easiest to Hardest in my opinion, sharing my process and thoughts along the way.

SOAP

The goal is to read the /etc/passwd file.
First look, there are a few buttons that stand out.
Let's click and see what happens.
The site seems to be loading data dynamically.
Let's open burp and have a look at the web request.

There is an obvious XML injection opportunity, lets have a look if the site has any filters or other mechanisms in place to stop us.
Lets try with an XML external entity injection to start.
Looking back at my notes, I'll use a rudamentary XXE payload and go from there.

Looks like there are no filters or security mechanisms in place?
I got the flag, this challenge took like five minutes.
I would have liked to test out some obfuscation techniques to bypass security measures.

Trickster


Looks pretty straightforward, a file upload attack.
Let's try uploading our webshell.
I'll be using a php webshell found here.
Checking the source code, we can see that the file needs a .png extension in the name. Let's try some shenanigans to test out this filter.
I renamed the file to have extension .png.php.

Looks like that didn't work. It is probably performing a magic bytes check on the file, and since our file isn't a real .png file, it does not have the respective file signature.
We can alter the file signature of our file using hexeditor.
A quick search on Google gives us the .PNG file signature.

Let's open hexeditor and alter this file.
I put some arbritary text before entering the hexeditor to make sure I didnt overwrite any php code.


Success. We have uploaded our webshell.
Now we need to find out where it got uploaded to.
Let's enumerate some directories with ffuf. I used ffuf with a common directory wordlist to find any interesting directories.

We found /uploads.
Now time to access the webshell.
Let's search for the flag.

find / -name *.txt


Flag found? Let's read its contents.

Nice and simple.
At this point I realised that these challenges are extremely easy compared to any HTB content (especially since these are MEDIUM difficulty).
So I thought might as well get through a couple more and see if I can learn anything new.

More SQLi

From the title, I expected a nice SQL injection challenge.
I've completed a comprehensive module on SQL injection on HTB Academy, so I was pretty confident.
First look, probably a simple SQL injection to bypass the login. I decided to type user "admin" and pass "admin" to see what would happen.

Looks easy, it even gives us the SQL query so we know where to inject.
Injected ' OR 1=1--' into the username input.
Now we have access.

First look at the welcome page, I've done something like this before...
I've exploited MySQL and MSSQL on HTB, but from the title it seems I'm going to need to learn some new syntax.
First, I'll attempt a Union injection with a different number of columns until we successfully get the results back.

cn' UNION select 1,2,3-- -


If I try to select four columns, there is no output.

This confirms that the query is selecting from three columns.
Now I have to learn some syntax. I looked at the SQLi syntax and formed a query statement to enumerate the table names.

cn' UNION SELECT 1, name, type FROM sqlite_master WHERE type='table'-- -


"Hints" looks interesting. Let's investigate.

cn' UNION SELECT 1, name, 3 FROM pragma_table_info('hints')-- -

cn' UNION SELECT id, info, 3 FROM hints-- -


Nevermind.
Let's look at "more_table" next.

See two columns, flag and id.

cn' UNION SELECT 1, flag, id FROM more_table-- - 


Flag obtained.
I liked this challenge. Although it was not too different, it was good to learn the SQLi syntax and I'm sure it will be useful in the future.

Javacode Analysis!?!

This challenge was very enjoyable, I liked the source code analysis aspects. While I have limited knowledge of Java, I have written web applications before so I more or less knew what was going on.
Let's begin.
First look, I logged in as the user provided and can see three books.
The flag book is locked behind "Admin".
Intercepting the web requests, I found that there was an authorisation token imbedded in each request.
webrequest
I began to read the source code to figure out what type of token it was.
jwtService.java I found that it was a JWT (JSON WEB TOKEN). This meant I could decode it and analyse its contents.
jwt.io
As you can see, it contains all our user data. I immediately tried to change the role to "admin" and access the flag book pdf, this didn't work.

I'm guessing I was missing the verification signature.
Let's dig a bit into how the token is generated in the source.
Secretgenerator.java
We find that there is a "secret_key" that is being used to is being used to sign and verify the JWT (JSON Web Token) using HMAC (Hash-based Message Authentication Code) with the SHA-256 algorithm (HMAC256).
Now this might be getting complicated, but let's explore "SecretGenerator.java", it sounds interesting.

Well, it seems that there has been a mistake. The generateRandomString function used to generate the "secret_key" that signs and verifies the JWT is infact, not generating a random string.
It is hard-coded to return "1234".
Now we can just generate our own JWT and bypass all this security.

I went back to jwt.io to create an admin token. This should allow me to access the flag book pdf.
But I ran into another problem, I didn't know the admin userID.
So I just enumerated all the users using the GET /base/users/ api endpoint.
I found this endpoint by clicking on my own profile and intercepting the web request. If this were a real web application, I could have leaked all registed users emails, userIDs and usernames.
I found that user: was userID 1, and admin: was userID 2. There were no other users.
Great, now we can create our JWT token.
Since I had already tried using the json web token in a web request to no avail, I thought that I should probably check the session cookies.
Sure enough, there is a "token-payload" and "auth-token" cookie. So I just edited them both.
I put the modified JWT into the "auth-token" cookie, and modified the "token-payload" to include the admin users details.
Now lets try to access the flag book pdf.
Flag obtained.
I really enjoyed this challenge, it pushed me to explore a variety of concepts, such as code analysis in Java, web applications, JWT and cryptography.
While these concepts are not new to me, I definitely learnt the most in this challenge.
Analysing how the JWT was generated and finding out the flaw in the code design was a cool way to frame a web exploitation challenge.


Overall

Overall, the PicoCTF Gym Challenges were pretty fun. While some were very easy compared to the challenges I'm used to, they were definitely great for practicing some of the skills I've developed over the past year.
Currently, I am more focused on real-world training and engagements so I'm trying to stay away from challenges which are CTF-like. But these challenges were definitely a great change of pace and helped me build some more confidence in my abilities.