快速业务通道

PHP泛安全

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-05-22
ream = php_stream_open_wrapper(opt, "a", IGNORE_URL | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
if (!stream)
return FAILURE;
php_stream_write(stream, message, strlen(message));
php_stream_close(stream);
break;
default:
php_log_err(message TSRMLS_CC);
break;
}
return SUCCESS;
}

可以看到error_log函数的核心就是 php_stream_open_wrapper()函数,问题也就出在保存错误信息的文件这一步,看下这个函数的语法:

php_stream * php_stream_open_wrapper ( char * path, char * mode, int options, char ** opened )
php_stream_open_wrapper() opens a stream on the file, URL or other wrapped resource specified by path.
r
Open text file for reading. The stream is positioned at the beginning of the file.
r+
Open text file for reading and writing. The stream is positioned at the beginning of the file.
w
Truncate the file to zero length or create text file for writing. The stream is positioned at the beginning of the file.
w+
Open text file for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file.
a
Open for writing. The file is created if it does not exist. The stream is positioned at the end of the file.
a+
Open text file for reading and writing. The file is created if it does not exist. The stream is positioned at the end of the file.

error_log函数里定义了a选项,就是检查当保存错误信息文件不存在时创建一个,到这都没问题,关键是后面:

IGNORE_URL | ENFORCE_SAFE_MODE | REPORT_ERRORS

如果定义了一个IGNORE_URL那么将关闭后面的SAFE_MODE 开关,这样如果把错误信息写成代码,后面加上如prefix://../../的URL,则代码被写入到一个PHP文件时就已经绕过了SAFE_MODE 的限制,再访问保存错误信息的文件则代码被顺利无限制的执行了.

归根结底漏洞产生于php_stream_open_wrapper()函数,然后被嵌套调用了.

还有一个以前的的copy函数bypass漏洞

$temp=tempnam($tymczas, "cx");
if(copy("compress.zlib://".$file, $temp)){
$handle = fopen($temp, "r");
$tekst = fread($handle, filesize($temp));
fclose($handle);

通过这样一段利用代码再指定一个$file就可以绕过安全模式读取任何文件了

漏洞的存在都是互相映射的,应用层的漏洞在底层也会出现,就象上面这些逻辑类的,那应用层最容易疏忽的过滤不严的漏洞在底层会出现吗?当然!看看tempnam()函数中的一段核心代码:

if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) ==
FAILURE) {
 WRONG_PARAM_COUNT;
}
convert_to_string_ex(arg1);
convert_to_string_ex(arg2);
if (php_check_open_basedir(Z_STRVAL_PP(arg1) TSRMLS_CC)) {
 RETURN_FALSE;
}
d = estrndup(Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1));
strlcpy(p, Z_STRVAL_PP(arg2), sizeof(p));

开始的函数原型给出了,第1个参数是指定生成临时文件的目录,第2个参数是生成临时文件的前缀.开始是对两个参数类型的检查及定义,然后对参数做限制,问题就出在红色代码处这个函数:php_check_open_basedir()是用来检查参数完整性并检查接受到的目录参数是否在open-basedir内,也就是按说我们对tempnam()传递参数后是不能在这个参数之外的目录生成临时文件了,可是居然函数只限制了arg1,没有过滤arg2,这样一来前面的限制就不会起作用了,然后后面就把arg2的参数附加给arg1了.接着就导致可以绕过openbase_dir的限制写文件

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号