[Pragyan CTF] Supreme Leader



North Korea reportedly has a bioweapon in the making. Hack into their database and steal it.

Link :

For the second web challenge we’re given with a URL, lets open it.

Cute Kim 🙂

Now let’d dump the headers of the response using curl:


We can see an interesting cookie:  KimJongUn=2541d938b0a58946090d7abdde0d3890_b8e2e0e422cae4838fb788c891afb44f. The value of the cookie is looking like 2 MD5 hashes combined with “_”. Let’s try to crack them online using my favorite site.

That’s it! Here is the flag: pragyanctf{send_nukes}

[33C3 CTF] pay2win Writeup



pay2win – Web
Do you have enough money to buy the flag?

This challenge was pretty tricky to understand at the beginning. I solved it with a quick and simple workaround that allowed me to solve the challenge without fully understand it. Once I got the flag I understood the whole story. So as with all the stories, we need to begin from the start.

We’re given with a website in where we can buy two products: ‘cheap’ (13.37 USD) and ‘flag’ (31337.42 USD). We, of course, want to buy the ‘cheap’ one because we don’t want to spend our money on some leet flag with the answer to life, the universe and blah blah. So — the ‘cheap’ it is.


In order to buy the product we need to supply a valid credit card number, there are bunch of examples of valid credit cards online.


Lets try one of them and see what we get.


Woo-hoo! We finally bought the ‘cheap’ product and fulfilled our dream.
Kidding. Lets move on and see what will we get when trying to buy the ‘flag’.



“failed”? Oh no. The server says that we exceeded the credit card limit. The first thing to come in my mind was to brute force the server with valid CC numbers, but I figured out very fast that this isn’t the right way to the solution. At this time I noticed something interesting about the URLs of the pages: there’s a GET parameter named ‘data’ that some parts of it are the same on every request. Until now I thought it’s always a new hash. I grabbed pencil and paper and started to figure out the patterns and the mutual parts. Okay, okay, I admit – opened VS Code and made a simple table. The mutual parts highlighted using Photoshop.


As you can see, every hash is combined from 3 parts. The beginning of each type is mutual and so is the end. I thought that certain combination is required to get the flag. But how I mix the parts to the correct hash so as to get the ‘flag’ content. Now it’s about trial and error. Or not.

After two manual tries I gave up because automation is always better and here comes the workaround I mentioned before. I created a list with instance of every colored part and added one example of white part from each page. I then created from this list another list with all possible permutations of 3 parts, i.e all the possible combinatios (990 combinations) and tried all of them using urllib2.urlopen() ’til I found ’33C3′ in the response.

I know. It isn’t the most efficient way to do this but it was short and quick.


It took the script 2 minutes to run and then it came up with 3 possible hashes, lets try one of them to see if we indeed got the flag:


YES! We got the flag! I took a deep breath and analysed the matched hashes to find out what is the right pattern. I came out with two possible patterns:

5765679f0870f4309b1a3c83588024d7c146a4104cf9d2c8 + X + 2f7ef761e2bbe791
5765679f0870f4309b1a3c83588024d7c146a4104cf9d2c8 + X + 4f75c9736d3b8e0641e7995bb92506da1ac7f8da5a628e19ae39825a916d8a2f
Where X is one of the white parts of ‘flag’ product (purchase page/success).

The logic behind is as followed: Seems like the blue part is for ‘success’ and the light-blue part is for ‘failed’. The yellow part is likely for ‘product page’. If you take every hash of ‘flag’ product (product page / purchase failed) and replace its first part (light-blue / yellow) with the blue part (‘success’) you come up with a valid hash that brings the flag.

That’s it. the flag is:  33C3_3c81d6357a9099a7c091d6c7d71343075e7f8a46d55c593f0ade8f51ac8ae1a8
I’ll be happy to read in the comments how the challenge was for you.

[H4CK1T 2016] QRb00k – Russia Writeup



Task: QRb00k – Russia – W3b – 400
The secured messenger was developed in Canada, it’s using systems with qr keys for communicating, it allows to read other people’s messages only to this key holders. But is it true? And you have to figure it out …

This was a very good web challenge. It took me quite a time to fully understand it but was absolutely worth of its 400 points.

Starting the challenge we are given with a messenger site that uses QR codes to communicate. The site has two main pages:

  • Create – which creates QR code from a given name and message
  • Read – an upload form to upload QR code and read the message inside

So let’s create a message:

We got a QR code which is the key to read our message:

Now let’s read the message using the QR code:


Ok, it all worked as it supposed to. I used the zxing service to view the content of the QR code:


Look at the raw text. It’s a short string that looks like it was base64 encoded. But wait, base64 can’t begin with “==”! Those characters usually appear at the end of base64 encoded strings. Is it reversed? Let’s check:

Yes! it indeed was reversed. our key (QR code) is created by: QR(Reverse(Base64(name))).

Ok, now that we understand the mechanics we can let the party begin and start playing with SQL Injection. In order to create the QR codes I used this site, It was faster than using the challenge site.

I began with the obvious: ‘ or 1=1–


Whoops, Busted. The system recognized my SQLi attack. I tried some filter bypassing methods and succeeded with this input:

Reverse(Base64(input)) == “==wc0VWZiF2Zl10JvoiLuoyL0NWZsV2cvoiLuoyLu9WauV3Lq4iLq8SKoU2chJWY0FGZvoiLuoyL0NWZsV2cvoiLuoyLu9WauV3Lq4iLq8yJ”


It worked! now let’s find the correct table (“messages”) and column by using some queries to map the database:

QR(Reverse(Base64(input))) == “zRXZlJWYnVWTn8iKu4iKvQ3YlxWZz9iKu4iKv42bp5WdvoiLuoyLnMXZnF2czVWbn8iKu4iKvU2apx2Lq4iLq8SZtFmbfVGbiFGdvoiLuoyLlJXZod3Lq4iLq8ycu1Wds92YuEWblh2Yz9lbvlGdh1mcvZmbp9iKu4iKv02byZ2Lq4iLq8SKl1WYu9lbtVHbvNGK0F2Yu92YfBXdvJ3ZvoiLuoyL0NWZsV2cvoiLuoyLu9WauV3Lq4iLq8yJ”


“secret_field”? Sounds suspicious. Let’s query it and see what it contains:


And we got the flag! I honestly really enjoyed this challenge.

Flag: h4ck1t{I_h@ck3d_qR_m3Ss@g3r}


If you have any questions feel free to ask 🙂

[H4CK1T 2016] Pentest – Mexico Writeup



Task: Remote pentest – Mexico – 150 – Web

Our foreign partners have some problems with qualified staff in the field of information technology, we decided to help them and to conduct remote testing of their new website. Your task is to find a hole in the system and grab some information to confirm the hack .Good luck !

YAY! Web challenge! If you are following my blog (If not, the subscribe form is on left) you already know how much I love web challenges, It’s either easy points or great puzzle.

Let’s open the website and see what we have:


WOW! JUSTICE LEAGUE! Did I mentioned that I love comic books and especially Batman? Oh, Not yet?

Well, this challenge is going to be awesome. No. It’s already awesome!

OK, deep breath. Let’s start. See that menu on the bottom? Let’s click on some link to see what will happen.


Look at the URL, the “about” page is included by the “index.php” using php commands ‘require’ or ‘include’. When we see something like that in a challenge we can check if the site is vulnerable to LFI attack. In Local File Inclusion attack we can include pages from the local server. Let’s try to include /etc/passwd to check for the existence of the vulnerability

Didn’t work. Let’s try to add null byte at the end


It worked! We successfully got the /etc/passwd file. So what now? Let’s try to read the pure php file to see if the flag is in the php pages.

We can use php://filter to print the content of index.php in base64 format. We need to encode the content because we don’t want the php engine to compile the php parts of the code.

We got encoding page, now let’s decode it and see if we find a flag . I deleted some content to decrease the size of the code in the post.


Nope. No flag. The “flag{…}” thing isn’t really the flag because the flag in this CTF should be in h4ck1t{…} format.
Also the other pages like ‘about’ and ‘contact’ is not contain any flag. So we probably need to perform LFI to RCE (Remote Code Execution) attack. We can use the php://input method to send php commands through Post requests. Using Firefox Hackbar plugin we can do it easily.
Put the URL to be  And the POST data to be


Success. We got the RCE and we now know about a new secret file. Let’s read it using the same way but this time with

And we got the flag 🙂

Flag: h4ck1t{g00d_rfi_its_y0ur_fl@g}

[CSAW 2016] mfw Writeup



Hey, I made my first website today. It’s pretty cool and web7.9.


Entering the site, the first thing that comes to mind is a LFI attack. The site is including a page which is requested in the URL.

The following table describes the possible respond pages:

URL Result
http://web.chal.csaw.io:8000/?page=home The “home” page is shown.
http://web.chal.csaw.io:8000/?page=about The “about” page is shown.
http://web.chal.csaw.io:8000/?page=contact The “contact” page is shown.
http://web.chal.csaw.io:8000/?page=Megabeets Just a message saying: “That file doesn’t exist!”
http://web.chal.csaw.io:8000/?page=flag An empty page is shown inside the website.
http://web.chal.csaw.io:8000/?page=../../../../etc/passwd Just a message saying: “Detected hacking attempt!”

Looking at the source code i saw the following comment:

Ok, I need to get the “flag” page but any LFI technique I tried didn’t work. I thought about something else, In the “about” page the creator of the site mentioned that it was built using git. So let’s see if I am able to download the repository. The page http://web.chal.csaw.io:8000/.git/config exists so I downloaded the repository using DVCS-RIPPER.

You can find index.php here.

So the page is using assert() which is vulnerable to Command Injection attack. After a little trial and error I came up with the answer:

And received the flag:

If you try entering the url in a browser, look in the source of the page (CTRL+U), the flag is commented.

[TWCTF-2016: Web] Global Page Writeup


Challenge description: 
Welcome to TokyoWesterns’ CTF!

As I entered the challenge I faced a three items list – two links and a strikethrough word:.

I clicked the tokyo link, which was actually a GET request with a parameter named page in index.php. In response I got a page with PHP error and information from Wikipedia about Tokyo, printed in Hebrew – my mother tongue.

Warning: include(tokyo/en-US.php): failed to open stream: No such file or directory in /var/www/globalpage/index.php on line 41
Warning: include(): Failed opening ‘tokyo/en-US.php’ for inclusion (include_path=’.:/usr/share/php:/usr/share/pear’) in /var/www/globalpage/index.php on line 41

First thing to come in mind is a LFI attack, but before making any reckless time-wasting moves, let’s first figure it all out. The page uses include() to, well, include the page “en-US.php” from folder named tokyo. The page wasn’t existed so an error was thrown. I tried pages like “en.php”, “he.php” and “jp.php” and they did exist. The page “ctf” displayed similar behaviors. Seems like all the pages display their information based on the user’s or the browser’s language.

The second thing I tested was the page’s reactions to different values. I tried the value “?page=flag” and it returned the expected error:

Warning: include(flag/en-US.php): failed to open stream: No such file or directory in /var/www/globalpage/index.php on line 41
Warning: include(): Failed opening ‘flag/en-US.php’ for inclusion (include_path=’.:/usr/share/php:/usr/share/pear’) in /var/www/globalpage/index.php on line 41
Warning: include(flag/en.php): failed to open stream: No such file or directory in /var/www/globalpage/index.php on line 41
Warning: include(): Failed opening ‘flag/en.php’ for inclusion (include_path=’.:/usr/share/php:/usr/share/pear’) in /var/www/globalpage/index.php on line 41

I then understood the page was trying to include the language file and every value that I’ll set to “page” will be a folder. I tested the page with the value “../../../etc/passwd” with and without a null-byte terminator but failed due to the sanitize of dots and slashes the page performs.

But how does the page know my language? It took me a while to figure it out. The page took my language settings from the “Accept-Language” field in the request’s header. I tried to change Accept-Language to something else using a Firefox plugin called Tamper Data and it worked! Any value I’ll put there will change the requested page. For example if I request “?page=Mega” and set Accept-Language to “beets” it would return the errors:

Warning: include(Mega/beets.php): failed to open stream: No such file or directory in /var/www/globalpage/index.php on line 41
Warning: include(): Failed opening ‘Mega/beets.php’ for inclusion (include_path=’.:/usr/share/php:/usr/share/pear’) in /var/www/globalpage/index.php on line 41

I combined it all together to perform a well known LFI attack using php://filter. I set the parameter value to “php:” and the Accept-Language field to “/filter/convert.base64-encode/resource=index”. This function encodes the page with Base64 before including it. And indeed I got “index.php” encoded with base64. The decoded page looks like this:

As you can see on the top of the code there is an included page named “flag.php”. I changed the Accept-Language accordingly to “/filter/convert.base64-encode/resource=flag” and received the encoded page. Decode it to reveal the flag:


By the way, you can also solve it the “Curl” way:


megabeets_inline_logoEat Veggies.

[CTF(x) 2016 : WEB] Harambehub – 100 pts Writeup


Challenge description:
This website was created in honor of harambe: http://problems.ctfx.io:7003
Problem author: omegablitz

This challenge was the second in the Web category and it actually was the first time I’ve ever seen something like that. We are given with a url, which returns an empty page and two source-files written in Java for Spark Framework. Make sure you read the given source-files before you continue.

The main file, HarambeHub.java, contains two methods which are actually get() and post() routes to two different pages, as you can see below:

Reading both source files we understand the application is capable of creating a new account and to retrieve the real_name of a user if you know its username and password.

Let’s try to register a new user, using a simple Powershell code:

We results with “OK: Your username is “[Member] Megabeets””. As you can see, the text “[Member] “ has been added to the username we supplied. By reading the function that handles the registration process we understand that we can register a user with that name again and again. Executing the exact same code results with the exact same answer: “OK: Your username is “[Member] Megabeets””. Let’s try this again but this time with “[Member] Megabeets” in the username. Now we end up with an error saying: “FAILED: User with that name already exists!”.

Let’s take a look at the code that checks if a given username already exists:

As you can see, the code compares the two strings in attempt to check whether the username exists, but it uses String.matches() instead of String.equals(). The method String.matches() checks the match of a string to a regular rxpression pattern. Keep this in mind, it’s the key to solving the challenge. If false is returned, it creates a new User with the username “[Member] <username>”, just as we’ve seen before.

But what happens if we try to register a user with a regular expression as its desired username? Does it say that the username already exists? Let’s play with it a little bit and see what we get when sending “.*” as the password (“.*” is the regex pattern to anything).

As expected, we received the error: “FAILED: User with that name already exists!”.

Now let’s take a look at the function that retrieves the real_name of a given username.

This function also uses String.matches() to compare the given password with the user’s password. Let’s see it in action:

We results with: “Itay Cohen”.

Good. Now we’ll send the same request but this time with wildcard as the password.

We again results with: “Itay Cohen”.

Let’s sum up what we have understood until now:

  1. We can get the real_name of any user if we know its username.
  2. We can understand if username already exists by using regular expressions.

That’s mean that we need to run through all the possible usernames till we find the user which his password is the flag. My gut feeling tells me the username will probably start with “[Admin]”.

I’ll do a simple test to check whether indeed a user begins with “[Admin]” exists. If so, only the developer can add a user with such a username because every registered username is prepend with “[Member]”.

FAILED: User with that name already exists!”.

I wrote a simple script to automate the process. May the bruteforce be with us.


It seems like we’ve found the username. Let’s get its real_name:

And we got the flag:


megabeets_inline_logoEat Veggies.

Harambe the Gorilla was a 17-year-old Western lowland silverback gorilla who was shot and killed at the Cincinnati Zoo after a child fell into his enclosure in late May 2016. The incident was wildly criticized online by many who blamed the child’s parents for the gorilla’s untimely death.

RIP Harambe.

[CTF(x) 2016 : WEB] north korea – 50 pts Writeup


What is North Korea hiding?

Entering the URL I faced with only a sentence:
“We, the Democratic People’s Republic of Korea, have developed a revolutionary new security standard. The West doesn’t stand a chance.”

That’s all? I took a look at the source code (ctrl+u) to see if something is hiding, and indeed I saw a hidden button and a simple script:

I clicked the button and it gave me the content of “http://problems.ctfx.io:7002/code” which was a message: “Nice try kiddo”.
Well, I took a look again at the first message: “…The West doesn’t stand a chance.”. What about the north? What if i”ll set the X-Forwarded-For to North Korea’s IP? X-Forwarded-For is the conventional way of identifying the originating IP address of the user connecting to the web server coming from either a HTTP proxy, load balancer.

And the response came with the flag:

megabeets_inline_logoEat Veggies.