【php精品源码栏目提醒】:以下是网学会员为您推荐的php精品源码-【精品】高级PHP应用程序漏洞审核技术 - 其它资料,希望本篇文章对您学习有所帮助。
高级
PHP应用程序漏洞审核技术 o 前言 o 传统的代码审计技术 o
PHP版本与应用代码审计 o 其他的因素与应用代码审计 o 扩展我们的字典 变量本身的key 变量覆盖 遍历初始化变量 parse_str变量覆盖漏洞 import_request_variables变量覆盖漏洞
PHP5 Globals magic_quotes_gpc与代码安全 什么是magic_quotes_gpc 哪些地方没有魔术引号的保护 变量的编码与解码 二次攻击 魔术引号带来的新的安全问题 变量key与魔术引号 代码注射
PHP中可能导致代码注射的函数 变量函数与双引号
PHP自身函数漏洞及缺陷
PHP函数的溢出漏洞
PHP函数的其他漏洞 session_destroy删除文件漏洞 随机函数 特殊字符 截断 include截断 数据截断 文件操作里的特殊字符 o 怎么进一步寻找新的字典 o DEMO o 后话 o 附录前言
PHP 是一种被广泛使用的脚本语言,尤其适合于 web 开发。
具有跨平台,容易学习,功能强大等特点,据统计全世界有超过 34的网站有
php 的应用,包括 Yahoo、sina、163、sohu 等大型门户网站。
而且很多具名的 web 应用系统(包括bbsblogwikicms 等等)都是使用
php 开 发的,Discuz、phpwind、phpbb、vbb、wordpress、boblog 等等。
随着 web 安全的热点升级,
php 应用程序的代码安全 问题也逐步兴盛起来,越来越多的安全人员投入到这个领域,越来越多的应用程序代码漏洞被披露。
针对这样一个状况,很多应用程序的官方都成立了安全部门,或 者雇佣安全人员进行代码审计,因此出现了很多自动化商业化的代码审计工具。
也就是这样的形势导致了一个局面:大公司的产品安全系数大大的提高,那些很明显 的漏洞基本灭绝了,那些大家都知道的审计技术都无用武之地了。
我们面对很多工具以及大牛扫描过 n 遍的代码,有很多的安全人员有点悲观,而有的官方安全人员 也非常的放心自己的代码,但是不要忘记了“没有绝对的安全”,我们应该去寻找新的途径挖掘新的漏洞。
本文就给介绍了一些非传统的技术经验和大家分享。
另外在这里特别说明一下本文里面很多漏洞都是来源于网络上牛人和朋友们的分享,在这里需要感谢他们 :)传统的代码审计技术WEB 应用程序漏洞查找基本上是围绕两个元素展开:变量与函数。
也就是说一漏洞的利用必须把你提交的恶意代码通过变量经过 n 次变量转换传递, 最终传递给目标函数 执行,还记得 MS 那句经典的名言吗?“一切输入都是有害的”。
这句话只强调了变量输入,很多程序员把“输入”理解为只是gpc_GET_POST_COOKIE, 但是变量在传递过程产生了 n 多的变化。
导致很多过滤只是个“纸老虎”! 我们换句话来描叙下代码安全:“一切进入函数的变量是有害的”。
PHP 代码审计技术用的最多也是目前的主力方法:静态分析,主要也是通过查找容易导致安全漏洞的危险函数,常用的如 grep,findstr 等搜索工具,很多自 动化工具也是使用正则来搜索这些函数。
下面列举一些常用的函数,也就是下文说的字典(暂略)。
但是目前基本已有的字典很难找到漏洞,所以我们需要扩展我们 的字典,这些字典也是本文主要探讨的。
其他的方法有:通过修改
PHP 源代码来分析变量流程,或者 hook 危险的函数来实现对应用程序代码的审核,但是这些也依靠了我们上面提到的字典。
PHP版本与应用代码审计到目前为止,
PHP 主要有 3 个版本:
php4、
php5、
php6,使用比例大致如下: Nophp4 68 2000-2007, security fixes after 2008/08,最终版本是
php4.4.9
php5 32 2004-present,Now at version 5.2.6(
PHP 5.3 alpha1 released) 目前还在测试阶段,变化很多做了大量的修改,取消了很多安全选
php6 项如 magic_quotes_gpc(这个不是今天讨论的范围)由于
php 缺少自动升级的机制,导致目前
PHP 版本并存,也导致很多存在漏洞没有被修补。
这些有漏洞的函数也是我们进行 WEB 应用程序代码审计的重点对象,也是我们字典重要来源。
其他的因素与应用代码审计很多代码审计者拿到代码就看,他们忽视了“安全是一个整体”,代码安全很多的其他因素有关系,比如上面我们谈到的
PHP 版本的问题,比较重要的还有操作系统类型(主要是两大阵营 win/nix),WEB 服务端软件(主要是 iis/apache两大类型)等因素。
这是由于不同的系统不同的 WEB SERVER 有着不同的安全特点或特性,下文有些部分会涉及。
所以我们在做某个公司 WEB 应用代码审计时,应该了解他们使用的系统,WEB 服务端软件,
PHP 版本等信息。
扩展我们的字典下面将详细介绍一些非传统
PHP 应用代码审计一些漏洞类型和利用技巧。
变量本身的key说到变量的提交很多人只是看到了 GET/POST/COOKIE 等提交的变量的值,但是忘记了有的程序把变量本身的 key 也当变量提取给函数处理。
ltphp//key.phpaaaaaaa1ampbbb2//print_R_GET foreach _GET AS key gt value print key.quotnquotgt上面的代码就提取了变量本身的 key 显示出来,单纯对于上面的代码,如果我们提交 URL:key.phpltscriptgtalert1lt/scriptgt1ampbbb2那么就导致一个 xss 的漏洞,扩展一下如果这个 key 提交给 include等函数或者 sql 查询呢?:)漏洞审计策略
PHP 版本要求:无系统要求:无审计策略:通读代码变量覆盖很多的漏洞查找者都知道 extract这个函数在指定参数为 EXTR_OVERWRITE 或者没有指定函数可以导致变量覆盖,但是还有很多其他情况导致变量覆盖的如:遍历初始化变量请看如下代码:ltphp//var.phpafuckahiforeach_GET as key gt value key valueprint agt很多的 WEB 应用都使用上面的方式 , (注意循环不一定是 foreach) 如 Discuz4.1的 WAP 部分的代码:chs if_POST ampamp charset utf-8 chs new ChineseUTF-8 charset foreach_POST as key gt value key chs-gtConvertvalue unsetchs漏洞审计策略
PHP 版本要求:无系统要求:无审计策略:通读代码parse_str变量覆盖漏洞//var.phpvarnewvar initparse_str_SERVERQUERY_STRINGprint var该函数一样可以覆盖数组变量,上面的代码是通过_SERVERQUERY_STRING来提取变量的,对于指定了变量名的我们可以通过注射“”来实现覆盖其他的变量://var.phpvar1ampa1var13d222var1 initparse_stra_GETvarprint var1上面的代码通过提交var 来实现对var1 的覆盖。
漏洞审计策略(parse_str)
PHP 版本要求:无系统要求:无审计策略:查找字符 parse_str漏洞审计策略(mb_parse_str)
PHP 版本要求:
php4lt4.4.7
php5lt5.2.2系统要求:无审计策略:查找字符 mb_parse_strimport_request_variables变量覆盖漏洞//var.
php_SERVERREMOTE_ADDR10.1.1.1echo GLOBALS .intini_getquotregister_globalsquot.quotnquotimport_request_variablesGPCif _SERVERREMOTE_ADDR 10.1.1.1 dieGo awayecho Hello admin漏洞审计策略(import_request_variables)
PHP 版本要求:
php4lt4.4.1
php5lt5.2.2系统要求:无审计策略:查找字符 import_request_variablesPHP5 Globals从严格意义上来说这个不可以算是
PHP 的漏洞,只能算是一个特性,测试代码:lt// register_globals ON//foo.phpGLOBALSfoobarHELLOphp echo foobargt但是很多的程序没有考虑到这点,请看如下代码://为了安全取消全局变量//var.phpGLOBALSaaaaaampb111if ini_getregister_globals foreach_REQUEST as kgtvunsetkprint aprint _GETb如果熟悉 WEB2.0 的攻击的同学,很容易想到上面的代码我们可以利用这个特性进行 crsf 攻击。
漏洞审计策略
PHP 版本要求:无系统要求:无审计策略:通读代码magic_quotes_gpc与代码安全什么是magic_quotes_gpc当打开时,所有的 (单引号),quot(双引号),(反斜线)和 NULL 字符都会被自动加上一个反斜线进行转义。
还有很多函数有类似的作用 如:addslashes、mysql_escape_string、mysql_real_escape_string等,另外还有 parse_str后的变量也受 magic_quotes_gpc 的影响。
目前大多数的主机都打开了这个选项,并且很多程序员也注意使用上面那些函数 去过滤变量,这看上去很安全。
很多漏洞查找者或者工具遇到些函数过滤后的变量直接就放弃,但是就在他们放弃的同时也放过很多致命的安全漏洞。
:)哪些地方没有魔术引号的保护1 _SERVER 变量
PHP5 的_SERVER 变量缺少 magic_quotes_gpc 的保护,导致近年来X-Forwarded-For 的漏洞猛暴,所以很多程序员考虑过滤 X-Forwarded-For,但是其他的变量呢?漏洞审计策略(_SERVER 变量)
PHP 版本要求:无系统要求:无审计策略:查找字符_SERVER2 getenv得到的变量(使用类似_SERVER 变量)漏洞审计策略(getenv)
PHP 版本要求:无系统要求:无审计策略:查找字符 getenv3 HTTP_RAW_POST_DATA 与
PHP 输入、输出流主要应用与 soap/xmlrpc/webpublish 功能里,请看如下代码:if isset HTTP_RAW_POST_DATA HTTP_RAW_POST_DATA file_get_contents
php://input if issetHTTP_RAW_POST_DATA HTTP_RAW_POST_DATA trimHTTP_RAW_POST_DATA漏洞审计策略(数据流)
PHP 版本要求:无系统要求:无审计策略:查找字符 HTTP_RAW_POST_DATA 或者
php://input4 数据库操作容易忘记的地方如:in/limit/order by/group by如 Discuzlt5.0 的 pm.
php:ifis_arraymsgtobuddys msgto array_mergemsgtobuddys arraymsgtoid ......foreachmsgto as uid uids . comma.uid comma ......query db-gtqueryquotSELECT m.username mf.ignorepm FROMtablepremembers m LEFT JOIN tableprememberfields mf USINGuid WHERE m.uid IN uidsquot漏洞审计策略
PHP 版本要求:无系统要求:无审计策略:查找数据库操作字符(selectupdateinsert 等等)变量的编码与解码一个 WEB 程序很多功能的实现都需要变量的编码解码,而且就在这一转一解的传递过程中就悄悄的绕过你的过滤的安全防线。
这个类型的主要函数有:1 stripslashes 这个其实就是一个 decode-addslashes2 其他字符串转换函数:base64_decode 对使用 MIME base64 编码的数据进行解码base64_encode 使用 MIME base64 对数据进行编码rawurldecode 对已编码的 URL 字符串进行解码rawurlencode 按照 RFC 1738 对 URL 进行编码urldecode 解码已编码的 URL 字符串urlencode 编码 URL 字符串... ...另外一个 unserialize/serialize3 字符集函数(GKBUTF7/8...)如 iconv/mb_convert_encoding等目前很多漏洞挖掘者开始注意这一类型的漏洞了,如典型的 urldecode:sql quotSELECT FROM article WHEREarticleidquot.urldecode_GETid.quotquot当 magic_quotes_gpcon 时,我们提交id2527,得到 sql 语句为:SELECT FROM article WHERE articleid漏洞审计策略
PHP 版本要求:无系统要求:无审计策略:查找对应的编码函数二次攻击详细见附录11数据库出来的变量没有进行过滤2数据库的转义符号: mysql/oracle 转义符号同样是(我们提交通过魔术引号变化为,当 我们 update 进入数据库时,通过转义变为) mssql 的转义字符为(所以我们提交通过魔术引号变化为,mssql 会 把它当为一个字符串直接处理,所以魔术引号对于 mssql 的注射没有任何 意义)从这里我们可以思考得到一个结论:一切进入函数的变量都是有害的,另外利用二次攻击我们可以实现一个 webrootkit,把我们的恶意构造直接放到数据库里。
我们应当把这样的代码看成一个 vul?漏洞审计策略
PHP 版本要求:无系统要求:无审计策略:通读代码魔术引号带来的新的安全问题首先我们看下魔术引号的处理机制:--gt--gtquot--gtquotnull--gt0这给我们引进了一个非常有用的符号“”,“”符号不仅仅是转义符号,在WIN 系统下也是目录转跳的符号。
这个特点可能导致
php 应用程序里产生非常有意思的漏洞:1得到原字符(quotnull)order_snsubstr_GETorder_sn 1//提交 //魔术引号处理 //substr sql quotSELECT order_id order_status shipping_status pay_status quot. quot shipping_time shipping_id invoice_no user_id quot. quot FROM quot . ecs-gttableorder_info. quot WHERE order_sn order_sn LIMIT 1quot2得到“”字符order_snsubstr_GETorder_sn 01//提交 //魔术引号处理 //substr sql quotSELECT order_id order_status shipping_status pay_status quot. quot shipping_time shipping_id invoice_no user_id quot. quot FROM quot . ecs-gttableorder_info. quot WHERE order_sn order_sn and order_tnquot._GETorder_tn.quotquot提交内容:order_snamporder_tn20and2011/执行的 SQL 语句为:SELECT order_id order_status shipping_status pay_statusshipping_timeshipping_id invoice_no user_id FROM order_info WHERE order_sn andorder_tn and 11/漏洞审计策略
PHP 版本要求:无系统要求:无审计策略:查找字符串处理函数如 substr 或者通读代码变量key与魔术引号我们最在这一节的开头就提到了变量 key,
PHP 的魔术引号对它有什么影响呢?ltphp//key.phpaaaaaaa1ampbbb2//print_R_GET foreach _GET AS key gt value print key.quotnquot gt1当 magic_quotes_gpc On 时,在
php5.24 下测试显示:aaaaaaabbb从上面结果可以看出来,在设置了 magic_quotes_gpc On 下,变量 key 受魔术引号影响。
但是在
php4 和 phplt5.2.1 的版本中,不处理数组第一维变量的 key,测试代码如下:ltphp//key.phpaaaaaaabb1print_R_GETgt结果显示:Array aaaaaaa gt Array bb gt 1 数组第一维变量的 key 不受魔术引号的影响。
漏洞审计策略
PHP 版本要求:
php4 和 phplt5.2.1系统要求:无审计策略:通读代码2当 magic_quotes_gpc Off 时,在
php5.24 下测试显示:aaaaaaabbb对于 magic_quotes_gpc Off 时所有的变量都是不安全的,考虑到这个,很多程序都通过 addslashes 等函数来实现魔术引号对变量的过滤,示例代码如下:ltphp//keyvul.phpaaaaa1//magic_quotes_gpc Off if get_magic_quotes_gpc _GET addslashes_array_GETfunction addslashes_arrayvalue return is_arrayvalue array_mapaddslashes_arrayvalue : addslashesvalueprint_R_GETforeach _GET AS key gt value print keygt以上的代码看上去很完美,但是他这个代码里 addslashesvalue只处理了变量的具体的值,但是没有处理变量本身的 key,上面的代码显示结果如下:Array aaaaa gt 1aaaaa漏洞审计策略
PHP 版本要求:无系统要求:无审计策略:通读代码代码注射
PHP中可能导致代码注射的函数很多人都知道 eval、preg_replace/e 可以执行代码,但是不知道
php 还有很多的函数可以执行代码如:assertcall_user_funccall_user_func_arraycreate_function变量函数...这里我们看看最近出现的几个关于 create_function代码执行漏洞的代码:ltphp//how to exp this codesort_by_GETsort_bysorterstrnatcasecmpdatabasesarraytesttestsort_function return 1 . sorter . aquot . sort_by . quotbquot . sort_by . quot usortdatabases create_functiona b sort_function漏洞审计策略
PHP 版本要求:无系统要求:无审计策略:查找对应函数(assertcall_user_funccall_user_func_arraycreate_function 等)变量函数与双引号对于单引号和双引号的区别,很多程序员深有体会,示例代码:echo quotanquotecho an我们再看如下代码://how to exp this codeifglobalsbbc_emailtext preg_replace arrayquot/email../email/iesquot quot/email./email/iesquot arraycheck_emailquot1quot quot2quot check_emailquot1quot quot1quot text另外很多的应用程序都把变量用quotquot存放在缓存文件或者 config 或者 data 文件里,这样很容易被人注射变量函数。
漏洞审计策略
PHP 版本要求:无系统要求:无审计策略:通读代码
PHP自身函数漏洞及缺陷
PHP函数的溢出漏洞大家还记得 Stefan Esser 大牛的 Month of
PHP Bugs(MOPB 见附录 2)项目么,其中比较有名的要算是 unserialize,代码如下:unserializestripslashesHTTP_COOKIE_VARScookiename . _data在以往的
PHP 版本里,很多函数都曾经出现过溢出漏洞,所以我们在审计应用程序漏洞的时候不要忘记了测试目标使用的
PHP 版本信息。
漏洞审计策略
PHP 版本要求:对应 fix 的版本系统要求:审计策略:查找对应函数名
PHP函数的其他漏洞Stefan Esser 大牛发现的漏洞:unset--Zend_Hash_Del_Key_Or_IndexVulnerability 比如 phpwind 早期的 serarch.
php 里的代码:unsetuids......querydb-gtqueryquotSELECT uid FROM pw_members WHERE username LIKEpwuserquotwhilememberdb-gtfetch_arrayquery uids . memberuid.uids uidssubstruids0-1 : sqlwhere. AND 0 ........query db-gtqueryquotSELECT DISTINCT t.tid FROM sqltable WHERE sqlwhereorderby limitquot漏洞审计策略
PHP 版本要求:
php4lt4.3
php5lt5.14系统要求:无审计策略:查找 unsetsession_destroy删除文件漏洞测试
PHP 版本:5.1.2 这个漏洞是几年前朋友 saiy 发现的,session_destroy函数的功能是删除 session 文件,很多 web 应用程序的 logout 的功能 都直接调用这个函数删除 session,但是这个函数在一些老的版本中缺少过滤导致可以删除任意文件。
测试代码如下:ltphp//val.phpsession_save_path./session_startif_GETdel session_unset session_destroyelse _SESSIONhei1 echosession_id print_r_SESSIONgt当我们提交构造 cookie:PHPSESSID/../1.
php,相当于unlinksess_/../1.
php这样就通过注射../转跳目录删除任意文件了。
很多著名的程序某些版本都受影响如 phpmyadmin,sablog,phpwind3 等等。
漏洞审计策略
PHP 版本要求:具体不详系统要求:无审计策略:查找 session_destroy随机函数1 rand VS mt_randltphp//on windowsprint mt_getrandmax //2147483647print getrandmax// 32767gt可以看出 rand最大的随机数是 32767,这个很容易被我们暴力破解。
ltphpa md5randfori0ilt32767i ifmd5i a print i.quot--gtokltbrgtquotexit else print i.quotltbrgtquotgt当我们的程序使用 rand 处理 session 时,攻击者很容易暴力破解出你的session,但是对于 mt_rand 是很难.