zoukankan      html  css  js  c++  java
  • SQL注入原理及代码分析(二)

    前言

    上一篇文章中,对union注入、报错注入、布尔盲注等进行了分析,接下来这篇文章,会对堆叠注入、宽字节注入、cookie注入等进行分析。第一篇文章地址:SQL注入原理及代码分析(一)
    如果想要了解Access的详细手工注入过程,可以看我的这篇文章:https://www.cnblogs.com/lxfweb/p/12643011.html
    如果想要了解MySQL的详细手工注入过程,可以看我的这篇文章:https://www.cnblogs.com/lxfweb/p/12655316.html
    如果想要了解SQL server的详细手工注入过程,可以看我的这篇文章:https://www.cnblogs.com/lxfweb/p/12675023.html

    SQL注入原理

    SQL注入漏洞的产生需要满足两个条件

    1. 参数用户可控:前端传给后端的参数内容是用户可以控制的。
    2. 参数带入数据库查询:传入的参数拼接到SQL语句并带入数据库查询。
      所以在实际环境中开发者要秉持“外部参数皆不可信原则”进行开发。

    几种常见的SQL注入攻击

    堆叠查询注入

    先说一下堆叠查询,堆叠查询可以执行多条语句,多语句之间以分号隔开。堆叠注入就是利用这个特点,在第二条SQL语句中构造自己要执行的句子。
    然后看代码

    <?php
    try {
        $conn = new PDO("mysql:host=localhost;dbname=dvwa", "root", "XFAICL1314");
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $stmt = $conn->query("SELECT * FROM users where `user_id`='" . $_GET['id']."'");
        $result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
        foreach ($stmt->fetchAll() as $k => $v) {
            foreach ($v as $key => $value) {
                echo $value;
            }
        }
        $dsn = null;
    }
    catch (PDOException $e)
    {
        echo "error";
    }
    $conn = null;
    ?>
    

    在堆叠注入页面中,程序获取GET参数id,使用PDO的方式进行数据查询,但是还是将id拼接到SQL语句中,导致POD没起到预编译的效果。程序仍然存在SQL注入。使用PDO执行SQL语句时,可以执行多条语句,但只返回第一条执行的结果。所以第二条语句中可以使用时间盲注等来会获取数据。时间注入上一篇文章分析了。
    所以咱们构造的语句为:
    ';select if(substr(user(),1,1)=0x72,sleep(5),1)%23


    我们发现构造的时间注入语句成功执行,之后可以通过这种方法猜解出,库名,表名,字段及内容。

    宽字节注入攻击

    先说一下宽字节注入原理,如果我们注入的参数为字符型,我们构造自己的SQL语句的时候需要用单引号闭合前面的SQL语句,但是咱们输入的单引号被转义(反斜杠)了,导致参数无法逃逸单引号的包围,一般情况是没有SQL注入的,不过有一个特例,那就是当数据库的编码为GBK时,可能存在宽字节注入,具体操作是先在url后添加%df,在添加单引号,因为反斜杠的编码为%5c,而在GBK编码中,%df%5c是繁体字"綅"。所以单引号逃逸,就可以执行咱们构造的SQL语句了。
    然后看代码

    <?php
    $conn = mysql_connect('localhost','root','XFAICL1314') or die('abd!');
    mysql_select_db('dvwa',$conn) OR emMsg("数据库连接失败");
    mysql_query("SET NAMES 'gbk'",$conn);
    $id = addslashes($_GET['id']);
    $sql="select * from users where user_id='$id'limit 0,1";
    $result = mysql_query($sql,$conn) or die(mysql_error());
    $row = mysql_fetch_array($result);
    if($row)
    {
        echo $row['user'].":".$row['password'];
    }
    else
    {
        print_r(mysql_error());
    }
    ?>
    </font>
    <?php
    echo "<br><br>SQL : ".$sql."<br><br>";
    ?>
    

    在宽字节注入页面中,程序获取GET参数id,并对参数id使用addslashes()转义,然后拼接到SQL语句中,进行查询。现在进行尝试。
    构造语句:%df' and 1=1%23

    我们发现单引号成功逃逸,之后的过程就是和union注入一样了,猜表,猜字段,获得数据。

    cookie注入攻击

    先看代码

    <?php
    $id=$_COOKIE['id'];
    $value="1";
    setcookie("id",$value);
    $con=mysqli_connect("localhost","root","XFAICL1314","dvwa");
    if(mysqli_connect_error())
    {
        echo "连接失败:". mysqli_connect_error();
    }
    $result = mysqli_query($con,"select * from users where `user_id`=".$id);
    if (!$result){
        printf("Error:%s
    ",mysqli_error($con));
        exit();
    }
    $row= mysqli_fetch_array($result);
    echo $row['user'].":". $row['password'];
    echo "<br>";
    ?>
    

    在cookie注入页面中,程序通过$_COOKIE获取到参数id,并直接将id拼接到select语句中进行查询,如果有结果,将解惑输出到页面。
    我们打开页面,发现url中没有GET参数。通过抓包发现参数id在cookie中。

    接着构造语句:and 1=2 拼接到cookie中,发现报错了,可以注入,之后也是用union注入的一些语句。

    包括用order by 判断字段,接着使用联合查询。得到表名,字段名和数据。
    cookie注入还有一种情况,那就是,程序用$_REQUEST[]来接收用户的输入,但是程序的防御程序只是对GET和POST接收的输入做了防御。没考虑cookie,这就导致了cookie注入。和上面的操作方式一样,只需要抓包,将有注入点的参数移到cookie中就可以了。

    XFF注入攻击

    XFF注入原理是通过修改X-Forwarded-For头对带入系统的dns进行sql注入,从而得到网站的数据库内容。X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP。
    这里用墨者学院的XFF注入靶场来做演示。
    打开靶场,发现是登陆页面,随便输入账号和密码。发现返回客户机ip,猜测是由XFF控制。

    抓包,添加XFF头,改为1.1.1.1,发现也更改,说明存在XFF注入。

    接着使用报错注入的方法,用updataxml()等函数将我们需要的数据查询出来,详细查询过程这里就不写了,查询到的账号密码的语句为:

    ' and updatexml(1,concat(0x7e,(select concat(username,0x7e,password) from user limit 0,1) ,0x7e),1) or '1'='1
    

    小结

    两篇文章将常见的几种SQL注入都简单分析了一遍,并构造了相关有缺陷的代码用来加深理解。希望对大家有所帮助。
    参考文献:《Web安全攻防》

  • 相关阅读:
    密码-散乱的密文
    设置nginx服务器
    Postman设置authorization
    mongodb 学习笔记 1
    一道面试题,观察者模式
    laravel-admin form组件
    laravel-admin 管理平台获取当前登陆用户信息
    Laravel-admin安装富文本编辑器 WangEditor 上传图片到服务器,而不是按BASE64保存
    Laravel报错Whoops, looks like something went wrong 解决办法
    菜鸟用composer 安装项目依赖 vendor:当拿到一个Laravel项目时怎么配置本地环境
  • 原文地址:https://www.cnblogs.com/lxfweb/p/13275582.html
Copyright © 2011-2022 走看看