ThinkPHP 5.1.x~5.2.x全版本 RCE 漏洞分析

  • 2019 年 10 月 8 日
  • 筆記

大概看了下,這個洞跟5.0的原理大致相同,都是利用Reuqest類的Method方法覆蓋了 $this->filter屬性,然後進入 filterValue調用 call_user_func($filter,$value)$value當前請求參數和URL地址中的參數合併,從而導致RCE。

漏洞驗證

測試版本:Thinkphp_5.1.1 修補程式:https://github.com/top-think/framework/commit/2454cebcdb6c12b352ac0acd4a4e6b25b31982e6 需要在入口文件處關閉報錯。

payload

c=exec&f=calc.exe&&_method=filter&

流程分析

在獲取應用調度資訊時會調用Request類的method方法獲取當前的請求類型

$this->config->get('var_method')外部可控,即 $this->method我們可控,從而我們可以通過 $this->{$this->method}($_POST)調用任意方法。

跟進 filter方法,發現我們post的數據可以覆蓋 $this->filter屬性。

回到App類,由於我們開啟了 $this->debug從而可以進入 Request類的 param方法。

跟進 param方法, $this->param當前請求參數和URL地址中的參數合併。然後進入 input方法。

跟進 input方法,因為 $data為上面提到的 $this->param即數組,從而進入if條件執行 array_walk_recursive($data,[$this,'filterValue'],$filter);

查閱 array_walk_recursive函數可知,該函數會調用 $this->filterValue函數,把 $data數組的每個值作為其第一個參數,鍵名作為第二個參數,並且把 $this->filter作為第三個參數。

繼續跟進 filterValue方法,發現調用了 call_user_func($filter,$value)$filter為剛開始我們覆蓋的 $this->filter屬性的遍歷鍵值,等於 $_POST數組。 $value當前請求參數和URL地址中的參數合併數組 $this->param的鍵值。

當遍歷到 $this->param的第二個鍵值 calc.exe$filters的第一個鍵值 exec時,成功執行命令,彈出了計算器。

修補程式分析

與5.0一樣,對錶單請求類型偽裝變數添加了白名單。