5.3.3 变量的编码与解码
一个WEB程序很多功能的实现都需要变量的编码解码,而且就在这一转一解的传递过程中
就悄悄的绕过你的过滤的安全防线。
这个类型的主要函数有:
1) stripslashes() 这个其实就是一个decode-addslashes()
2) 其他字符串转换函数:
base64_decode -- 对使用 MIME base64 编码的数据进行解码
base64_encode -- 使用 MIME base64 对数据进行编码
rawurldecode -- 对已编码的 URL 字符串进行解码
rawurlencode -- 按照 RFC 1738 对 URL 进行编码
urldecode -- 解码已编码的 URL 字符串
urlencode -- 编码 URL 字符串
......
(另外一个 unserialize/serialize)
3) 字符集函数(GKB,UTF7/8...)如iconv()/mb_convert_encoding()等
目前很多漏洞挖掘者开始注意这一类型的漏洞了,如典型的urldecode:
--code-------------------------------------------------------------------------
$sql = "SELECT * FROM article WHERE articleid='".urldecode($_GET[id])."'";
-------------------------------------------------------------------------------
当magic_quotes_gpc=on时,我们提交?id=%2527,得到sql语句为:
--code-------------------------------------------------------------------------
SELECT * FROM article WHERE articleid='''
-------------------------------------------------------------------------------
+++++++++++++++++++++++++
漏洞审计策略
-------------------------
PHP版本要求:无
系统要求:无
审计策略:查找对应的编码函数
+++++++++++++++++++++++++
5.3.4 二次攻击(详细见附录[1])
1) 数据库出来的变量没有进行过滤
2) 数据库的转义符号:
* mysql/oracle转义符号同样是\(我们提交'通过魔术引号变化为\',当我们update进入数
据库时,通过转义变为')
* mssql的转义字符为'(所以我们提交'通过魔术引号变化为\',mssql会把它当为一个字符
串直接处理,所以魔术引号对于mssql的注射没有任何意义)
从这里我们可以思考得到一个结论:一切进入函数的变量都是有害的,另外利用二次攻击
我们可以实现一个webrootkit,把我们的恶意构造直接放到数据库里。我们应当把这样的代
码看成一个vul?
+++++++++++++++++++++++++
漏洞审计策略
-------------------------
PHP版本要求:无
系统要求:无
审计策略:通读代码
+++++++++++++++++++++++++
5.3.5 魔术引号带来的新的安全问题
首先我们看下魔术引号的处理机制:
[\-->\\,'-->\',"-->\",null-->\0]
这给我们引进了一个非常有用的符号“\”,“\”符号不仅仅是转义符号,在WIN系统下也是
目录转跳的符号。这个特点可能导致php应用程序里产生非常有意思的漏洞:
1) 得到原字符(',\,",null])
--code-------------------------------------------------------------------------
$order_sn=substr($_GET['order_sn'], 1);
//提交 '
//魔术引号处理 \'
//substr '
$sql = "SELECT order_id, order_status, shipping_status, pay_status, ".
" shipping_time, shipping_id, invoice_no, user_id ".
" FROM " . $ecs->table('order_info').
" WHERE order_sn = '$order_sn' LIMIT 1";
-------------------------------------------------------------------------------
2) 得到“\”字符
--code-------------------------------------------------------------------------
$order_sn=substr($_GET['order_sn'], 0,1);
//提交 '
//魔术引号处理 \'
//substr \
$sql = "SELECT order_id, order_status, shipping_status, pay_status, ".
" shipping_time, shipping_id, invoice_no, user_id ".
" FROM " . $ecs->table('order_info').
" WHERE order_sn = '$order_sn' and order_tn='".$_GET['order_tn']."'";
-------------------------------------------------------------------------------
提交内容:
--code-------------------------------------------------------------------------
?order_sn='&order_tn=%20and%201=1/*
-------------------------------------------------------------------------------
执行的SQL语句为:
--code-------------------------------------------------------------------------
SELECT order_id, order_status, shipping_status, pay_status, shipping_time,
shipping_id, invoice_no, user_id FROM order_info WHERE order_sn = '\' and
order_tn=' and 1=1/*'
-------------------------------------------------------------------------------
+++++++++++++++++++++++++
漏洞审计策略
-------------------------
PHP版本要求:无
系统要求:无
审计策略:查找字符串处理函数如substr或者通读代码
+++++++++++++++++++++++++
5.3.6 变量key与魔术引号
我们最在这一节的开头就提到了变量key,PHP的魔术引号对它有什么影响呢?
--code-------------------------------------------------------------------------
<?php
//key.php?aaaa'aaa=1&bb'b=2
//print_R($_GET);
foreach ($_GET AS $key => $value)
{
print $key."\n";
}
?>
-------------------------------------------------------------------------------
1) 当magic_quotes_gpc = On时,在php5.24下测试显示:
aaaa\'aaa
bb\'b
从上面结果可以看出来,在设置了magic_quotes_gpc = On下,变量key受魔术引号影响。
但是在php4和php<5.2.1的版本中,不处理数组第一维变量的key,测试代码如下:
--code-------------------------------------------------------------------------
<?php
//key.php?aaaa'aaa[bb']=1
print_R($_GET);
?>
-------------------------------------------------------------------------------
结果显示:
Array ( [aaaa'aaa] => Array ( [bb\'] => 1 ) )
数组第一维变量的key不受魔术引号的影响。
+++++++++++++++++++++++++
漏洞审计策略
-------------------------
PHP版本要求:php4和php<5.2.1
系统要求:无
审计策略:通读代码
+++++++++++++++++++++++++
2) 当magic_quotes_gpc = Off时,在php5.24下测试显示:
aaaa'aaa
bb'b
对于magic_quotes_gpc = Off时所有的变量都是不安全的,考虑到这个,很多程序都通过
addslashes等函数来实现魔术引号对变量的过滤,示例代码如下:
--code-------------------------------------------------------------------------
<?php
//keyvul.php?aaa'aa=1'
//magic_quotes_gpc = Off
if (!get_magic_quotes_gpc())
{
$_GET = addslashes_array($_GET);
}
function addslashes_array($value)
{
return is_array($value) ? array_map('addslashes_array', $value) : addslashes($value);
}
print_R($_GET);
foreach ($_GET AS $key => $value)
{
print $key;
}
?>
-------------------------------------------------------------------------------
以上的代码看上去很完美,但是他这个代码里addslashes($value)只处理了变量的具体
的值,但是没有处理变量本身的key,上面的代码显示结果如下:
Array
(
[aaa'aa] => 1\'
)
aaa'aa
+++++++++++++++++++++++++
漏洞审计策略
-------------------------
PHP版本要求:无
系统要求:无
审计策略:通读代码
+++++++++++++++++++++++++
5.4 代码注射
5.4.1 PHP中可能导致代码注射的函数
很多人都知道eval、preg_replace+/e可以执行代码,但是不知道php还有很多的函数可
以执行代码如:
assert()
call_user_func()
call_user_func_array()
create_function()
变量函数
...
这里我们看看最近出现的几个关于create_function()代码执行漏洞的代码:
--code-------------------------------------------------------------------------
<?php
//how to exp this code
$sort_by=$_GET['sort_by'];
$sorter='strnatcasecmp';
$databases=array('test','test');
$sort_function = ' return 1 * ' . $sorter . '($a["' . $sort_by . '"], $b["' . $sort_by . '"]);
';
usort($databases, create_function('$a, $b', $sort_function));
-------------------------------------------------------------------------------
+++++++++++++++++++++++++
漏洞审计策略
-------------------------
PHP版本要求:无
系统要求:无
审计策略:查找对应函数(assert,call_user_func,call_user_func_array,create_function等)
+++++++++++++++++++++++++
5.4.2 变量函数与双引号
对于单引号和双引号的区别,很多程序员深有体会,示例代码:
--code-------------------------------------------------------------------------
echo "$a\n";
echo '$a\n';
-------------------------------------------------------------------------------
我们再看如下代码:
--code-------------------------------------------------------------------------
//how to exp this code
if($globals['bbc_email']){
$text = preg_replace(
array("/\[email=(.*?)\](.*?)\[\/email\]/ies",
"/\[email\](.*?)\[\/email\]/ies"),
array('check_email("$1", "$2")',
'check_email("$1", "$1")'), $text);
-------------------------------------------------------------------------------
另外很多的应用程序都把变量用""存放在缓存文件或者config或者data文件里,这样很
容易被人注射变量函数。
+++++++++++++++++++++++++
漏洞审计策略
-------------------------
PHP版本要求:无
系统要求:无
审计策略:通读代码
+++++++++++++++++++++++++