美文网首页
SQL注入三部曲-初级

SQL注入三部曲-初级

作者: labixx | 来源:发表于2017-09-04 10:53 被阅读0次

    目录

    什么是SQL注入
    SQL注入产生的原因
    SQL注入攻击方式
    如何进行SQL注入
    SQL注入三部曲

    1.渗透攻防WEB篇-SQL注入攻击初级

    什么是SQL注入

    结构化查询语言(Structured Query Language,缩写:SQL),是一种特殊的编程语言,用于数据库中的标准数据查询语言。1986年10月,美国国家标准学会对SQL进行规范后,以此作为关系式数据库管理系统的标准语言(ANSI X3. 135-1986),1987年得到国际标准组织的支持下成为国际标准。不过各种通行的[数据库系统](http://www.ichunqiu.com/courses/277)在其实践过程中都对SQL规范作了某些编改和扩充。所以,实际上不同数据库系统之间的SQL不能完全相互通用。
    

    SQL注入(SQL Injection)是一种常见的web安全漏洞,攻击者利用这个问题,可以访问或修改数据,或者利用潜在的数据库漏洞进行攻击。

    SQL注入产生的原因

    针对SQL注入的攻击行为可描述为通过在用户可控参数中注入SQL语法,破坏原有的SQL结构,达到编写程序时意料之外结果的攻击行为,其成因可以归结为以下两个元云叠加造成的:
    

    1.程序编写者在处理应用程序和数据库交互时,使用字符串拼接的方式造成SQL语句
    2.未对用户可控参数进行住够的过滤便将参数内容拼接进入到SQL语句中

    SQL注入攻击方式

    SQL注入的攻击方式根据应用程序处理数据库返回内容的不同,可以分为可显注入、报错注入和盲注:

    1、可显注入:攻击者可以直接在当前界面内容中获取想要获得的内容

    2、报错注入:数据库查询返回结果并没有在页面中显示,但是应用程序将数据库报错信息打印到了页面中,所以攻击者可以构造数据库报错语句,从报错信息中获取想要获得的内容

    3、盲注:数据库查询结果无法从直观页面中获取,攻击者通过使用数据库逻辑或使数据库库执行延时等方法获取想要获得的内容

    如何进行SQL注入

    SQL注入攻击是非常令人讨厌的安全漏洞,是所有的web开发人员,不管是什么平台,技术,还是数据层,需要确信他们理解和防止的东西。不幸的是,开发人员往往不集中花点时间在这上面,以至他们的应用,更糟糕的是,他们的客户极其容易受到攻击。下面的三部曲从漏洞发现到漏洞确认,再到漏洞利用,最后漏洞防御四个方面的技术做了详细的讲解。

    SQL注入三部曲

    1.渗透攻防WEB篇-SQL注入攻击初级

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

    注释:
    数据库驱动是不同数据库开发商(比如oracle mysql等)为了某一种开发语言环境(比如java)能够实现统一的数据库调用而开发的一个程序,他的作用相当于一个翻译人员,将Java语言中对数据库的调用语言通过这个翻译翻译成各个种类的数据库自己的数据库语言,当然这个翻译(数据库驱动)是由各个开发商针对统一的接口自定义开发的

    目录:

    第一节 注入攻击原理及自己编写注入点

    1.1、什么是SQL?
    1.2、什么是SQL注入?
    1.3、SQL注入是怎么样产生的?
    1.4、编写注入点

    第二节 寻找及确认SQL注入

    2.1、推理测试法
    2.2、and大法和or大法
    2.3、加法和减法

    第一节注入攻击原理及自己编写注入点

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

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

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

    在PHP中动态SQL语句字符串:

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

    看上面代码我们可以控制输入参数xway,修改所要执行SQL语句,达到攻击的目的。

    1.4编写注入点

    基础知识:
    SQL SELECT 语法
    SELECT 列名称 FROM 表名称
    符号 * 取代列的名称是选取所有列

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

    下面的运算符号可以在WHERE子句中使用操作符

    = 等于
    
    <> 不等于
    
    > 大于
    
    < 小于
    
    >= 大于等于
    
    <= 小于等于
    
    BETWEEN 在某个范围内
    
    LIKE 搜索某种模式
    

    以上基础主要是介绍数据库的查询简单使用方式,之后我们在出入中会使用到

    编写注入点:
    第一步:我们使用if语句先判断一下变量是否初始化

    <?php
    If(isset(_GET[“id”])){
    
    }
    ?>
    

    注释:isset检查变量是否设置

    第二步:在if语句内,我们连接数据库。

    mysql_connect(servername,username,password);
    

    注释:php中mysql_connect函数用于连接数据库
    servername 可选。规定要连接的服务器。默认是 "localhost:3306"。
    username 可选。规定登录所使用的用户名。默认值是拥有服务器进程的用户的名称。
    password 可选。规定登录所用的密码。默认是 ""。

    第三步:选择数据库,选择你要使用的数据库

    mysql_select_db(database,connection)
    

    注释:database 必须,数据库名
    connection 可选。规定 SQL 连接标识符。如果未规定,则使用上一个打开的连接。

    第四步:选择完数据库,执行一条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输出查询内容
    echo $querry

    最后的页面

    <?php
    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_fetch_array对查询结果进行分类,然后提取在页面的表单内

    数据库配置
    创建数据库ichunqiu
    表单users
    列 id,username,password
    插入几条数据


    将上面网页保存成test.php放在phpstudy下的www目录下。
    然后我们就开始下一阶段的内容

    第二节寻找及确认SQL注入

    2.1推理测试法

    寻找SQL注入漏洞有一种很简单的方法,就是通过发送特殊的数据来触发异常。

    首先我们需要了解数据是通过什么方式进行输入,这里我总结了三个:
    GET请求:该请求在URL中发送参数。
    POST请求:数据被包含在请求体中。
    其他注入型数据:如cookie注入,http头注入等多种注入方式

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


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

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

    注释:var_dump()方法是判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值并回返数据类型.此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。

    为了更好的了解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
    

    完成后删除

    2.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连接符将查询关联,并通过查询的成功和失败判断插入字符是否被带入数据库进行执行,如果执行了我们就判断该点存在SQL注入。

    修改输出格式:

    <?php
    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>";
        while ($result = mysql_fetch_array($sql))  
        {
        echo "<tr>";
        echo "<td>" . $result[0] . "</td>";
        echo "<td>" . $result[1] . "</td>";
        echo "</tr>";
        }
        echo "</table>";
        mysql_close($con);
        echo $querry;
    }
    ?>
    

    执行查询结果



    使用or 1=1 输出全部结果

    2.3 加法和减法

    注入中数字型:使用加法减法判断
    其他类型:使用单引号判断

    我们使用代码类型为注入类型为数字型.

    我们使用+号时需要对加号进行url编码为%2b
    编码后执行为id=1%2b1输出结果为id=2时表示运算在SQL中执行,该点存在SQL注入。

    5DC4AD0F-2E96-4EA5-A085-FDA089F84CD2.png

    减号也是相同原理,减号不用使用url进行编码

    相关文章

      网友评论

          本文标题:SQL注入三部曲-初级

          本文链接:https://www.haomeiwen.com/subject/eansjxtx.html