1. Bypass due to lack of thinking
Problem Solving Path: http://ctf5.shiyanbar.com/web/pcat/index.php
Open after is a login box similar things, view the page source code can see the word source:source.txt
Open Connection: Http://ctf5.shiyanbar.com/web/pcat/source.txt
You can see the PHP logic for logging in:
<?php error_reporting (0); if (!isset ($_post[' uname ')) | |!isset ($_post[' pwd ']) {echo ' <form action= ' "method=" POST ">". "
<br/> "; Echo ' <input name= "uname" type= "text"/> '. "
<br/> "; Echo ' <input name= "pwd" type= "text"/> '. "
<br/> "; Echo ' <input type= ' submit "/> '."
<br/> "; Echo ' </form> '.
<br/> "; Echo ' <!--source:source.txt--> '.
<br/> ";
Die
} function Attackfilter ($StrKey, $StrValue, $ArrReq) {if (Is_array ($StrValue)) {$StrValue =implode ($StrValue); } if (Preg_match ("/". $ArrReq. "
/is ", $StrValue) ==1) {print" Matthews village dress qi Borrow 垷 锛 Imperial harm Å è¡#̈亞 禌 鑹 granary Dev ";
Exit ();
}} $filter = "and|select|from|where|union|join|sleep|benchmark|,|\ (|\)";
foreach ($_post as $key = $value) {attackfilter ($key, $value, $filter);}
$con = mysql_connect ("XXXXXX", "XXXXXX", "XXXXXX");
if (! $con) {die (' Could not connect: '. Mysql_error ());} $db = "XXXXXX";
mysql_select_db ($db, $con); $sql = "SELECT * FROM Interest wherE uname = ' {$_post[' uname ']} ';
$query = mysql_query ($sql);
if (mysql_num_rows ($query) = = 1) {$key = Mysql_fetch_array ($query);
if ($key [' pwd '] = = $_post[' pwd ') {print "ctf{xxxxxx}";
}else{print "Bang ﹀ dress bi did imagery 锛"; }}else{print "Juan € Hammer list 禌 鑹 granary dev";} mysql_close ($con);?>
As you can see, there is a filter in SQL that filters out some SQL keywords such as benchmark,join and so on.
and the SQL query statement is:
SELECT * from interest WHERE uname = ' {$_post[' uname ']}
Also by:
Mysql_num_rows ($query) = = 1
This judgment can be learned that there is only one record in the database, this part of the logic is probably then through the submission of the uname query results, if only one of the results continue, if the PWD field in the query results and post past key value is the same, the flag is given.
This is a trick to inject, we use GROUP by PWD with rollup to add a row after the query result, and the value of this line of the PWD field is null
In the official MySQL document, this describes the rollup function:
The idea is to use with rollup in the GROUP BY clause to add a row to the database to calculate the total number, the more detailed use of the ROLLUP clause, you can refer to the official MySQL documentation, here is not much to do.
Combine limit and offset to write a payload
That is: The user name entered is: ' or 1=1 GROUP by PWD with rollup limit 1 Offset 2 #
Here is an explanation of the SQL executed at this point:
SELECT * from interest where uname= ' or 1=1
GROUP by PWD with rollup (add a row in the database to make Pwd=null)
Limit 1 (query only one row)
Offset 2 (query from second line)
#注释
The password can be queried successfully as long as it is empty
2. Just log in, OK?
Problem Solving Path: http://ctf5.shiyanbar.com/web/wonderkun/web/index.html
The topic says this filters a lot of sensitive symbols, so first constructs the commonly used payload: ' or 1=1 #
The discovery of OR and #都被过滤掉了, through test discovery-also filtered, looks scary, but fortunately ' not filtered, so constructs payload:
Username = Travis ' = '
Password=travis ' = '
This time, the result was flag.
Why this can be bypassed.
When submitting username=travis ' = ' &password=travis ' = '
The statement will become as follows:
SELECT * from user where username= ' travis ' = ' and password= ' travis ' = '
This time is not clear enough, I extract the previous paragraph of judgement (the same reason behind)
Username= ' travis ' = '
This is a 2 equal sign, then the order of calculation is left to right,
Calculate username= ' Travis ' in the general database can not have my nickname (if any, you will change a string), so here the return value is 0 (equivalent to false)
Then 0 = "the result." See here The estimate you also understand, just return 1 (equivalent to TRUE)
So this injection is equivalent to
SELECT * from user where 1 and 1
Also equals select * from user
(This problem is only filtered out of the results of more than 3 to show flag, did not always say "sorry, no this user. ”)
The comparison of the surface is a weak type of comparison,
The following conditions will be true
1= ' 1 '
1= ' 1.0 '
1= ' 1 followed by a letter (and then a number can also be) '
0= ' except for strings that start with a non-0 digit '
(Overall, as long as the previous 0, to make the statement is true is very simple, so this question of the universal password as long as I have the above way to write a lot)