[PCH-009]Security risk of php string offset by ryat_at_www.80vul.com 一、前言[关于PCH] "PCH"及"Php Codz Hacking"是80vul在2009年4月推出的一个项目,主要是在php源代码的基 础分析和探讨一些可以给php应用安全带来影响的'特性'或者'漏洞'。这个项目最早起源于 webzine 0x3里的《高级PHP应用程序漏洞审核技术》[1]: * 分析php源代码,发现新的漏洞函数“特性”或者漏洞。(在上一节里介绍的那些“漏洞审 计策略”里,都没有php源代码的分析,如果你要进一步找到新的字典,可以在php源代码的 基础上分析下成因,然后根据这个成因来分析寻找新的漏洞函数“特性”或者漏洞。) 而本文就是PCH的一篇,在php的代码基础上分析PHP字符串offset一个可以给PHP应用程序带 来安全风险的小"特性"... 二、PHP String Offset 先来看看手册中关于字符串offset取值特性的一段描述[详见[2]]: String access and modification by character Characters within strings may be accessed and modified by specifying the zero-based offset of the desired character after the string using square array brackets, as in $str[42]. Think of a string as an array of characters for this purpose. The functions substr() and substr_replace() can be used when you want to extract or replace more than 1 character. Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose. 通过这个特性可以很方便的对字符串进行修改或者取值等操作,比如下面的代码: $xigr = 'ryat'; echo $xigr[0]; // echo r 再看看这段代码: echo $xigr['hi']; // echo r 为什么对于字符串$xigr来说,$xigr[0]和$xigr['hi']取得值是一样的呢?让我们来看看PHP部 分源码... 三、PHP源码分析: // zend_execute.c static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC) { zval *container = *container_ptr; zval **retval; switch (Z_TYPE_P(container)) { ... case IS_STRING: { zval tmp; if (type != BP_VAR_UNSET && Z_STRLEN_P(container)==0) { goto convert_to_array; } if (dim == NULL) { zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); } if (Z_TYPE_P(dim) != IS_LONG) { switch(Z_TYPE_P(dim)) { /* case IS_LONG: */ case IS_STRING: case IS_DOUBLE: case IS_NULL: case IS_BOOL: /* do nothing */ break; default: zend_error(E_WARNING, "Illegal offset type"); break; } tmp = *dim; zval_copy_ctor(&tmp); convert_to_long(&tmp); dim = &tmp; ... 上面的代码片段可以看出,对于$xigr['hi']这种形式的字符串,在offset取值时键值会被转换 为整形,也就是等同于$xigr[0]这种形式:) 四、带来的应用安全风险 虽然这是一个很方便的特性,但是如果开发者对这个特性没有充分的认识或者忽视的时候,就 可以给应用程序带来灾难性的安全漏洞。这个主要体现开发者在处理数组变量名时没有指定 变量类型,当这个数组变量被恶意提交字符类型来取值,导致的一些安全风险。 1、绕过某些条件判断 如在phpspy2006的代码在判断登录时使用了如下条件判断: $admin['check'] = "1"; $admin['pass'] = "angel"; ...... if($admin['check'] == "1") { .... } $admin没有被初始定义为数组类型,那么当我们用字符串提交时phpsyp.php?admin=1xxx时, php会取字符串1xxx的第一位,成功绕过if的条件判断。 [PS:此漏洞是由80vul的saiy发现的,thx] 2、"魔术引号带来的新的安全问题" 在《高级PHP应用程序漏洞审核技术》[1]一文里的"魔术引号带来的新的安全问题"一节里,有 提到通过提取魔术引号产生的“”字符带来的安全问题,同样这个问题在这里又一次完美体 现,如下面的代码片段: // foo.php?xigr='ryat function daddslashes($string, $force = 0) { !defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc()); if(!MAGIC_QUOTES_GPC || $force) { if(is_array($string)) { foreach($string as $key => $val) { $string[$key] = daddslashes($val, $force); } } else { $string = addslashes($string); } } return $string; } ... foreach(array('_COOKIE', '_POST', '_GET') as $_request) { foreach($$_request as $_key => $_value) { $_key{0} != '_' && $$_key = daddslashes($_value); } } echo $xigr['hi']; // echo 上面的代码原本期望得到一个经过daddslashes()安全处理后的数组变量$xigr['hi'],但是没 有对变量$xigr做严格的类型规定,当我们提交一个字符串变量$xigr='ryat,经过上面的处理 变为'ryat,到最后$xigr['hi']就会输出,如果这个变量引入到SQL语句,那么就会引起严重 的安全问题了,再来看下面的代码片段: ... if($xigr) { foreach($xigr as $k => $v) { $uids[] = $v['uid']; } $query = $db->query("SELECT uid FROM users WHERE uid IN ('".implode("','", $uids)."')"); 利用上面提到的思路,通过提交foo.php?xigr[]='&xigr[][uid]=evilcode这样的构造形式可 以很容易的突破GPC或类似的安全处理,形成SQL注射漏洞:D 五、后话 上面的例子再一次说明努力挖掘PHP本身的特性或者漏洞才是PHP应用安全的主要出路。另外 还有一句话送给各位看官“虫子永远属于那些有想法勤劳的小鸟”。 六、参考 [1]http://code.google.com/p/pasc2at/wiki/SimplifiedChinese [2]:http://php.net/manual/en/language.types.string.php -EOF-
转自:http://www.80vul.com/webzine_0x06/PSTZine_0x06_0x03.txt
文章来源于lcx.cc:[PCH-009] Security risk of php string offset
0x00 目录 0x01 链接的构成 0x02 浏览器算如何对url进行解析的 0x03 链接真的只能是这样固定的格式么? 0x04 链接真的是你看到的那样么? 0x01 链接的构成 链接真的只能固定成我们常用的格式么? 不知道有多少人思考过这个问题!我们经常…
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论