H@cktivitycon — Web

Shellbr3ak
10 min readAug 1, 2020

Hello guys, this is $hellbr3ak back again, but this time we’re going to be doing some of the web challenges from the CTF that hackerone ran.

For me, this one was my first CTF, and I was so happy to participate in it.

First, we’re gonna start off with

LadyBug:

this was the first challenge I solved in this CTF.

so enough talking and let’s jump in.

looking at the page, we don’t see anything of interest, so I decided to run:

curl -I http://one.jh2i.com:50018/

to get the server response headers.

as you can see the server that’s running is:

Werkzeug/1.0.1 powered by python/3.6.9

After googling this server, I found that exploit-db has an exploit for it, but before firing it up, we need to check if the debug shell is enabled for end-users.

Going to http://one.jh2i.com:50018/console
gives us this page:

Essentially what the exploit does is, it starts checking whether the debug shell is enabled or not, if it’s not it stops working, and if it is, it just sends a simple reverse shell code in python, pretty simple isn’t it ;)

So let’s fire up that exploit and see what we’re gonna get:

P.S: Do not forget to set your netcat listener along with ngrok tcp port forwarding :P

And we got the shell and the flag for this challenge. :)

Our next challenge is

Bite:

And here’s the web page:

Clicking on the links in the “Reference” box gives us this page

and for me, whenever I see a parameter called (page, path, etc) I try LFI,

giving the parameter page this value:
../../../../../../etc/passwd

gives us this:

but if we inject a null byte at the end of our payload, like :

../../../../../../etc/passwd%00

Aaand indeed it worked, our next step is to get the flag.

after poking around for a while, it turned out to be stored in the root “/” dir

and here we can see the flag ;)

Now, to the next challenge

Waffle Land:

I’m not gonna lie, this challenge was a bit tough to me, at first I noticed that the search bar has an SQLi vulnerability, but I couldn’t get anything out of it.

Then an awesome guy told me that the name of the challenge is a hint already (WAFfle Land), and I realized that there’s a firewall needed to be bypassed to get information from the DB.

inserting “ test’ “ in the search bar gives us this error message:

So, the search query looks pretty simple :

select * from product where name like ‘%input_goes_here%’

Another good information we got from this message is that the DB service being used here is Sqlite3, I’ve tried to inject a union statement to get information from other tables, but I kept getting 403 Forbidden.

payload: test’ union select 1,2,3,4—

so I couldn’t figure out how many columns being retrieved from the first statement, (at least using “union” injection ;) ), so I tried injecting “order by” statements as follows:

payload: test’ order by 1 —

I kept replacing the number in the statement until I got this error

which means the first select statement is retrieving values from 5 columns

as you can see in the image, we are not getting any error messages.

At this point I tried getting information using nasted select statements

payload: test’ and (select column_name from table_name) —

and after trying SO MANY payloads, I found a table called ‘user’ and it has the columns we want ‘username’ and ‘password’, but I couldn’t exfiltrate any data using that payload.

But wait, the server rejected our first union injection although it contained a ‘select’ statement, then let’s try to inject a ‘union’ keyword without a ‘select’

I wanted to make sure that my assumption is correct, so I tried to inject a ‘select’ keyword

and we didn’t get that 403 Forbidden error, so it’s obvious now that the WAF is checking for exact match to ‘union select’, if it’s in the injected statement, it’s gonna give us 403 Forbidden, but how can we bypass this??

the answer is, with comments ;)

payload: test’/**/union/**/select/**/1,2,3,4,5--

and we got this, yaay!!!

Now let’s get the information we want to login as admin

payload: test’/**/union/**/select/**/1,username,3,password,5 from us er—

And we got it!!!

now let’s log in as admin and get that flag

P.S: ignore the $ sign the in password

And, to the next challenge:

Lightweight Contact Book:

This challenge was my best, the reason is, I didn’t know anything about LDAP injection, and honestly I didn’t want to solve it since I don’t know what LDAP exactly is, then I changed my mind and said, why not learning new thing?

After all, it was the main reason for me to participate in this CTF.

So, I had to read a lot about Ldap in general (how it works, its structure, and its syntax, etc).

I will not explain LDAP here, but I’ll do my best to explain the injection very well.

First, I tried to inject a wildcard (*), and I got these information:

then I wanted to check the sign in functionality, and I saw a something weird.

There was a “Forgot your password?” functionality.

I tried to insert the administrator’s username (simple as ‘Administrator’), to see what type of actions the server is gonna take (as the CTF creators said that everything is there for a reason). And indeed what I hit “recover password” button, I got this message:

And we got a great hint saying that the passwords are stored in the ‘description’ field (fields in LDAP are similar to columns in SQL-based DBs).

Now all I need to do, is to craft an LDAP query to get the password of the user administrator, but unfortunately, it wasn’t that simple since it’s a blind injection (Blind injection essentially means that you won’t get the data in the response body).

While reading about LDAP injection, I came across this amazing website:

https://book.hacktricks.xyz/pentesting-web/ldap-injection

you can read it if you’re interested.

You definitely should be. ;)

And after a few tests, I came up with this query:

administrator)(description=*)(&

This query will give the administrator’s username and email if it returns True.

now we need to fuzz for valid characters to get the password.

The payload you need for fuzzing is :

administrator)(description=FUZZ*)(&

So in order to make fuzzing faster, I wrote this python script with a very cool effect:

And we got the password:

very_secure_hacktivity_pass

Now let’s login as administrator and retrieve the flag.

The next challenge is:

Template Shack:

We see a simple web site with two links (Free, Premium) that goes to nowhere, and a login functionality.

So, we’re going to intercept the login request with burp to see how it looks like:

And we got this.

A POST request to the path ‘/login’ with the uesrname and password parameters, but the interesting part here is the token cookie, and obviously it’s a JWT tokens.

you can read about it here:

https://jwt.io/introduction/

This website has a cool functionality to decode JWT tokens, let’s see how it looks like:

We see the algorithm is HS256.

HS256. Hash-based Message Authentication Code (HMAC) is an algorithm that combines a certain payload with a secret using a cryptographic hash function like SHA-256.

and the username is ‘guest’, but we need to get the 256-bit-secret to craft our cookie and get an admin session. so I’m gonna be using hashcat to crack this tokens to retrieve the secret key.

Save the tokens in a file and run hashcat:

And we got it, the secret key is “supersecret”

now, go to https://jwt.io/ and replace the ‘guest’ username with ‘admin’ and insert the ‘supersecret’ key. (Note: you don’t need to base64 encode the tokens here in this case).

Now go back to the challenge’s web page and press F12 to open the developer tools, then navigate to ‘storage’ and replace your crafted JWT tokens with the ‘token’.

Then refresh the page, and you should be logged in as admin.

After submitting the admin’s token you can go to:

jh2i.com:50023/admin

P.S: I found this directory using ffuf command-line tool

And here’s what the admin page looks like:

clicking on the links on the right side of the page, we found another page:

We got this 404 Error message and it’s printing out the path of the non-existent page, not to mention that this is not the 404 page we used to see, is it?

Considering the name of the challenge, and seeing this weird 404 message, it’s fair to assume that we’re in front of an SSTI vulnerability.

let’s try this simple payload to see if it’s gonna work:

{{7*7}}

And as you can see, we got a 49 (the result of multiplying 7 by 7) rendered in the response page, which indicates an SSTI vulnerability.

Now, it’s time to find out the template engine in use here to craft the right exploit and retrieve the flag, and to do so, I’m gonna intercept this request to see if burp is going to give me any useful information.

In the response headers, we see the server is powered by python.

(yeah, yeah, I know it’s the same server as in the LadyBug challenge, but in the case of this challenge, the debug shell isn’t enabled “sad face”).

But who cares, we have an SSTI here ;)

back to the exploitation part.

To be honest, I’m not very good at exploiting SSTI, so I had to use google a lot to get a “working” exploit, but eventually a friend sent me this blog:

https://medium.com/@nyomanpradipta120/ssti-in-flask-jinja2-20b068fdaeee

and finally I crafted this payload to execute shell commands:

{{ ‘’.__class__.__mro__[1].__subclasses__() [405](‘ls’,shell=True,stdout=-1).communicate()}}

And indeed we found the flag.txt file, and luckily it’s stored in the /admin directory. Now let’s modify the payload to read that flag

{{ ‘’.__class__.__mro__[1].__subclasses__() [405](‘cat flag.txt’,shell=True,stdout=-1).communicate()}}

And we got it!!! ;)

Well, that was my write up about the challenges I managed to solve in H@ctivitycon CTF, I hope you guys enjoyed it.

Eventually, some shouts:

  • Thanks to Hacker0x01 and Nahamsec for putting on a great con.
  • John Hammond for putting on another great CTF.
  • Adam Langley for creating another insane web challenge.
  • And to all the people who kept giving advises when I was getting stuck.

--

--

Shellbr3ak

Offensive Security Engineer | Threat Intelligence Analyst | Cloud/Web App Penetration Tester | CTIA | eWPTXv2 | OSWE | CTF Lover