【渗透攻防WEB篇】SQL注入攻击初级

前言
无论用什么语言编写的Web应用,它们都用一个共同点,具备交互性而且多数是数据库驱动。在网络中,数据库驱动的Web应用随处可见,由此而存在的SQL注入是影响企业运营且最具破坏性的漏洞之一,这里我想问,咱们真的了解SQL注入吗?看完本篇文章但愿能让你更加深入的认识SQL注入。php


目录html

第一节 注入攻击原理及本身编写注入点
mysql

  • 1.一、什么是SQL?
  • 1.二、什么是SQL注入?
  • 1.三、SQL注入是怎么样产生的?
  • 1.四、编写注入点


第二节 寻找及确认SQL注入
sql

    • 2.一、推理测试法
    • 2.二、and大法和or大法
    • 2.三、加法和减法

 

正文
数据库

  • 第一节 注入攻击原理及本身编写注入点


1.一、什么是SQL?
SQL 是一门 ANSI 的标准计算机语言,用来访问和操做数据库系统。SQL 语句用于取回和更新数据库中的数据。SQL 可与数据库程序协同工做,好比 MS Access、DB二、Informix、MS SQL Server、Oracle、Sybase 以及其余数据库系统。

1.二、什么是SQL注入?
看起来很复杂,其实很简单就能解释,SQL注入就是一种经过操做输入来修改后台SQL语句达到代码执行进行攻击目的的技术。

1.三、SQL注入是怎么样产生的?

构造动态字符串是一种编程技术,它容许开发人员在运行过程当中动态构造SQL语句。开发人员可使用动态SQL来建立通用、灵活的应用。动态SQL语句是在执行过程当中构造的,它根据不一样的条件产生不一样的SQL语句。当开发人员在运行过程当中须要根据不一样的查询标准来决定提取什么字段(如SELECT语句),或者根据不一样的条件来选择不一样的查询表时,动态构造SQL语句会很是有用。

在PHP中动态构造SQL语句字符串:
编程

 

$query = "SELECT * FROM users WHERE username = ".$_GET["ichunqiu"];

 

看上面代码咱们能够控制输入参数ichunqiu,修改所要执行SQL语句,达到攻击的目的。数组

 

1.四、编写注入点
为了照顾一下新人,这里先介绍一下涉及到的基础知识:服务器

 

SQL SELECT 语法
SELECT 列名称 FROM 表名称
符号 * 取代列的名称是选取全部列
WHERE 子句
如需有条件地从表中选取数据,可将 WHERE 子句添加到 SELECT 语句。
语法
SELECT 列名称 FROM 表名称 WHERE 列 运算符 值

下面的运算符可在 WHERE 子句中使用:网络

了解了以上基础知识就让咱们来本身编写注入点把。函数


第一步:咱们使用if语句来先判断一下变量是否初始化

 

<?php
if(isset($_GET["ichunqiu"])){
     
}
?>

 

 

第二步:在if语句里面,咱们链接数据库。在PHP中,这个任务经过 mysql_connect() 函数完成。

mysql_connect(servername,username,password);
servername        可选。规定要链接的服务器。默认是 "localhost:3306"。
username        可选。规定登陆所使用的用户名。默认值是拥有服务器进程的用户的名称。
password        可选。规定登陆所用的密码。默认是 ""。

 

第三步:链接成功后,咱们须要选择一个数据库。

mysql_select_db(database,connection)
database        必需。规定要选择的数据库。
connection        可选。规定 MySQL 链接。若是未指定,则使用上一个链接。

 

第四步:选择完数据库,咱们须要执行一条 MySQL 查询。

mysql_query(query,connection)
query        必需。规定要发送的 SQL 查询。注释:查询字符串不该以分号结束。
connection        可选。规定 SQL 链接标识符。若是未规定,则使用上一个打开的链接。

 

第五步:执行完查询,咱们再对结果进行处理

mysql_fetch_array(data,array_type)
data        可选。规定要使用的数据指针。该数据指针是 mysql_query() 函数产生的结果。
array_type        
可选。规定返回哪一种结果。可能的值:
MYSQL_ASSOC - 关联数组
MYSQL_NUM - 数字数组
MYSQL_BOTH - 默认。同时产生关联和数字数组

 

题外话:咱们使用echo将执行的SQL语句输出,方便咱们查看后台执行了什么语句。

echo $querry

 

最终代码以下:

if(isset($_GET["id"])){
    $con = mysql_connect("127.0.0.1:3306","root","root");
    if (!$con)
    {
        die('Could not connect: ' . mysql_error());
    }
    mysql_select_db("ichunqiu",$con);
    $querry = "select * from users where id = " . $_GET['id'];
    $sql = mysql_query($querry,$con);
    $result = mysql_fetch_array($sql);
 
    echo "<table class='itable' border='1' cellspacing='0' width='300px' height='150'>";
    echo "<tr>";
    echo "<td>id</td>";
    echo "<td>username</td>";
    echo "</tr>";
 
    echo "<tr>";
    echo "<td>".$result['id']."</td>";
    echo "<td>".$result['username']."</td>";
    echo "</tr>";
    echo "</table>";
    mysql_close($con);
    echo $querry;
}
?>

 

MySQL数据库实验环境配置:
代码层工做已经作好,可是在数据库里面,咱们尚未ichunqiu这个数据库啊,接下来我就带你们一步步建立数据库,建立表,建立列,插入数据。

 

第一步:建立数据库

 
 
第二步:建立表users和列id,username,password
 
 
第三步:咱们插入几条数据
 
 
一样的道理,你们多插几条数据。到此咱们整个任务就完成了。

 

  • 第二节 寻找及确认SQL注入


2.一、推理测试法
寻找SQL注入漏洞有一种很简单的方法,就是经过发送特殊的数据来触发异常。


首先咱们须要了解数据是经过什么方式进行输入,这里我总结了三个:

  • GET请求:该请求在URL中发送参数。
  • POST请求:数据被包含在请求体中。
  • 其余注入型数据:HTTP请求的其余内容也可能会触发SQL注入漏洞。


了解完数据的输入方式,咱们接下来再学习数据库错误。这里咱们以MySQL为例,其它的请你们自行学习咯。
咱们如今参数后面加个单引号,以下图:

 

 

sql语句最终变为

select * from users where id = 1'

 

执行失败,因此mysql_query()函数会返回一个布尔值,在下行代码中mysql_fetch_array($sql)将执行失败,而且PHP会显示一条警告信息,告诉咱们mysql_fetch_array()的第一个参数必须是个资源,而代码在实际运行中,给出的参数值倒是一个布尔值。
咱们修改代码在

 

$sql = mysql_query($querry,$con);下一行加上
var_dump($sql);

 

 

能够发现:

为了更好的了解MySQL错误,咱们在

$sql = mysql_query($querry,$con);

加上

if(!$sql)
    {
        die('<p>error:'.mysql_error().'</p>');
    }

这样当应用捕获到数据库错误且SQL查询失败时,就会返回错误信息:(咱们在参数中添加单引号返回的错误信息)

error:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1

而后借助这些错误,咱们这能够推断应该存在SQL注入。还有其余数据库错误信息,以及MySQL其余错误信息,因为篇幅问题就不一一讲解了。



2.二、and大法和or大法
页面不返回任何错误信息,咱们就能够借助本方法来推断了,首先咱们在参数后面加上 and 1=1和and 1=2看看有什么不一样

 

能够发现and 1=1 返回了数据,而and 1=2没有,这是因为1=1是一个为真的条件,前面的结果是true,true and true 因此没有任何问题,第二个 1=2 是个假条件, true and false仍是false,因此并无数据返回。


好,讲完and,咱们自来看看 or ,or就是或者,两个都为假,才会为假。咱们先把id改成5,能够发现id=5是没有数据的。

能够发现咱们加上or 1=1就成功返回了数据,这是由于1=1为真,无论前面是否是假,数据都会返回,这样就把表里面数据所有返回,咱们没看见,是由于代码中并无迭代输出。这样,咱们来修改一下代码。

 

echo "<table class='itable' border='1' cellspacing='0' width='300px' height='150'>";
        echo "<tr>";
        echo "<td>id</td>";
        echo "<td>username</td>";
        echo "</tr>";
        //遍历查询结果
        while ($result = mysql_fetch_array($sql)) {
        echo "<tr>";
        echo "<td>" . $result[0] . "</td>";
        echo "<td>" . $result[1] . "</td>";
        echo "</tr>";
    }

 

而后你就能够发现:

 

2.三、加法和减法
这里咱们须要区分一下数字型和字符串型:

  • 数字型:不须要使用单引号来表示
  • 其余类型:使用单引号来表示

综合上述,咱们能够发现咱们的例子是数字型的,这样咱们就可使用加法和减法来判断了。


加法,咱们在参数输入1+1,看看返回的数据是否是id等于2的结果,这里注意一下+号在SQL语句是有特效含义的,因此咱们要对其进行url编码,最后也就是%2b。

 

 

减法是一样的道理,不过咱们不须要对-号进行url编码了。

结束语
感谢你们的支持吧,在此我也总结一下前面本身的不足,因为篇幅很长,宽度是到位了,可是并无深刻,也不算详细,因此本篇教程分为了三级即初级、中级、高级。六节来写,既要深度也要宽度,固然我也不是技术大牛,如文中有错误请指出,我会加以改正,谢谢。

 

文章首链:http://bbs.ichunqiu.com/thread-9518-1-1.html


感谢您的阅读,若是您学到了,请点赞(码字不易)!


欢迎热心园友补充!

做者:zusheng


系列文章预告及导航

渗透攻防Web篇-SQL注入攻击中级(状态:更新中)

  • 第三节 利用SQL注入
  • 第四节 SQL盲注利用


渗透攻防Web篇-SQL注入攻击高级(状态:更新中)

    • 第五节 避开过滤方法总结
    • 第六节 探讨SQL注入防护技巧
相关文章
相关标签/搜索