技术笔记

PHP+Mysql注入的基本过程

字号+ 作者:sn0w 来源:转载 2016-11-27 14:55 我要评论( )

这 里我们最主要的是看mysql版本,当mysql版本5.0时我们只需要访问information_schema库即可查询数据库的相关概要信 息,而对于5.0的版本则需要爆破,今天我们测试......

这 里我们最主要的是看mysql版本,当mysql版本>5.0时我们只需要访问information_schema库即可查询数据库的相关概要信 息,而对于<5.0的版本则需要爆破,今天我们测试的环境是mysql 5.5.40,对于小于5.0的mysql不建议手工测试,可以使用slqmap等注入工具辅助,成功率在于字典的大小。
我 们先了解一下mysql中的information_schema库。information_schema数据库是MySQL自带的,它提供了访问数据 库元数据的方式。什么是元数据呢?元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。有些时候用于表述该信息的其他术语包括“数据 词典”和“系统目录”。在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权 限等。
我们今天的测试代码:
[PHP] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
    include('./connect.php');  //connect.php 数据库连接信息
    $id=$_GET['id'];
    $select_sql="SELECT * FROM article WHERE id=$id";
    echo "测试语句:".$select_sql."<br/>";
    mysql_query('set names utf8');
    $select_sql_result=mysql_query($select_sql);
    echo "Mysql Error:".mysql_error();
    $date=mysql_fetch_assoc($select_sql_result);
 ?>
 <!DOCTYPE html>
 <html>
   <head>
     <meta charset="utf-8">
     <title><?php echo $date['title']."啦啦啦啦啦啦"?></title>
   </head>
   <body>
      <h1><?php echo $date['title'] ?></h1><br />
      作者:<?php echo $date['author'] ?><br/>
      时间:<?php echo date("Y-m-d H:i:s",$date['dateline'])?><br />
      概述: <?php echo $date['description']; ?><br />
      正文: <?php echo $date['content'] ?>
   </body>
 </html>

以上代码实现了一个根据客户端提交的ID,在数据库内查询一个指定新闻的功能,其中id并没有进行任何过滤处理从而造成典型的GET数字型注入。
正常访问页面:

1.验证注入:
and 1=1

and 1=2

2.判断字段数:



2.1 order by查询:order by在sql语句中是对结果集的指定列进行排序,比如我们想让结果集按照第一列排序就是 order by 1 按照第二列排序 order by 2 依次类推,按照这个原理我们来判断他的字段数,如果我们按照他的第1列进行排序数据库会返回正常,但是当我们按照第100列排序,但是数据库中并不存在第 100列,从而报错。 如图:(手速略慢谅解)当我们测试到7时数据库报错,说明该表只有6个字段

2.2 UNION SELECT 联合查询:可以用于一个或多个SELECT的结果集,但是他有一个条件,就是两个select查询语句的查询必须要有相同的列才可以执行,利用这个特性我 们可以进行对比查询,也就是说当我们union select的列与它查询的列相同时,页面返回正常。如图:当字段为6个时页面返回正常,而大于或小于字段数时都会报错。(下面我们使用这种方法)

/***********************************分割线************************************/
解决两个小问题:
第一个:大部分程序只会调用数据库查询的第一条返回(我们这个也是),而通过联合查询出的数据中,我们想看到的数据是在第二条中如果我们想看到我们想要的数据有两种方法,第一种是让第一条数据返回假,第二种是通过sql语句直接返回我们想要的数据。
第一种:我们让第一个查询的结果始终为假

这里可能有疑问,返回为什么什么也没有呢 因为我们的第二个查询中并没有查询到什么 返回为NULL 自然就什么也没有了,我们把语句放在mysql中看一下返回结果

第二种:通过limit语句,limit在mysql中是用来分页的,我们也可以通过他拿到我们想要的结果集

返回也是空 我们看看在mysql下的


第二个:哪个列中的数据是在页面中显示出来的,可能有一些列中的数据只是用于后台程序对数据处理使用,并不会在前台显示,所以我们需要判断哪个字段我们可以看到。如图,我们通过数字代替了NULL进行查询,确定了2,3,4,5 四个字段可以在页面中显示。
回答一下为什么我们不一开始就是用数字,因为union select 不仅要求列的数量相同 同时数据类型也要相似。

/***********************************分割线************************************/
3.查询库名:
这里我们直接使用mysql自带函数database()查询 得到库名:test

4.查表名:
这里就用到了我们一开始说的information_schema库,查表名我们主要用到的是TABLES表。这里我们用到了group_concat它可以返回查询的所有结果,因为我们需要通过命名判断该我们需要的敏感数据。这里我们的目标是admin表。

5.查字段:
这里同样使用information_schema库,这里使用的是columns表。得到字段id,username,password

6.查数据:
我们的最终目标也就是这个了




/***********************************分割线************************************/
这个只是基本的用法,当然我们也可以在这个的基础上通过语句构造出更好的。最后附上sqlmap中的测试语句

UNION ALL SELECT NULL,NULL,table_name,NULL,NULL,NULL FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='test'   查表名
UNION ALL SELECT NULL,NULL,column_name,NULL,NULL,NULL FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name=0x61727469636c65 AND table_schema=0x74657374#  查列
UNION ALL SELECT NULL,NULL,id,NULL,NULL,NULL FROM test.article ORDER BY id#  读取数据
11' UNION ALL SELECT NULL,NULL,CASE WHEN ((SELECT super_priv FROM mysql.user WHERE user=0x726f6f74 LIMIT 0,1)=0x59) THEN 1 ELSE 0 END,NULL,NULL,NULL#  判断权限
UNION ALL SELECT NULL,password,user,NULL,NULL,NULL FROM mysql.user#  读取帐号密码

本文来自: 蜗蜗侠's Blog-关注网络安全 http://blog.icxun.cn/Note/322.html

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 转大表哥安全狗SQL注入语句(176处)

    转大表哥安全狗SQL注入语句(176处)

    2017-12-05 13:47

  • Mysql注入点在limit关键字后面的利用方法

    Mysql注入点在limit关键字后面的利用方法

    2016-12-18 15:06

  • 一个罕见的MSSQL注入漏洞案例

    一个罕见的MSSQL注入漏洞案例

    2016-12-18 15:03

  • 密码学笔记

    密码学笔记

    2016-12-13 16:08

网友点评
暂时未开启评论功能~