Monday, August 12, 2013

ctf.wargame.vn 2013 web150

url:http://42.117.7.116/web150_be56cb18b29a7b9dba9497d46e58ca83/
Hint:
Hint 1: ~~:>
Hint 2: Get index.php source !
Hint 3: Go home #mysql, you're drunk





Get the source code of index.php with the link http://42.117.7.116/web150_be56cb18b29a7b9dba9497d46e58ca83/index.php~

&lt?php
include 'connect.php';
$flag ="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
@error_reporting(1);
if(!isset($_GET['flag']))
{
print <<
&ltform method=GET&gt
&ltinput type=password name=flag&gt&lt/input&gt
&ltinput type=submit&gt&lt/input&gt
&lt/form&gt
FORM;
die;
} $input = sha1($_GET['flag'],true);
$this_is_baaad = array("or", "and", "not", "|","!","@","$","&","^","+","-","*", "select", "from", "where", "join", "sleep", ",", "(", ")", "'","=","\\","/",">","<","~");
foreach($this_is_baaad as $srsly)
{
if(stripos($input, $srsly) !== false)
{
print "Do not try to trick me!";
die;
}
}
##connect to mysql
$q = mysql_query("SELECT * FROM web100 WHERE flag = ".$input." and false",$link);//=]]]]]]
if(mysql_num_rows($q) >0)
{
print "Snowden: Thank you!! Super Mario: Here is the NSA flag: ".$flag;
}
else
{
print "You are the Fake Mario, not Super Mario!!!"."
";
system("sleep 2");
}
?&gt

So, it will sanitize our input by using sha1 function and put that sanitized input directly into sql query. That query is also very funny since it has "..and false" We might  never get the flag because of that logical operation; however we can bypass it easily with comment syntax.
Back to see what this code check the input. Almost important SQLi keywords are in the blacklist ($this_is_baaad) except # . wow, this is a comment syntax. there must be a coder's mistake. We can inject # to exploit that query but how we can put character # in while sha1 encrypt everything we type. Examine that function carefully:
$input = sha1($_GET['flag'],true); <~ raw_output is true

In my mind, the query must be :
select * from web100 WHERE flag=xxxx# and false
Because there is no quote before and after the input in that query, the flag in that sql query should be an integer.  After getting some suggestions from Xchym, I realize that what i supposed is totally wrong and I passed this challenge accidentally.
Some useful links related to this cast:
http://dev.mysql.com/doc/refman/5.5/en/comparison-operators.html#operator_equal
 http://dev.mysql.com/doc/refman/5.0/en/cast-functions.html

In this case, mysql will convert a string to a numeric value before doing any operations.
For example:
select 'abc' =0 -->this will return 1 because 'abc' will be converted to numeric value which is 0, then comparing between 0 and 0 will return true.
select '1abc' = 0 -> this will return 0 because '1abc' will be converted to 1, but select '0abc' = 0  will return 1 because '0abc' will be converted to 0 and
select '1abc' =1 will also return 1 because '1abc' will be converted to 1

Hence, to bypass this challenge, we need  some possible values:
0#
1#
2#
.
.
.
10#
11#
..

We crate a bruteforce to see which hash contain our possible value.
However, in this ctf, we know the format of the flag is mario_xxxx; therefore only 0# is satisfied and it is only what we need.
Try with 0#
&lt? php for($bf=0; $bf<10000000 bf="" br="">    $pwn = sha1($bf, TRUE); // return 20 chars
    if( (substr($pwn,0,2)=="0#"))
    {       
        $i++;
        if ($i==10) break; //just need only some results
        echo "$bf&ltbr&gt";
    }
}
?>

After getting some numbers which hash contain 0#, try them with our challenges anddone.

No comments:

Post a Comment