PHP漏洞挖掘之旅——SQL注入漏洞

学习使人丰富知识,

知识使人提升才能,

才能使人创造业绩。

php漏洞挖掘之旅

SQL注入基本知识

要想真正全面的了解PHP中的SQL注入漏洞,我们必须要有以下几方面知识的系统掌握。一是PHP语法知识(搜索一下PHP手册就行,网上有很多);二是MySQL语法知识(最重要的部分,PHP懂的多点少点没关系,但MySQL语法一定要全面系统的掌握,因为里面涉及到了语法的构造);三是对HTTP协议有一定的了解,要懂得Get和Post方式的不同;四是要懂得Cookie和Session的知识。看上去似乎需要很多的准备,但其实大家只要用心学,相信这些东西不会难倒大家的。废话不多说了,我们开始自己挖掘PHP漏洞之旅的第二站吧。希望在这里能让大家感觉到比五一黄金周更好的心情。

PHP注入比较重要的一点就是GPC的设置问题,因为MySQL4以下的版本是不支持子语句的,而且当php.ini里的magic_quotes_gpc为On时,提交的变量中所有的“” (单引号)、“"”(双引号)、“”(反斜线)和空字符都会自动转为含有反斜线的转义字符,给注入带来不少的阻碍。不过只要有经验,构造有效的语句其实一点也不难,甚至成功率很高,但也要具体情况具体分析。

下面先讲解一下“Union Select”联查,这部分和ASP有点出入,除了一定要用“Union”连接两条SQL语句,最难掌握的就是字段的数量。如果大家看过MySQL参考手册,就会知道Select语句中的“select_expression”(select_expression表示你希望检索的列[字段])部分列出的列必须具有同样的类型。第一个Select查询中使用的列名将作为结果集的列名返回。简单地说,也就是Union后面查选的字段数量、字段类型都应该与前面的Select一样;而且,如果前面的Select为真,就会同时返回两个Select的结果;当前面的Select为假时,就会返回第二个Select所得到的结果,不过某些情况下会替换掉第一个Select原来应该显示的字段。它们之间的关系如图1所示,有了这个图,直观多了吧?所以我们应该先知道前面查询表的数据表的结构,才能更好的进行注入。

图1

如果我们查询两个数据表的字段相同,类型也相同,我们就可以这样提交:

SELECT * FROM article WHERE articleid=$id UNION SELECT * FROM……

如果字段数量、字段类型任意一个不相同,我们就必须先搞清楚数据类型和字段数量,此时可以这样提交:

SELECT * FROM article WHERE articleid=$id UNION SELECT 1,1,1,1,1,1,1 FROM……

否则就会提示如下的错误:

The used SELECT statements have a different number of columns

如果不知道数据类型和字段数量,可以用“1”来慢慢试,因为“1”属于int、str、var类型,所以只要慢慢改变数量,一定可以猜到的。如果大家不能马上理解上面的知识,后面还有详细的例子,可以帮大家更好的理解。

现在,理论知识我们已经了解了,下面我们就用上次远程文件包含的方法在Linux下继续自己动手找漏洞的过程。

详解SQL注入部分(初级)

这部分对PHP注入非常重要,希望大家能自己分析里面的每一步骤,然后动手实践,最后完成漏洞挖掘。

我们还是从最简单的程序开始。第一个程序是QDBlog,它是非常简单且小巧的PHP+MySQL的日志系统,整个Blog系统才9k,别看它小,但小并不代表程序就没有漏洞。首先启动Red Hat Linux EL 4,把源代码下载回来,然后在命令行下操作,图2是我把源代码下载并且解压缩的步骤。

图2

小知识

Linux下的压缩格式和Windows有所不同,Linux的压缩格式一般为.tar.gz(我们用“tar –xvzf 文件名.tar.gz”来解压缩)、.tar.bz2(先用“bunzip2 文件名.tar.gz2”,再用“tar xvf”解压缩)。

进入程序目录后,我们仍然要用到GREP(global search regular expression and print out the line,全面搜索正则表达式并把行打印出来)命令。如果不懂GREP命令也没关系,大家请参考上一期的文章或者在Google里搜索GREP就可以了,里面有不少详细解释,我这里就不浪费版面了。

在命令行中输入“grep -n -r $_POST *”,意思是在当前目录下的所有文件中进行递归搜索符合“$_POST”的语句并打印出来。如图3所示,我们得到了一些结果,如下的代码进入了我们的眼帘。

图3

authenticate.php:2:if($_POST[username] and $_POST[wordpass]) {

authenticate.php:7:$sql = "SELECT permissions, username FROM $prefix"."auth WHERE username = " . $_POST[username] . " AND password = MD5(".$_POST[wor dpass].");";

这段代码的意思是在“authenticate.php:2”中有提交用户和密码的SQL查询语句。OK,现在有了文件名和行数,我们就进入到文件里面看看这里的username变量有没有初始化,如果没有的话就意味着我们可以利用经典的“1 OR 1 = 1”不用密码就能直接进入后台进行管理了。

这里我们用nano这个工具来操作,它是vi的增强版,具体的用法我就不多说了。输入“nano authenticate.php”,如图4所示,代码不是很多,我就简单讲解一下,让大家对认证也有一些了解。“if($_POST[username] and $_POST[wordpass])”表示,如果同时设置了从login.php中传递过来的username用户名和wordpass密码就执行if中的语句;“$sql = "SELECT permissions, username FROM $prefix"."auth WHERE username = " . $_POST[username] . " AND password = MD5(".$_POST[wordpass].");";”的意思是说从$prefix.auth($prefix是安装qdblog的前缀)中把输入的用户名、密码和数据库中的进行对比,如果输入的数据和数据库中的一致就登录到index.php中,否则继续进入login.php。知道了username和wordpass是从login.php中传递过来的,我们下面要做的就是看看 login.php中的用户名和密码变量是否设置了,如图5所示。这个程序果然非常简单,直接就把输入的用户和密码带入了数据库中,这是很明显的漏洞。到这里,程序的漏洞已经分析出来了,我们看一下如何利用吧。

图4

图5

接下来我们就实践一下看看分析的是否正确吧。如图6所示,我们来到login.php,用上面分析的漏洞来试试,在用户名处输入“1 OR 1 = 1”,密码随便输入,此时authenticate.php中的语句就变成了“$sql = "SELECT permissions, username FROM qd_auth WHERE username = 1 OR 1 = 1 AND password = MD5(“12345”);”,这样就绕过了验证。如图7所示,我们进入了后台了,成功了!

图7

利用已经学习到的知识,现在挖掘到了第二种类型的漏洞了,感觉如何呢?

SQL注入进级部分(中级)

中级的SQL注入就是利用注入漏洞来拿到用户和MD5密码,进而进入后台,得到WebShell。

最近国内的两大论坛PHPWind和Discuz都暴出了0Day,不少网站纷纷倒下,下面我们就结合上面讲的知识来分析一下PHPWind论坛的最新漏洞。PHPWind是国内用得比较多的一个PHP+MySQL的论坛程序,最近PHPWind 5.0出现了一个SQL注入漏洞,SQL注入的经典思维就是变量没有过滤直接就带入到数据库中进行查询了。

这个漏洞出现在passport_client.php文件中,我把有漏洞的代码分析一下。如图8所示是程序的第5-11行,意思是说如果$passport_ifopen或者$passport_type不等于client的话,同时$action.$userdb.$forward.$passport_key不等于$verify就返回

本文由掘安技术小组研究室综合网络整理,图片来源于网络;转载请注明”转自掘安技术小组研究室“,并附上链接。

维权通道(客服中心):

投稿| ※辉少

照片| ※风顺※

责编| ※许心痕※

编辑| ※风顺※

审核| ※许心痕※

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180109A0M41900?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券