海豚命令執行復現

語言: CN / TW / HK

概述

想復現命令執行的漏洞,情不知所起,來漏洞庫看看。就這個哥們了。開始下載安裝。

安裝

安裝效果圖

前臺

後臺

驗證

點選進去發現,命令執行,,,還是tp5。不就是那個RCE嗎。。來來,上個payload看效果。

流程梳理

那就帶大家看看程式碼流程圖吧。首先分析下這個payload,\think\app這個是類檔案,invokefunction這個是方法名,後面的都是引數。打斷點發請求,過程如下圖所示:

圖中的這段程式碼,反射的高階用法,觸發函式呼叫。也就是call_user_func_array這個方法,此方法呼叫說明如下:

/**
* Call a user function given with an array of parameters
* @link https://php.net/manual/en/function.call-user-func-array.php
* @param callback $function <p>
* The function to be called.
* </p>
* @param array $param_arr <p>
* The parameters to be passed to the function, as an indexed array.
* </p>
* @return mixed the function result, or false on error.
* @since 4.0.4
* @since 5.0
*/function call_user_func_array ($function, array $param_arr) {}
第一個引數傳入的system方法。這個方法呼叫說明如下:
/**
* Execute an external program and display the output
* @link https://php.net/manual/en/function.system.php
* @param string $command <p>
* The command that will be executed.
* </p>
* @param int $return_var [optional] <p>
* If the return_var argument is present, then the
* return status of the executed command will be written to this
* variable.
* </p>
* @return string|false the last line of the command output on success, and false
* on failure.
* @since 4.0
* @since 5.0
*/function system ($command, &$return_var = null) {}
接著給system傳入的系統命令whoami/ls作為驗證判斷條件,在驗證環節,就出來了計算機當前使用者。

重點

程式碼看著賊簡單,但是要明白裡面的訪問方式,這個就得聊聊了。同時也會明白為什麼會產生這樣的漏洞。

在tp裡,如果你訪問了一個不存在的類檔案時,系統會幫助使用者搜尋載入,通過這個spl_autoload_register函式。如下程式碼:

  // 註冊自動載入機制
public static function register($autoload = '')
{ // 註冊系統自動載入
spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true); // 註冊名稱空間定義
self::addNamespace([ 'think' => LIB_PATH . 'think' . DS, 'behavior' => LIB_PATH . 'behavior' . DS, 'traits' => LIB_PATH . 'traits' . DS,
]); // 載入類庫對映檔案
if (is_file(RUNTIME_PATH . 'classmap' . EXT)) { self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT));
} // Composer自動載入支援
if (is_dir(VENDOR_PATH . 'composer')) { self::registerComposerLoader();
} // 自動載入extend目錄
self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);
}

從過控制器和方法名的轉換,解析url中的引數,最終例項出APP的類,呼叫invokefunction方法。

其中Loader::parseName($controller, 1)方法,這個可以控制這種直接傳遞名稱空間的引數,

 /**
* 字串命名風格轉換
* type 0 將Java風格轉換為C的風格 1 將C風格轉換為Java的風格
* @param string $name 字串
* @param integer $type 轉換型別
* @param bool $ucfirst 首字母是否大寫(駝峰規則)
* @return string
*/
public static function parseName($name, $type = 0, $ucfirst = true)
{ if ($type) {
$name = preg_replace_callback('/_([a-zA-Z])/', function ($match) { return strtoupper($match[1]);
}, $name); return $ucfirst ? ucfirst($name) : lcfirst($name);
} else { return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
}
}
方法中只匹配了/_([a-zA-Z])/的正則,反斜線過濾掉,就可以防止這種rce的執行。看一下官方的處理方式:

它這種就是檢驗這種直接傳遞名稱空間違規的方式,給過濾掉。載入位置:

再請求出現了正確的攔截:

這裡編號CNVD-2021-65112漏洞復現完成。

總結

記錄幾個RCE的涉及函式吧,積累後續挖掘的突破口,希望大家來補充!

  • array_walk_recursive

  • call_user_func

  • call_user_func_array

  • array_map()

  • preg_replace

  • array_filter()

    還有很多,,,常遇到頻率比較高的應該是前四個,沒有具體統計。感興趣的小夥伴,可以關注TIDE安全團隊,看下

    程式碼審計wiki,程式碼執行漏洞篇
    http://wiki.tidesec.com/docs/codeaudit/3d336f68c2686b738d86cd65e479173f

Tide安全團隊正式成立於2019年1月,是新潮資訊旗下以網際網路攻防技術研究為目標的安全團隊,團隊致力於分享高質量原創文章、開源安全工具、交流安全技術,研究方向覆蓋網路攻防、系統安全、Web安全、移動終端、安全開發、物聯網/工控安全/AI安全等多個領域。

團隊作為“省級等保關鍵技術實驗室”先後與哈工大、齊魯銀行、聊城大學、交通學院等多個高校名企建立聯合技術實驗室。 團隊公眾號自建立以來,共釋出原創文章400餘篇,自研平臺達到31個,目有18個平臺已開源。此外積極參加各類線上、線下CTF比賽並取得了優異的成績。如有對安全行業感興趣的小夥伴可以踴躍加入或關注我們