wordpress 读取副标题,15 企业网站优化方案有哪些内容,国外代理服务器免费,三室两厅装修高级PHP应用程序漏洞审核技术【一】
目录
高级PHP应用程序漏洞审核技术【一】 本文章向大家介绍高级PHP应用程序漏洞审核技术【一】#xff0c;主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项#xff0c;具有一定的参考价值#xff0c;需要的朋友可以参…高级PHP应用程序漏洞审核技术【一】
目录
高级PHP应用程序漏洞审核技术【一】 本文章向大家介绍高级PHP应用程序漏洞审核技术【一】主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项具有一定的参考价值需要的朋友可以参考一下。 前言
小编入门代码审计时看的几篇写的比较经典的PDF文档之一分享出来希望能帮助到想学习代码审计的小伙伴。 一、前言 PHP是一种被广泛使用的脚本语言尤其适合于web开发。具有跨平台容易学习功能强大等特点据统计全世界有超过34%的网站有php的应用包括Yahoo、sina、163、sohu等大型门户网站。而且很多具名的web应用系统包括bbs,blog,wiki,cms等等都是使用php开发的 Discuz、phpwind、phpbb、vbb、wordpress、boblog等等。随着web安全的热点升级php应用程序的代码安全问题也逐步兴盛起来越来越多的安全人员投入到这个领域越来越多的应用程序代码漏洞被披露。
针对这样一个状况很多应用程序的官方都成立了安全部门或者雇佣安全人员进行代码审计因此出现了很多自动化商业化的代码审计工具。也就是这样的形势导致了一个局面大公司的产品安全系数大大的提高那些很明显的漏洞基本灭绝了那些大家都知道的审计技术都无用武之地了。我们面对很多工具以及大牛扫描过n遍的代码有很多的安全人员有点悲观而有的官方安全人员也非常的放心自己的代码但是不要忘记了“没有绝对的安全”我们应该去寻找新的途径挖掘新的漏洞。本文就给介绍了一些非传统的技术经验和大家分享。 另外在这里特别说明一下本文里面很多漏洞都是来源于网络上牛人和朋友们的分享在这里需要感谢他们
二、传统的代码审计技术 WEB应用程序漏洞查找基本上是围绕两个元素展开变量与函数。也就是说一漏洞的利用必须把你提交的恶意代码通过变量经过n次变量转换传递最终传递给目标函数执行还记得MS那句经典的名言吗“一切输入都是有害的”。这句话只强调了变量输入
很多程序员把“输入”理解为只是gpc[$_GET,$_POST,$_COOKIE]但是变量在传递过程产生了n多的变化。导致很多过滤只是个“纸老虎”我们换句话来描叙下代码安全“一切进入函数的变量是有害的”。 PHP代码审计技术用的最多也是目前的主力方法静态分析主要也是通过查找容易导致安全漏洞的危险函数常用的如grepfindstr等搜索工具很多自动化工具也是使用正则来搜索这些函数。下面列举一些常用的函数也就是下文说的字典暂略。
但是目前基本已有的字典很难找到漏洞所以我们需要扩展我们的字典这些字典也是本文主要探讨的。 其他的方法有通过修改PHP源代码来分析变量流程或者hook危险的函数来实现对应用程序代码的审核但是这些也依靠了我们上面提到的字典。
三、PHP版本与应用代码审计 到目前为止PHP主要有3个版本php4、php5、php6使用比例大致如下php4 68%2000-2007No security fixes after 2008/08最终版本是php4.4.9、php5 32%、2004-presentNow at version 5.2.6PHP 5.3 alpha1 released!php6、目前还在测试阶段变化很多做了大量的修改取消了很多安全选项如magic_quotes_gpc。这个不是今天讨论的范围
由于php缺少自动升级的机制导致目前PHP版本并存也导致很多存在漏洞没有被修补。这些有漏洞的函数也是我们进行WEB应用程序代码审计的重点对象也是我们字典重要来源。
四、其他的因素与应用代码审计 很多代码审计者拿到代码就看他们忽视了“安全是一个整体”代码安全很多的其他因素有关系比如上面我们谈到的PHP版本的问题比较重要的还有操作系统类型主要是两大阵营win/*nixWEB服务端软件主要是iis/apache两大类型等因素。这是由于不同的系统不同的WEB SERVER有着不同的安全特点或特性下文有些部分会涉及。 所以我们在做某个公司WEB应用代码审计时应该了解他们使用的系统WEB服务端软件PHP版本等信息。
五、扩展我们的字典 下面将详细介绍一些非传统PHP应用代码审计一些漏洞类型和利用技巧。
5.1 变量本身的key 说到变量的提交很多人只是看到了GET/POST/COOKIE等提交的变量的值但是忘记了有的程序把变量本身的key也当变量提取给函数处理。 --code------------------------------------------------------------------------- ?php //key.php?aaaaaaa1bbb2 //print_R($_GET); foreach ($_GET AS $key $value) { print $key.n; } ? ------------------------------------------------------------------------------- 上面的代码就提取了变量本身的key显示出来单纯对于上面的代码如果我们提交URL --code------------------------------------------------------------------------- key.php?scriptalert(1);/script1bbb2 ------------------------------------------------------------------------------- 那么就导致一个xss的漏洞扩展一下如果这个key提交给include()等函数或者sql查询呢 漏洞审计策略 ------------------------- PHP版本要求无 系统要求无 审计策略通读代码
5.2 变量覆盖variable-overwrite 很多的漏洞查找者都知道extract()这个函数在指定参数为EXTR_OVERWRITE或者没有指定函数可以导致变量覆盖但是还有很多其他情况导致变量覆盖的如
5.2.1 遍历初始化变量 请看如下代码 --code------------------------------------------------------------------------- ?php //var.php?afuck $ahi; foreach($_GET as $key $value) { $$key $value; } print $a; ? ------------------------------------------------------------------------------- 很多的WEB应用都使用上面的方式注意循环不一定是foreach如Discuz!4.1的WAP部分的代码 --code------------------------------------------------------------------------- $chs ; if($_POST $charset ! utf-8) { $chs new Chinese(UTF-8, $charset); foreach($_POST as $key $value) { $$key $chs-Convert($value); } unset($chs); ------------------------------------------------------------------------------- 漏洞审计策略 ------------------------- PHP版本要求无 系统要求无 审计策略通读代码
5.2.2 parse_str()变量覆盖漏洞CVE-2007-3205、mb_parse_str() --code------------------------------------------------------------------------- //var.php?varnew $var init; parse_str($_SERVER[QUERY_STRING]); print $var; ------------------------------------------------------------------------------- 该函数一样可以覆盖数组变量上面的代码是通过$_SERVER[QUERY_STRING]来提取变量的对于指定了变量名的我们可以通过注射“”来实现覆盖其他的变量 --code------------------------------------------------------------------------- //var.php?var1a[1]var1%3d222 $var1 init; parse_str($a[$_GET[var]]); print $var1; ------------------------------------------------------------------------------- 上面的代码通过提交$var来实现对$var1的覆盖。 漏洞审计策略parse_str ------------------------- PHP版本要求无 系统要求无 审计策略查找字符parse_str 漏洞审计策略mb_parse_str ------------------------- PHP版本要求php44.4.7 php55.2.2 系统要求无 审计策略查找字符mb_parse_str
5.2.3 import_request_variables()变量覆盖漏洞CVE-2007-1396 --code------------------------------------------------------------------------- //var.php?_SERVER[REMOTE_ADDR]10.1.1.1 echo GLOBALS .(int)ini_get(register_globals).n; import_request_variables(GPC); if ($_SERVER[REMOTE_ADDR] ! 10.1.1.1) die(Go away!); echo Hello admin!; ------------------------------------------------------------------------------- 漏洞审计策略import_request_variables ------------------------- PHP版本要求php44.4.1 php55.2.2 系统要求无 审计策略查找字符import_request_variables
5.2.4 PHP5 Globals 从严格意义上来说这个不可以算是PHP的漏洞只能算是一个特性测试代码 --code------------------------------------------------------------------------- ? // register_globals ON //foo.php?GLOBALS[foobar]HELLO php echo $foobar; ? ------------------------------------------------------------------------------- 但是很多的程序没有考虑到这点请看如下代码 --code------------------------------------------------------------------------- //为了安全取消全局变量 //var.php?GLOBALS[a]aaaab111 if (ini_get(register_globals)) foreach($_REQUEST as $k$v) unset(${$k}); print $a; print $_GET[b]; ------------------------------------------------------------------------------- 如果熟悉WEB2.0的攻击的同学很容易想到上面的代码我们可以利用这个特性进行crsf 攻击。 漏洞审计策略 ------------------------- PHP版本要求无 系统要求无 审计策略通读代码 5.3 magic_quotes_gpc与代码安全
5.3.1 什么是magic_quotes_gpc 当打开时所有的 单引号双引号反斜线和 NULL 字符都会被自动加上一个反斜线进行转义。还有很多函数有类似的作用 如addslashes()、mysql_escape_string()、 mysql_real_escape_string()等另外还有parse_str()后的变量也受magic_quotes_gpc的影响。目前大多数的主机都打开了这个选项并且很多程序员也注意使用上面那些函数去过滤变量这看上去很安全。很多漏洞查找者或者工具遇到些函数过滤后的变量直接就放弃但是就在他们放弃的同时也放过很多致命的安全漏洞。
5.3.2 哪些地方没有魔术引号的保护
1) $_SERVER变量 PHP5的$_SERVER变量缺少magic_quotes_gpc的保护导致近年来X-Forwarded-For的漏洞猛暴所以很多程序员考虑过滤X-Forwarded-For但是其他的变量呢 漏洞审计策略$_SERVER变量 ------------------------- PHP版本要求无 系统要求无 审计策略查找字符_SERVER 2) getenv()得到的变量使用类似$_SERVER变量 漏洞审计策略getenv() ------------------------- PHP版本要求无 系统要求无 审计策略查找字符getenv
3) $HTTP_RAW_POST_DATA与PHP输入、输出流主要应用与soap/xmlrpc/webpublish功能里请看如下代码 --code------------------------------------------------------------------------- if ( !isset( $HTTP_RAW_POST_DATA ) ) { $HTTP_RAW_POST_DATA file_get_contents( php://input ); } if ( isset($HTTP_RAW_POST_DATA) ) $HTTP_RAW_POST_DATA trim($HTTP_RAW_POST_DATA); ------------------------------------------------------------------------------- 漏洞审计策略数据流 ------------------------- PHP版本要求无 系统要求无 审计策略查找字符HTTP_RAW_POST_DATA或者php://input
4) 数据库操作容易忘记的地方如in()/limit/order by/group by 如Discuz!5.0的pm.php --code------------------------------------------------------------------------- if(is_array($msgtobuddys)) { $msgto array_merge($msgtobuddys, array($msgtoid)); ...... foreach($msgto as $uid) { $uids . $comma.$uid; $comma ,; } ...... $query $db-query(SELECT m.username, mf.ignorepm FROM {$tablepre}members m LEFT JOIN {$tablepre}memberfields mf USING(uid) WHERE m.uid IN ($uids)); ------------------------------------------------------------------------------- 漏洞审计策略 ------------------------- PHP版本要求无 系统要求无 审计策略查找数据库操作字符select,update,insert等等
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_gpcon时我们提交?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--] 这给我们引进了一个非常有用的符号“”“”符号不仅仅是转义符号在WIN系统下也是目录转跳的符号。这个特点可能导致php应用程序里产生非常有意思的漏洞 1) 得到原字符,,,null] --code------------------------------------------------------------------------- $order_snsubstr($_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_snsubstr($_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_snorder_tn%20and%2011/* ------------------------------------------------------------------------------- 执行的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 11/* ------------------------------------------------------------------------------- 漏洞审计策略 ------------------------- PHP版本要求无 系统要求无 审计策略查找字符串处理函数如substr或者通读代码
5.3.6 变量key与魔术引号
我们最在这一节的开头就提到了变量keyPHP的魔术引号对它有什么影响呢
--code-------------------------------------------------------------------------
?php
//key.php?aaaaaaa1bbb2
//print_R($_GET);
foreach ($_GET AS $key $value)
{
print $key.n;
}
?
-------------------------------------------------------------------------------
1) 当magic_quotes_gpc On时在php5.24下测试显示
aaaaaaabbb从上面结果可以看出来在设置了magic_quotes_gpc On下变量key受魔术引号影响。但是在php4和php5.2.1的版本中不处理数组第一维变量的key测试代码如下
--code-------------------------------------------------------------------------
?php
//key.php?aaaaaaa[bb]1
print_R($_GET);
?
-------------------------------------------------------------------------------
结果显示:
Array ( [aaaaaaa] Array ( [bb] 1 ) )
数组第一维变量的key不受魔术引号的影响。漏洞审计策略
-------------------------
PHP版本要求php4和php5.2.1
系统要求无
审计策略通读代码2) 当magic_quotes_gpc Off时在php5.24下测试显示
aaaaaaabbb对于magic_quotes_gpc Off时所有的变量都是不安全的考虑到这个很多程序都通过addslashes等函数来实现魔术引号对变量的过滤示例代码如下
--code-------------------------------------------------------------------------
?php
//keyvul.php?aaaaa1
//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
(
[aaaaa] 1
)
aaaaa漏洞审计策略
-------------------------
PHP版本要求无
系统要求无
审计策略通读代码