目录
高级PHP应用程序漏洞审核技术
前言
传统的代码审计技术
PHP版本与应用代码审计
其他的因素与应用代码审计
扩展我们的字典
变量本身的key
变量覆盖
遍历初始化变量
parse_str()变量覆盖漏洞
import_request_variables()变量覆盖漏洞
PHP5 Globals
magic_quotes_gpc与代码安全
什么是magic_quotes_gpc
哪些地方没有魔术引号的保护
变量的编码与解码
二次攻击
魔术引号带来的新的安全问题
变量key与魔术引号
代码注射
PHP中可能导致代码注射的函数
首页 后端开发 php教程 高级PHP应用程序漏洞复核技术

高级PHP应用程序漏洞复核技术

Jun 13, 2016 pm 12:02 PM
include php rand SEED srand

高级PHP应用程序漏洞审核技术

高级PHP应用程序漏洞审核技术

?

  • 高级PHP应用程序漏洞审核技术
    • 前言
    • 传统的代码审计技术
    • PHP版本与应用代码审计
    • 其他的因素与应用代码审计
    • 扩展我们的字典
      • 变量本身的key
      • 变量覆盖
        • 遍历初始化变量
        • parse_str()变量覆盖漏洞
        • import_request_variables()变量覆盖漏洞
        • PHP5 Globals
      • magic_quotes_gpc与代码安全
        • 什么是magic_quotes_gpc
        • 哪些地方没有魔术引号的保护
        • 变量的编码与解码
        • 二次攻击
        • 魔术引号带来的新的安全问题
        • 变量key与魔术引号
      • 代码注射
        • PHP中可能导致代码注射的函数
        • 变量函数与双引号
      • PHP自身函数漏洞及缺陷
        • PHP函数的溢出漏洞
        • PHP函数的其他漏洞
        • session_destroy()删除文件漏洞
        • 随机函数
      • 特殊字符
        • 截断
          • include截断
          • 数据截断
          • 文件操作里的特殊字符
    • 怎么进一步寻找新的字典
    • DEMO
    • 后话
    • 附录

?

前言

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代码审计技术用的最多也是目前的主力方法:静态分析,主要也是通过查找容易导致安全漏洞的危险函数,常用的如grep,findstr等搜索工具,很多自动化工具也是使用正则来搜索这些函数。下面列举一些常用的函数,也就是下文说的字典(暂略)。但是目前基本已有的字典很难找到漏洞,所以我们需要扩展我们的字典,这些字典也是本文主要探讨的。

其他的方法有:通过修改PHP源代码来分析变量流程,或者hook危险的函数来实现对应用程序代码的审核,但是这些也依靠了我们上面提到的字典。

PHP版本与应用代码审计

到目前为止,PHP主要有3个版本:php4、php5、php6,使用比例大致如下:

?

php4 68% 2000-2007,No 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也当变量提取给函数处理。

<span style="color: #666600;" class="pun"><?</span><span class="pln">php</span><span style="color: #880000;" class="com">//key.php?aaaa'aaa=1&bb'b=2 </span><span class="pln"></span><span style="color: #880000;" class="com">//print_R($_GET); </span><span class="pln">?</span><span style="color: #000088;" class="kwd">foreach</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_GET AS $key </span><span style="color: #666600;" class="pun">=></span><span class="pln"> $value</span><span style="color: #666600;" class="pun">)</span><span class="pln"></span><span style="color: #666600;" class="pun">{</span><span class="pln">? ? ? ? </span><span style="color: #000088;" class="kwd">print</span><span class="pln"> $key</span><span style="color: #666600;" class="pun">.</span><span style="color: #008800;" class="str">"\n"</span><span style="color: #666600;" class="pun">;</span><span class="pln"></span><span style="color: #666600;" class="pun">}</span><span class="pln"></span><span style="color: #666600;" class="pun">?></span>
登录后复制

上面的代码就提取了变量本身的key显示出来,单纯对于上面的代码,如果我们提交URL:

<span class="pln">key</span><span style="color: #666600;" class="pun">.</span><span class="pln">php</span><span style="color: #666600;" class="pun">?<</span><span class="pln">script</span><span style="color: #666600;" class="pun">></span><span class="pln">alert</span><span style="color: #666600;" class="pun">(</span><span style="color: #006666;" class="lit">1</span><span style="color: #666600;" class="pun">);</</span><span class="pln">script</span><span style="color: #666600;" class="pun">>=</span><span style="color: #006666;" class="lit">1</span><span style="color: #666600;" class="pun">&</span><span class="pln">bbb</span><span style="color: #666600;" class="pun">=</span><span style="color: #006666;" class="lit">2</span>
登录后复制

那么就导致一个xss的漏洞,扩展一下如果这个key提交给include()等函数或者sql查询呢?:)

?

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:通读代码

?

变量覆盖

很多的漏洞查找者都知道extract()这个函数在指定参数为EXTR_OVERWRITE或者没有指定函数可以导致变量覆盖,但是还有很多其他情况导致变量覆盖的如:

遍历初始化变量

请看如下代码:

<span style="color: #666600;" class="pun"><?</span><span class="pln">php</span><span style="color: #880000;" class="com">//var.php?a=fuck</span><span class="pln">$a</span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">'hi'</span><span style="color: #666600;" class="pun">;</span><span class="pln"></span><span style="color: #000088;" class="kwd">foreach</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_GET </span><span style="color: #000088;" class="kwd">as</span><span class="pln"> $key </span><span style="color: #666600;" class="pun">=></span><span class="pln"> $value</span><span style="color: #666600;" class="pun">)</span><span style="color: #666600;" class="pun">{</span><span class="pln">? ? ? ? $$key </span><span style="color: #666600;" class="pun">=</span><span class="pln"> $value</span><span style="color: #666600;" class="pun">;</span><span class="pln"></span><span style="color: #666600;" class="pun">}</span><span class="pln"></span><span style="color: #000088;" class="kwd">print</span><span class="pln"> $a</span><span style="color: #666600;" class="pun">;</span><span class="pln"></span><span style="color: #666600;" class="pun">?></span>
登录后复制

很多的WEB应用都使用上面的方式(注意循环不一定是foreach),如Discuz!4.1的WAP部分的代码:

<span class="pln">$chs </span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">''</span><span style="color: #666600;" class="pun">;</span><span class="pln"></span><span style="color: #000088;" class="kwd">if</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_POST </span><span style="color: #666600;" class="pun">&&</span><span class="pln"> $charset </span><span style="color: #666600;" class="pun">!=</span><span style="color: #008800;" class="str">'utf-8'</span><span style="color: #666600;" class="pun">)</span><span style="color: #666600;" class="pun">{</span><span class="pln">? ? ? ? $chs </span><span style="color: #666600;" class="pun">=</span><span style="color: #000088;" class="kwd">new</span><span style="color: #660066;" class="typ">Chinese</span><span style="color: #666600;" class="pun">(</span><span style="color: #008800;" class="str">'UTF-8'</span><span style="color: #666600;" class="pun">,</span><span class="pln"> $charset</span><span style="color: #666600;" class="pun">);</span><span class="pln">? ? ? ? </span><span style="color: #000088;" class="kwd">foreach</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_POST </span><span style="color: #000088;" class="kwd">as</span><span class="pln"> $key </span><span style="color: #666600;" class="pun">=></span><span class="pln"> $value</span><span style="color: #666600;" class="pun">)</span><span style="color: #666600;" class="pun">{</span><span class="pln">? ? ? ? ? ? ? ? $$key </span><span style="color: #666600;" class="pun">=</span><span class="pln"> $chs</span><span style="color: #666600;" class="pun">-></span><span style="color: #660066;" class="typ">Convert</span><span style="color: #666600;" class="pun">(</span><span class="pln">$value</span><span style="color: #666600;" class="pun">);</span><span class="pln">? ? ? ? </span><span style="color: #666600;" class="pun">}</span><span class="pln">? ? ? ? unset</span><span style="color: #666600;" class="pun">(</span><span class="pln">$chs</span><span style="color: #666600;" class="pun">);</span>
登录后复制

?

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:通读代码

?

parse_str()变量覆盖漏洞

<span style="color: #880000;" class="com">//var.php?var=new</span><span class="pln">$var </span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">'init'</span><span style="color: #666600;" class="pun">;</span><span class="pln"> ? ? ? ? ? ? ? ? ? ? parse_str</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_SERVER</span><span style="color: #666600;" class="pun">[</span><span style="color: #008800;" class="str">'QUERY_STRING'</span><span style="color: #666600;" class="pun">]);</span><span class="pln"> </span><span style="color: #000088;" class="kwd">print</span><span class="pln"> $var</span><span style="color: #666600;" class="pun">;</span>
登录后复制

该函数一样可以覆盖数组变量,上面的代码是通过$_SERVER['QUERY_STRING']来提取变量的,对于指定了变量名的我们可以通过注射“=”来实现覆盖其他的变量:

<span style="color: #880000;" class="com">//var.php?var=1&a[1]=var1%3d222</span><span class="pln">$var1 </span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">'init'</span><span style="color: #666600;" class="pun">;</span><span class="pln">parse_str</span><span style="color: #666600;" class="pun">(</span><span class="pln">$a</span><span style="color: #666600;" class="pun">[</span><span class="pln">$_GET</span><span style="color: #666600;" class="pun">[</span><span style="color: #008800;" class="str">'var'</span><span style="color: #666600;" class="pun">]]);</span><span class="pln"></span><span style="color: #000088;" class="kwd">print</span><span class="pln"> $var1</span><span style="color: #666600;" class="pun">;</span>
登录后复制

上面的代码通过提交$var来实现对$var1的覆盖。

?

漏洞审计策略(parse_str)
PHP版本要求:无
系统要求:无
审计策略:查找字符parse_str

?

?

漏洞审计策略(mb_parse_str)
PHP版本要求:php4<4.4.7 php5<5.2.2
系统要求:无
审计策略:查找字符mb_parse_str

?

import_request_variables()变量覆盖漏洞

<span style="color: #880000;" class="com">//var.php?_SERVER[REMOTE_ADDR]=10.1.1.1</span><span class="pln">echo </span><span style="color: #008800;" class="str">'GLOBALS '</span><span style="color: #666600;" class="pun">.(</span><span style="color: #000088;" class="kwd">int</span><span style="color: #666600;" class="pun">)</span><span class="pln">ini_get</span><span style="color: #666600;" class="pun">(</span><span style="color: #008800;" class="str">"register_globals"</span><span style="color: #666600;" class="pun">).</span><span style="color: #008800;" class="str">"n"</span><span style="color: #666600;" class="pun">;</span><span class="pln">import_request_variables</span><span style="color: #666600;" class="pun">(</span><span style="color: #008800;" class="str">'GPC'</span><span style="color: #666600;" class="pun">);</span><span class="pln"></span><span style="color: #000088;" class="kwd">if</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_SERVER</span><span style="color: #666600;" class="pun">[</span><span style="color: #008800;" class="str">'REMOTE_ADDR'</span><span style="color: #666600;" class="pun">]</span><span style="color: #666600;" class="pun">!=</span><span style="color: #008800;" class="str">'10.1.1.1'</span><span style="color: #666600;" class="pun">)</span><span style="color: #000088;" class="kwd">die</span><span style="color: #666600;" class="pun">(</span><span style="color: #008800;" class="str">'Go away!'</span><span style="color: #666600;" class="pun">);</span><span class="pln">echo </span><span style="color: #008800;" class="str">'Hello admin!'</span><span style="color: #666600;" class="pun">;</span>
登录后复制

?

漏洞审计策略(import_request_variables)
PHP版本要求:php4<4.4.1 php5<5.2.2
系统要求:无
审计策略:查找字符import_request_variables

?

PHP5 Globals

从严格意义上来说这个不可以算是PHP的漏洞,只能算是一个特性,测试代码:

<span style="color: #666600;" class="pun"><?</span><span class="pln"></span><span style="color: #880000;" class="com">// register_globals =ON</span><span class="pln"></span><span style="color: #880000;" class="com">//foo.php?GLOBALS[foobar]=HELLO</span><span class="pln">php echo $foobar</span><span style="color: #666600;" class="pun">;</span><span class="pln"> </span><span style="color: #666600;" class="pun">?></span>
登录后复制

但是很多的程序没有考虑到这点,请看如下代码:

<span style="color: #880000;" class="com">//为了安全取消全局变量</span><span class="pln"></span><span style="color: #880000;" class="com">//var.php?GLOBALS[a]=aaaa&b=111</span><span class="pln"></span><span style="color: #000088;" class="kwd">if</span><span style="color: #666600;" class="pun">(</span><span class="pln">ini_get</span><span style="color: #666600;" class="pun">(</span><span style="color: #008800;" class="str">'register_globals'</span><span style="color: #666600;" class="pun">))</span><span style="color: #000088;" class="kwd">foreach</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_REQUEST </span><span style="color: #000088;" class="kwd">as</span><span class="pln"> $k</span><span style="color: #666600;" class="pun">=></span><span class="pln">$v</span><span style="color: #666600;" class="pun">)</span><span class="pln"> unset</span><span style="color: #666600;" class="pun">(</span><span class="pln">$</span><span style="color: #666600;" class="pun">{</span><span class="pln">$k</span><span style="color: #666600;" class="pun">});</span><span class="pln"></span><span style="color: #000088;" class="kwd">print</span><span class="pln"> $a</span><span style="color: #666600;" class="pun">;</span><span class="pln"></span><span style="color: #000088;" class="kwd">print</span><span class="pln"> $_GET</span><span style="color: #666600;" class="pun">[</span><span class="pln">b</span><span style="color: #666600;" class="pun">];</span>
登录后复制

如果熟悉WEB2.0的攻击的同学,很容易想到上面的代码我们可以利用这个特性进行crsf攻击。

?

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:通读代码

?

magic_quotes_gpc与代码安全

?

什么是magic_quotes_gpc

当打开时,所有的 '(单引号),"(双引号),\(反斜线)和 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版本要求:无
系统要求:无
审计策略:查找字符_SERVER

?

2) getenv()得到的变量(使用类似$_SERVER变量)

?

漏洞审计策略(getenv())
PHP版本要求:无
系统要求:无
审计策略:查找字符getenv

?

3) $HTTP_RAW_POST_DATA与PHP输入、输出流

主要应用与soap/xmlrpc/webpublish功能里,请看如下代码:

<span style="color: #000088;" class="kwd">if</span><span style="color: #666600;" class="pun">(</span><span style="color: #666600;" class="pun">!</span><span class="pln">isset</span><span style="color: #666600;" class="pun">(</span><span class="pln"> $HTTP_RAW_POST_DATA </span><span style="color: #666600;" class="pun">)</span><span style="color: #666600;" class="pun">)</span><span style="color: #666600;" class="pun">{</span><span class="pln">? ? ? ? $HTTP_RAW_POST_DATA </span><span style="color: #666600;" class="pun">=</span><span class="pln"> file_get_contents</span><span style="color: #666600;" class="pun">(</span><span style="color: #008800;" class="str">'php://input'</span><span style="color: #666600;" class="pun">);</span><span class="pln"></span><span style="color: #666600;" class="pun">}</span><span class="pln"></span><span style="color: #000088;" class="kwd">if</span><span style="color: #666600;" class="pun">(</span><span class="pln"> isset</span><span style="color: #666600;" class="pun">(</span><span class="pln">$HTTP_RAW_POST_DATA</span><span style="color: #666600;" class="pun">)</span><span style="color: #666600;" class="pun">)</span><span class="pln">? ? ? ? $HTTP_RAW_POST_DATA </span><span style="color: #666600;" class="pun">=</span><span class="pln"> trim</span><span style="color: #666600;" class="pun">(</span><span class="pln">$HTTP_RAW_POST_DATA</span><span style="color: #666600;" class="pun">);</span>
登录后复制

?

漏洞审计策略(数据流)
PHP版本要求:无
系统要求:无
审计策略:查找字符HTTP_RAW_POST_DATA或者php://input

?

4) 数据库操作容易忘记'的地方如:in()/limit/order by/group by

如Discuz!<5.0的pm.php:

<span style="color: #000088;" class="kwd">if</span><span style="color: #666600;" class="pun">(</span><span class="pln">is_array</span><span style="color: #666600;" class="pun">(</span><span class="pln">$msgtobuddys</span><span style="color: #666600;" class="pun">))</span><span style="color: #666600;" class="pun">{</span><span class="pln">? ? ? ? $msgto </span><span style="color: #666600;" class="pun">=</span><span class="pln"> array_merge</span><span style="color: #666600;" class="pun">(</span><span class="pln">$msgtobuddys</span><span style="color: #666600;" class="pun">,</span><span class="pln"> array</span><span style="color: #666600;" class="pun">(</span><span class="pln">$msgtoid</span><span style="color: #666600;" class="pun">));</span><span class="pln">? ? ? ? ? ? ? ? </span><span style="color: #666600;" class="pun">......</span><span class="pln"></span><span style="color: #000088;" class="kwd">foreach</span><span style="color: #666600;" class="pun">(</span><span class="pln">$msgto </span><span style="color: #000088;" class="kwd">as</span><span class="pln"> $uid</span><span style="color: #666600;" class="pun">)</span><span style="color: #666600;" class="pun">{</span><span class="pln">? ? ? ? $uids </span><span style="color: #666600;" class="pun">.=</span><span class="pln"> $comma</span><span style="color: #666600;" class="pun">.</span><span class="pln">$uid</span><span style="color: #666600;" class="pun">;</span><span class="pln">? ? ? ? $comma </span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">','</span><span style="color: #666600;" class="pun">;</span><span class="pln"></span><span style="color: #666600;" class="pun">}</span><span class="pln"></span><span style="color: #666600;" class="pun">......</span><span class="pln">$query </span><span style="color: #666600;" class="pun">=</span><span class="pln"> $db</span><span style="color: #666600;" class="pun">-></span><span class="pln">query</span><span style="color: #666600;" class="pun">(</span><span style="color: #008800;" class="str">"SELECT m.username, mf.ignorepm FROM {$tablepre}members m? ? ? ? LEFT JOIN {$tablepre}memberfields mf USING(uid)? ? ? ? WHERE m.uid IN ($uids)"</span><span style="color: #666600;" class="pun">);</span>
登录后复制

?

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:查找数据库操作字符(select,update,insert等等)

?

变量的编码与解码

一个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:

<span class="pln">$sql </span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">"SELECT * FROM article WHERE articleid='"</span><span style="color: #666600;" class="pun">.</span><span class="pln">urldecode</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_GET</span><span style="color: #666600;" class="pun">[</span><span class="pln">id</span><span style="color: #666600;" class="pun">]).</span><span style="color: #008800;" class="str">"'"</span><span style="color: #666600;" class="pun">;</span>
登录后复制

当magic_quotes_gpc=on时,我们提交?id=%2527,得到sql语句为:

<span class="pln">SELECT </span><span style="color: #666600;" class="pun">*</span><span class="pln"> FROM article WHERE articleid</span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">'''</span>
登录后复制

?

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:查找对应的编码函数

?

二次攻击

详细见附录[1]

1)数据库出来的变量没有进行过滤

2)数据库的转义符号:

  • mysql/oracle转义符号同样是\(我们提交'通过魔术引号变化为\',当我们update进入数据库时,通过转义变为')
  • mssql的转义字符为'(所以我们提交'通过魔术引号变化为\',mssql会把它当为一个字符串直接处理,所以魔术引号对于mssql的注射没有任何意义)

从这里我们可以思考得到一个结论:一切进入函数的变量都是有害的,另外利用二次攻击我们可以实现一个webrootkit,把我们的恶意构造直接放到数据库里。我们应当把这样的代码看成一个vul?

?

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:通读代码

?

魔术引号带来的新的安全问题

首先我们看下魔术引号的处理机制:

<span style="color: #666600;" class="pun">[\-->\\,</span><span style="color: #008800;" class="str">'-->\',"-->\",null-->\0]</span>
登录后复制

这给我们引进了一个非常有用的符号“\”,“\”符号不仅仅是转义符号,在WIN系统下也是目录转跳的符号。这个特点可能导致php应用程序里产生非常有意思的漏洞:

1)得到原字符(',\,",null])

<span class="pln">$order_sn</span><span style="color: #666600;" class="pun">=</span><span class="pln">substr</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_GET</span><span style="color: #666600;" class="pun">[</span><span style="color: #008800;" class="str">'order_sn'</span><span style="color: #666600;" class="pun">],</span><span style="color: #006666;" class="lit">1</span><span style="color: #666600;" class="pun">);</span><span class="pln"></span><span style="color: #880000;" class="com">//提交 ? ? ? ? ? ? ? ? '</span><span class="pln"></span><span style="color: #880000;" class="com">//魔术引号处理 ? ? ? ? \'</span><span class="pln"></span><span style="color: #880000;" class="com">//substr ? ? ? ? ? ? ? '</span><span class="pln">$sql </span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">"SELECT order_id, order_status, shipping_status, pay_status, "</span><span style="color: #666600;" class="pun">.</span><span class="pln">? ?</span><span style="color: #008800;" class="str">" shipping_time, shipping_id, invoice_no, user_id "</span><span style="color: #666600;" class="pun">.</span><span class="pln">? ?</span><span style="color: #008800;" class="str">" FROM "</span><span style="color: #666600;" class="pun">.</span><span class="pln"> $ecs</span><span style="color: #666600;" class="pun">-></span><span class="pln">table</span><span style="color: #666600;" class="pun">(</span><span style="color: #008800;" class="str">'order_info'</span><span style="color: #666600;" class="pun">).</span><span class="pln">? ?</span><span style="color: #008800;" class="str">" WHERE order_sn = '$order_sn' LIMIT 1"</span><span style="color: #666600;" class="pun">;</span>
登录后复制

2)得到“\”字符

<span class="pln">$order_sn</span><span style="color: #666600;" class="pun">=</span><span class="pln">substr</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_GET</span><span style="color: #666600;" class="pun">[</span><span style="color: #008800;" class="str">'order_sn'</span><span style="color: #666600;" class="pun">],</span><span style="color: #006666;" class="lit">0</span><span style="color: #666600;" class="pun">,</span><span style="color: #006666;" class="lit">1</span><span style="color: #666600;" class="pun">);</span><span class="pln"></span><span style="color: #880000;" class="com">//提交 ? ? ? ? ? ? ? ? '</span><span class="pln"></span><span style="color: #880000;" class="com">//魔术引号处理 ? ? ? ? \'</span><span class="pln"></span><span style="color: #880000;" class="com">//substr ? ? ? ? ? ? ? \ ? ?</span><span class="pln">$sql </span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">"SELECT order_id, order_status, shipping_status, pay_status, "</span><span style="color: #666600;" class="pun">.</span><span class="pln">? ?</span><span style="color: #008800;" class="str">" shipping_time, shipping_id, invoice_no, user_id "</span><span style="color: #666600;" class="pun">.</span><span class="pln">? ?</span><span style="color: #008800;" class="str">" FROM "</span><span style="color: #666600;" class="pun">.</span><span class="pln"> $ecs</span><span style="color: #666600;" class="pun">-></span><span class="pln">table</span><span style="color: #666600;" class="pun">(</span><span style="color: #008800;" class="str">'order_info'</span><span style="color: #666600;" class="pun">).</span><span class="pln">? ?</span><span style="color: #008800;" class="str">" WHERE order_sn = '$order_sn' and order_tn='"</span><span style="color: #666600;" class="pun">.</span><span class="pln">$_GET</span><span style="color: #666600;" class="pun">[</span><span style="color: #008800;" class="str">'order_tn'</span><span style="color: #666600;" class="pun">].</span><span style="color: #008800;" class="str">"'"</span><span style="color: #666600;" class="pun">;</span>
登录后复制

提交内容:

<span style="color: #666600;" class="pun">?</span><span class="pln">order_sn</span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">'&order_tn=%20and%201=1/* </span>
登录后复制

执行的SQL语句为:

<span class="pln">SELECT order_id</span><span style="color: #666600;" class="pun">,</span><span class="pln"> order_status</span><span style="color: #666600;" class="pun">,</span><span class="pln"> shipping_status</span><span style="color: #666600;" class="pun">,</span><span class="pln"> pay_status</span><span style="color: #666600;" class="pun">,</span><span class="pln"> shipping_time</span><span style="color: #666600;" class="pun">,</span><span class="pln"> shipping_id</span><span style="color: #666600;" class="pun">,</span><span class="pln"> invoice_no</span><span style="color: #666600;" class="pun">,</span><span class="pln"> user_id FROM order_info WHERE order_sn </span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">'\' and order_tn='</span><span style="color: #000088;" class="kwd">and</span><span style="color: #006666;" class="lit">1</span><span style="color: #666600;" class="pun">=</span><span style="color: #006666;" class="lit">1</span><span style="color: #880000;" class="com">/*'</span>
登录后复制

?

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:查找字符串处理函数如substr或者通读代码

?

变量key与魔术引号

我们最在这一节的开头就提到了变量key,PHP的魔术引号对它有什么影响呢?

<span style="color: #666600;" class="pun"><?</span><span class="pln">php</span><span style="color: #880000;" class="com">//key.php?aaaa'aaa=1&bb'b=2 </span><span class="pln"></span><span style="color: #880000;" class="com">//print_R($_GET); </span><span class="pln">?</span><span style="color: #000088;" class="kwd">foreach</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_GET AS $key </span><span style="color: #666600;" class="pun">=></span><span class="pln"> $value</span><span style="color: #666600;" class="pun">)</span><span class="pln">? ? ? ? </span><span style="color: #666600;" class="pun">{</span><span class="pln">? ? ? ? </span><span style="color: #000088;" class="kwd">print</span><span class="pln"> $key</span><span style="color: #666600;" class="pun">.</span><span style="color: #008800;" class="str">"\n"</span><span style="color: #666600;" class="pun">;</span><span class="pln">? ? ? ? </span><span style="color: #666600;" class="pun">}</span><span class="pln"></span><span style="color: #666600;" class="pun">?></span>
登录后复制

1)当magic_quotes_gpc = On时,在php5.24下测试显示:

<span class="pln">aaaa</span><span style="color: #666600;" class="pun">\</span><span style="color: #008800;" class="str">'aaabb\'b</span>
登录后复制

从上面结果可以看出来,在设置了magic_quotes_gpc = On下,变量key受魔术引号影响。但是在php4和php<5.2.1的版本中,不处理数组第一维变量的key,测试代码如下:

<span style="color: #666600;" class="pun"><?</span><span class="pln">php</span><span style="color: #880000;" class="com">//key.php?aaaa'aaa[bb']=1 </span><span class="pln">print_R</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_GET</span><span style="color: #666600;" class="pun">);</span><span class="pln"> </span><span style="color: #666600;" class="pun">?></span>
登录后复制

结果显示:

<span style="color: #660066;" class="typ">Array</span><span style="color: #666600;" class="pun">(</span><span style="color: #666600;" class="pun">[</span><span class="pln">aaaa</span><span style="color: #008800;" class="str">'aaa] => Array ( [bb\'] => 1 ) ) </span>
登录后复制

数组第一维变量的key不受魔术引号的影响。

?

漏洞审计策略
PHP版本要求:php4和php<5.2.1
系统要求:无
审计策略:通读代码

?

2)当magic_quotes_gpc = Off时,在php5.24下测试显示:

<span class="pln">aaaa</span><span style="color: #008800;" class="str">'aaabb'</span><span class="pln">b</span>
登录后复制

对于magic_quotes_gpc = Off时所有的变量都是不安全的,考虑到这个,很多程序都通过addslashes等函数来实现魔术引号对变量的过滤,示例代码如下:

<span style="color: #666600;" class="pun"><?</span><span class="pln">php </span><span style="color: #880000;" class="com">//keyvul.php?aaa'aa=1'</span><span class="pln"></span><span style="color: #880000;" class="com">//magic_quotes_gpc = Off</span><span class="pln">?</span><span style="color: #000088;" class="kwd">if</span><span style="color: #666600;" class="pun">(!</span><span class="pln">get_magic_quotes_gpc</span><span style="color: #666600;" class="pun">())</span><span class="pln"></span><span style="color: #666600;" class="pun">{</span><span class="pln">?$_GET ?</span><span style="color: #666600;" class="pun">=</span><span class="pln"> addslashes_array</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_GET</span><span style="color: #666600;" class="pun">);</span><span class="pln"></span><span style="color: #666600;" class="pun">}</span><span class="pln"></span><span style="color: #000088;" class="kwd">function</span><span class="pln"> addslashes_array</span><span style="color: #666600;" class="pun">(</span><span class="pln">$value</span><span style="color: #666600;" class="pun">)</span><span class="pln"></span><span style="color: #666600;" class="pun">{</span><span class="pln">? ? ? ? </span><span style="color: #000088;" class="kwd">return</span><span class="pln"> is_array</span><span style="color: #666600;" class="pun">(</span><span class="pln">$value</span><span style="color: #666600;" class="pun">)</span><span style="color: #666600;" class="pun">?</span><span class="pln"> array_map</span><span style="color: #666600;" class="pun">(</span><span style="color: #008800;" class="str">'addslashes_array'</span><span style="color: #666600;" class="pun">,</span><span class="pln"> $value</span><span style="color: #666600;" class="pun">)</span><span style="color: #666600;" class="pun">:</span><span class="pln"> addslashes</span><span style="color: #666600;" class="pun">(</span><span class="pln">$value</span><span style="color: #666600;" class="pun">);</span><span class="pln"></span><span style="color: #666600;" class="pun">}</span><span class="pln">print_R</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_GET</span><span style="color: #666600;" class="pun">);</span><span class="pln"></span><span style="color: #000088;" class="kwd">foreach</span><span style="color: #666600;" class="pun">(</span><span class="pln">$_GET AS $key </span><span style="color: #666600;" class="pun">=></span><span class="pln"> $value</span><span style="color: #666600;" class="pun">)</span><span class="pln"></span><span style="color: #666600;" class="pun">{</span><span class="pln">? ? ? ? </span><span style="color: #000088;" class="kwd">print</span><span class="pln"> $key</span><span style="color: #666600;" class="pun">;</span><span class="pln"></span><span style="color: #666600;" class="pun">}</span><span class="pln"></span><span style="color: #666600;" class="pun">?></span>
登录后复制

以上的代码看上去很完美,但是他这个代码里addslashes($value)只处理了变量的具体的值,但是没有处理变量本身的key,上面的代码显示结果如下:

<span style="color: #660066;" class="typ">Array</span><span class="pln"></span><span style="color: #666600;" class="pun">(</span><span class="pln">? ? </span><span style="color: #666600;" class="pun">[</span><span class="pln">aaa</span><span style="color: #008800;" class="str">'aa] => 1\')aaa'</span><span class="pln">aa</span>
登录后复制

?

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:通读代码

?

代码注射

PHP中可能导致代码注射的函数

很多人都知道eval、preg_replace+/e可以执行代码,但是不知道php还有很多的函数可以执行代码如:

?

assert()
call_user_func()
call_user_func_array()
create_function()
变量函数
...

?

这里我们看看最近出现的几个关于create_function()代码执行漏洞的代码:

<span style="color: #666600;" class="pun"></span><span class="pln">php</span><span style="color: #880000;" class="com">//how to exp this code</span><span class="pln">$sort_by</span><span style="color: #666600;" class="pun">=</span><span class="pln">$_GET</span><span style="color: #666600;" class="pun">[</span><span style="color: #008800;" class="str">'sort_by'</span><span style="color: #666600;" class="pun">];</span><span class="pln">$sorter</span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">'strnatcasecmp'</span><span style="color: #666600;" class="pun">;</span><span class="pln">$databases</span><span style="color: #666600;" class="pun">=</span><span class="pln">array</span><span style="color: #666600;" class="pun">(</span><span style="color: #008800;" class="str">'test'</span><span style="color: #666600;" class="pun">,</span><span style="color: #008800;" class="str">'test'</span><span style="color: #666600;" class="pun">);</span><span class="pln">$sort_function </span><span style="color: #666600;" class="pun">=</span><span style="color: #008800;" class="str">' ?return 1 * '</span><span style="color: #666600;" class="pun">.</span><span class="pln"> $sorter </span><span style="color: #666600;" class="pun">.</span><span style="color: #008800;" class="str">'($a["'</span><span style="color: #666600;" class="pun">.</span><span class="pln"> $sort_by </span><span style="color: #666600;" class="pun">.</span><span style="color: #008800;" class="str">'"], $b["'</span><span style="color: #666600;" class="pun">.</span><span class="pln"> $sort_by </span><span style="color: #666600;" class="pun">.</span><span style></span>
登录后复制
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

适用于 Ubuntu 和 Debian 的 PHP 8.4 安装和升级指南 适用于 Ubuntu 和 Debian 的 PHP 8.4 安装和升级指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 带来了多项新功能、安全性改进和性能改进,同时弃用和删除了大量功能。 本指南介绍了如何在 Ubuntu、Debian 或其衍生版本上安装 PHP 8.4 或升级到 PHP 8.4

如何设置 Visual Studio Code (VS Code) 进行 PHP 开发 如何设置 Visual Studio Code (VS Code) 进行 PHP 开发 Dec 20, 2024 am 11:31 AM

Visual Studio Code,也称为 VS Code,是一个免费的源代码编辑器 - 或集成开发环境 (IDE) - 可用于所有主要操作系统。 VS Code 拥有针对多种编程语言的大量扩展,可以轻松编写

在PHP API中说明JSON Web令牌(JWT)及其用例。 在PHP API中说明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

php程序在字符串中计数元音 php程序在字符串中计数元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符组成的序列,包括字母、数字和符号。本教程将学习如何使用不同的方法在PHP中计算给定字符串中元音的数量。英语中的元音是a、e、i、o、u,它们可以是大写或小写。 什么是元音? 元音是代表特定语音的字母字符。英语中共有五个元音,包括大写和小写: a, e, i, o, u 示例 1 输入:字符串 = "Tutorialspoint" 输出:6 解释 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。总共有 6 个元

解释PHP中的晚期静态绑定(静态::)。 解释PHP中的晚期静态绑定(静态::)。 Apr 03, 2025 am 12:04 AM

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。

您如何在PHP中解析和处理HTML/XML? 您如何在PHP中解析和处理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示了如何使用PHP有效地处理XML文档。 XML(可扩展的标记语言)是一种用于人类可读性和机器解析的多功能文本标记语言。它通常用于数据存储

什么是PHP魔术方法(__ -construct,__destruct,__call,__get,__ set等)并提供用例? 什么是PHP魔术方法(__ -construct,__destruct,__call,__get,__ set等)并提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些?PHP的魔法方法包括:1.\_\_construct,用于初始化对象;2.\_\_destruct,用于清理资源;3.\_\_call,处理不存在的方法调用;4.\_\_get,实现动态属性访问;5.\_\_set,实现动态属性设置。这些方法在特定情况下自动调用,提升代码的灵活性和效率。

PHP和Python:比较两种流行的编程语言 PHP和Python:比较两种流行的编程语言 Apr 14, 2025 am 12:13 AM

PHP和Python各有优势,选择依据项目需求。1.PHP适合web开发,尤其快速开发和维护网站。2.Python适用于数据科学、机器学习和人工智能,语法简洁,适合初学者。

See all articles