這道題真的是漲了我的知識,也確實interesting
而且章喉,因為我想要加大刷題的量搜锰,不想碼字占用我太多的時間伴郁,所以未來的writeup
的格式可能會很簡陋,但是一定會有重點蛋叼,會有該有的東西焊傅。
開始~
題目:http://ctf5.shiyanbar.com/web/pcat/index.php
首先,還是web題的老套路狈涮,抓包狐胎,看源碼,找hint歌馍,審計代碼......
我們在網(wǎng)頁的注釋中發(fā)現(xiàn)了source.txt
里面放著源碼握巢,然后開始審計:
<?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 "水可載舟,亦可賽艇松却!";
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 "亦可賽艇暴浦!";
}
}else{
print "一顆賽艇!";
}
mysql_close($con);
?>
比較引人注意的是玻褪,這次的過濾肉渴,很全面,把我們常規(guī)思路大概都過濾掉了带射。
而且同规,后面的mysql_num_rows($query) == 1
也讓我們看不到結(jié)果,于是沒有辦法,我只能猜測是基于時間的盲注券勺,但是我們發(fā)現(xiàn)sleep
benchmark
以及括號都被過濾了绪钥。而且,就算前面的限制都過去关炼,你也不知道pwd程腹。
那么,這是用到了sql語句中的一個叫做rollup
的東西儒拂,他是用在groupby
后進(jìn)行數(shù)據(jù)統(tǒng)計的寸潦,與他類似的有一個叫做cube
的,他和rollup
的不同之處也就是我們要利用的地方社痛,講道理见转,用cube
也是可以的,因為對于單一分組來說蒜哀,也就一組數(shù)據(jù)報表斩箫。但是嘗試發(fā)現(xiàn)不可以,這里不知道為什么撵儿。
rollup
和cube
呢乘客,其實就是groupby
的一個擴(kuò)展功能,叫做超級聚合淀歇,也就是對于分組數(shù)據(jù)進(jìn)行一下統(tǒng)計報表易核。講道理他是和聚合函數(shù)連用的,來產(chǎn)生一個合計
的數(shù)據(jù)浪默,但是耸成,同時他也會產(chǎn)生一個NULL的數(shù)據(jù)。
后來浴鸿,我想了一下,為什么是這樣呢弦追?
首先岳链,我們構(gòu)造的sql里面groupby 卻沒有聚合,所以得到的就是單獨的一列內(nèi)容劲件,然后在這單獨的一列上rollup得到的就是null
所以掸哑,只要我們的password不傳值進(jìn)去,我們就通過驗證了零远。