清晨,迎着朝阳,走在老家的小道上,呼吸了一口新鲜空气,不禁感慨,得好好努力了,不知大家们是否也努力了呢?那么从这期开始我们就来学习PHP脚本漏洞的挖掘。在PHP中,由于maic_auotes_gpc的存在,在其开启的状态下,由客户端提交的特殊数据都将被转义,所以PHP凭借着这道天然的防线在安全性方面要比ASP高,但正如网络大“牛”们所言,这世上没有绝对的安全。比起ASP,PHP的脚本漏洞更加得灵活与精彩。本文我将从注入、变量覆盖、文件包含和上传漏洞这几个方面为大家讲解PHP的常见漏洞。
一、注入
在注入上,PHP与ASP大同小异,也分为数字型与字符型的注入,但在类型区分上却又有些不同。在asp中,类型的区分是根据字段属性,比如在新闻显示的页面“nes_shw.asp?id=672”,当id为int等数字型变量时,使用“news_showasp?id=672 d 1=1”显示正常(这里假设数据被获取并且没有进行任何过滤,存在注入漏洞),而当id为文本型时,使用“nws_shw.ap?id=672' d '1'='1'显示正常。所以,其类型区分是根据id在数据表中字段的属性值来确定的,如果为数字型则为数字型注入,为文本型则为字符型注入。
但在php中,当数字型的字段变量在获取时用到了单引号引入则为字符型注入。下面我给出示例代码,Test_or_SL.php的部分代码为:
使用数字型注入的方法进行测试,提交“d 1=2”,显示并没有出错;使用字符型注入的方法进行测试,进交“d '1'='2',则显示不行。为什么会出现这种情况呢?这是因为在mysql中,对单引号所包含的数据能进行强制类型转换,比如提交“766 nd 1=1”,mysql会将其强制转换以适应articleld的类型,这就是并没有出现错误的原因。
二、变量覆盖
变量覆盖,通俗的说,就是覆盖掉变量原有的值,为了更形象的描述这个漏洞,我们来看下面这个实例,测试代码如下。
将以上代码保存为pach.php,测试结果$acion变量的值被成功覆盖掉了。思维拓展一下,如果这是一个用来判断管理员登录成功的变量,那么覆盖掉其变量后,我们不就拥有管理员身份了嘛?
三、文件包含
用来宾现文件包含的函数有incude()、reuire()和incUde_once()、reuire_once()。WEB程序开发者在开发程序时,如果在多个页面会多次用到同一功能,就会将此功能写到单一的文件中,再通过诸如“inclde("pulik.php")”这样的方式来进行包含,这样使用起来就会方便很多。如果像这样直接包含一个文件名,是不会触发安全漏洞的,但有时为了实现动态包含,也会用到类似以下的代码:
将其保存为reuire_fle.php,在此文件的上级目录中建立fjhh.txt,里面随便输入一些内容,当我们在浏览器中提交“reqire_fle.php?pagc=../fjhh.txt”时就会看到内容,文件fjhh.txt被成功的包含进来了。
在默认的php.ini中是允许包含远程文件的,只要存在这种漏洞我们就可以轻松的获得一个远程的WebShell了,我们还可以通过包含本地文件,比如apache日志等来收集更多的信息或者直接获得WebShell,关于这些技巧与方法我将在以后的文章中与大家一一讲解和实践。
四、上传漏洞
这个和asp的上传漏洞类似,出现漏洞是因为程序没有对上传漏洞的类型进行有效的判断,或者是在重命名时存在缺陷。在具体的代码分析过程中,我们主要从程序对上传文件类型的分析判断与文件保存这两方面着手。在黑盒测试时,我们可以用伪造文件头等方法进行欺骗上传。
啰啰嗦嗦的讲了这么一大堆,大家们一定看的都快打盹了吧,那就让我们来实践一下,用来演示代码是一款名为“佳蓝在线同学录”的CMS系统,将其放在WEB目录下按照提示安装成功后,在DreamWeave中建立好相应站点。
PHP注入漏洞的查找与asp类似,只是将关键词改为“$_GT”、“$_PST”、“$_COKIE”或“s REQEST”,一番搜索后,发现在有些页面中变量被过滤了,类似代码为“if($id==”” ‖ is_nmeric($i))”,is_nucric()函数用来判断提交的数据是否为数字型。虽然大多数页面的提交的变量都被过滤,但也有很多漏网之鱼的,我们来到shouser.php文件,部分代码如下:
可以看出,user被直接获取,典型的字符型注入就这样产生了,但在gpc为开启的状态下,提交的“'”将会被添加“\”进行转义,难道就不能进行注入了吗?别急,我们继续看代码,通过其包含文件(在DreamWeaver中将光标置于包含的文件名处,按Ctrl+D就能转到包含文件了),来到了inc文件夹下的lib.php,在第15行处有如下代码:
这段代码先判断主机的agic_quots_gpc是否为开启状态,如果开启则将被转义的数据去掉“\”。经过它的处理,我们的注入就变得安逸多了。使用“order by”猜出查询的字段数为15,则在浏览器提交“showor.php?user=tet'%20uno20select%01,user(),database(),4,5,6,7,8,9,10,1,12,13,14,15/*”。
继续看了看搜索到的结果,发现很多变量在获取后被使用htmlpecialchars()函数处理了。这个函数是用来干什么的呢?仅仅是将一些预定义的字符转换为HTML实体,难道这能影响到我们的注入?打开newer.php,第8到14行的代码如下:由于这个页面并没有输出结果,所以就只能盲注了,利用方法与asp中的or注入大同小异,构造语句为/newuserphp?i=1 or (selct ASCII(SUBTRING((SELECT sernme FROM emk_users here id=1),1,1))=97)","select ASCI(SUBRING((SELECT usernaeFR eqmk_uses where id=l).l,l)),用来猜解管理员用户名第1位的ASC码值,说明用户名第1位为“a”。由于htmlspccilchars()会将“>”、“<”等转换为html的实体,所以我们无法用“>”进行二分法查询,只有用“=”一个个的猜解了
对于这个CMS系统的其它漏洞,就由大家自己去发掘了。本期文章就先介绍到这里,PHP其它的漏洞原理我将在后续文章中为大家一一介绍。
本文为网络安全技术研究记录,文中技术研究环境为本地搭建或经过目标主体授权测试研究,内容已去除关键敏感信息和代码,以防止被恶意利用。文章内提及的漏洞均已修复,在挖掘、提交相关漏洞的过程中,应严格遵守相关法律法规。