BWAPP之SQL注入通关



1、SQL injection(GET/search)

low

输入单引号直接报错,说明有注入点

直接order by二分法得出主查询字段数为7

直接union注入,测出回显点为2,3,4,5

BWAPP之SQL注入通关_第1张图片

查数据库信息:

BWAPP之SQL注入通关_第2张图片

测出数据库名为bwapp,用户为root,版本为5.5.53

查询表名:

BWAPP之SQL注入通关_第3张图片

查询字段名:

BWAPP之SQL注入通关_第4张图片

查字段值:

BWAPP之SQL注入通关_第5张图片

没有难度。

medium

尝试多种方法都不行,看了一眼源码:

BWAPP之SQL注入通关_第6张图片

发现是用addslashes()进行转义的,尝试了下宽字节绕过,也不行。

看了下原来数据库采用的是urf8编码,本来想改成gbk复现一下,结果改不成。

BWAPP之SQL注入通关_第7张图片

character_set_system:数据库系统使用的编码格式,这个值一直是utf8,不需要设置,它是为存储系统元数据的编码格式。

所以暂时想不到什么绕过方法。

high

使用了mysql_real_escape_string()函数将特殊字符转义

受影响的字符:

  • \x00
  • \n
  • \r
  • \
  • "
  • \x1a

暂时无法注入。


2、SQL Injection(GET/Select)

是一个选择表单的格式,但这也不妨碍注入。直接在url中注入

BWAPP之SQL注入通关_第8张图片

low

输入单引号报错,说明存在注入点。

判断是数字型

BWAPP之SQL注入通关_第9张图片

order by测出主查询字段数为7

直接union注入

BWAPP之SQL注入通关_第10张图片

找到了回显点。

查询数据库名 bwapp

查询表名

可以用limit来限制回显个数,也可以用group_concat()一次性查出效率更高

BWAPP之SQL注入通关_第11张图片

查询字段名

BWAPP之SQL注入通关_第12张图片

查询数据

BWAPP之SQL注入通关_第13张图片

medium

虽然用了addslashes()函数进行了转义,但因为是数字型的不需要单引号闭合,所以没什么用,方法和上面一样。

high

采用了PDO技术,做了参数化和预处理,将sql语句和用户输入分离,有效预防了sql注入。

BWAPP之SQL注入通关_第14张图片


3、SQL Injection (POST/Search)

low

由于是post型注入,所以直接burp抓包:

输入单引号直接报错

BWAPP之SQL注入通关_第15张图片 image-20210411213945366

order by 测到8报错,所以确定主查询为7个字段

BWAPP之SQL注入通关_第16张图片 BWAPP之SQL注入通关_第17张图片

测出回显点位2,3,4,5。剩下的就和上面一样了,暴数据库名、表名、字段名、字段值

BWAPP之SQL注入通关_第18张图片

medium

用了addslashes()函数进行了转义’ " \ null,所以绕过比较困难。

但并不是说,只要加了这个函数就可以防御所有情况,这篇文章给了三种情况:

1、参数没有加引号的,直接绕过

2、宽字节注入(两种情况1.数据库字符集为gbk,2.代码中用了转换字符编码的函数)

3、addslashes()过滤后进行了url解码,直接url双重编码绕过。

总之比较灵活,还是要具体情况具体对待。

但是对这一关而言,绕过还是比较难的。

high

用了mysql_real_escape_string()函数进行了转义,绕过比较困难。

BWAPP之SQL注入通关_第19张图片


4、SQL Injection (POST/Select)

这一关与SQL Injection(GET/Select)只是请求方式上的差异。


5、SQL Injection (AJAX/JSON/jQuery)

BWAPP之SQL注入通关_第20张图片

可以看到通过AjAX异步请求发送到sqli_10-2.php,然后其他的和前面一样。


5、SQL Injection(CAPTCHA)

这一关和前面的区别就是多了一道验证码,正确输入验证码进入后,直接注入,手法和之前一样。


6、SQL Injection (Login Form/Hero)

使用万能密码直接登入(需要提前知道用户名)

BWAPP之SQL注入通关_第21张图片

在用户名的位置进行注入测试:

用order by测出主查询字段数为4

BWAPP之SQL注入通关_第22张图片 BWAPP之SQL注入通关_第23张图片

进行union注入:

BWAPP之SQL注入通关_第24张图片 image-20210416222354753

如图所示,获得回显点为2和4

获取数据库名和用户名:

BWAPP之SQL注入通关_第25张图片 image-20210416222533159

获取表名:

BWAPP之SQL注入通关_第26张图片 image-20210416222756873

获取字段名:

BWAPP之SQL注入通关_第27张图片 image-20210416222950809

获取字段值:

BWAPP之SQL注入通关_第28张图片 image-20210416223210014

最后将密码利用md5在线解密网站进行解密。

打完收工。

medium级别使用addslashes()进行转义

high级别使用mysql_real_escape_string()函数将特殊字符转义


7、SQL Injection (Login Form/User)

进行注入测试,发现存在sql注入:

BWAPP之SQL注入通关_第29张图片 image-20210417113737019

order by测出主查询字段数为9,但是无法进一步union注入。

BWAPP之SQL注入通关_第30张图片 image-20210417115710471

看一眼源码:

BWAPP之SQL注入通关_第31张图片

发现只有密码通过后面的验证之后才能回显。

image-20210417115838168

而这一段payload回显password值为3,显然无法通过判断。

所以要想进一步注入,就要知道bee账号对应的密码的散列值,这要在实战中直接就拉闸了,顶多能进账户,想脱库很难。

为了演示,假设我们已经知道bee账号对应的散列值,重新更改payload:

BWAPP之SQL注入通关_第32张图片

如图所示,这样的回显应该可以通过检测了。

试一下:

BWAPP之SQL注入通关_第33张图片 image-20210417120447031

果然如此,和猜想一致,不过要注意的是password字段的值要加引号,不然会报错。

然后进一步暴数据库名:

image-20210417120649472 image-20210417120655581

接着暴表名、字段名、字段值。

与上一关不同之处在于,上一关在回显之前并没有验证密码,如图所示:

BWAPP之SQL注入通关_第34张图片


8、SQL Injection - Stored (Blog)

先随便输一个:333

BWAPP之SQL注入通关_第35张图片

发现直接将输入的语句回显到了页面上,于是判断后台应该是先将用户输入的内容存入数据库,然后查询回显。

语句大概是这样: insert into blog values(username, now(), ‘$content’)

思路一:

所以可以尝试使用报错注入:

insert into blog values(username, now(), ''or updatexml(1,concat(0x7e,database()),2) or ‘’)

image-20210417145445869 image-20210417145431115

如图所示,成功爆出数据库名。

接着暴表名:

image-20210417145739868 image-20210417145800030

暴字段名:

image-20210417145944671 image-20210417145957365

暴字段值:

BWAPP之SQL注入通关_第36张图片 image-20210417150317964

如图所示,成功爆出用户名和字段的md5值,但是回显的字符串长度有限制,已经被截断了。

于是可以使用substr()函数来截取后一段:

image-20210417151044412 image-20210417151057427

以此类推,将所有的密码截取完拼接起来。

小结:

注意报错注入一定要用concat()函数,否则无法正常回显。

思路二:

还有一种思路是构造闭合,在注入字段的后面字段中做文章。

条件:注入的那个字段,不是insert语句中的最后一个字段。

例如原句为:

insert into blog (login, content, date) values(username, ‘$content’, now())

理想效果:

insert into blog (login,content, date) values(username, ‘hello baby’, database())#’)

这是我们先验证注入字段的位置:

BWAPP之SQL注入通关_第37张图片 image-20210417143629004

如图所示报错:Column count doesn’t match value count at row 1

说明注入的字段并不是insert语句中的最后一个,满足条件。

于是加一个字段,继续测试:

image-20210417153841882 image-20210417153851271

这一次没有报错,成功插入!

于是可以在后面的那个字段上做文章:

查询数据库名:

BWAPP之SQL注入通关_第38张图片 image-20210417154044248

暴表名:

image-20210417154227347 image-20210417154237724

暴字段名:

image-20210417154353890 image-20210417154402113

暴字段值:

image-20210417154519163 image-20210417154526843

打完收工!


9、SQL Injection - Stored (User-Agent)

BWAPP之SQL注入通关_第39张图片

从页面回显的内容来看,猜测网站会将数据包中的host和user-agent字段存入数据库中,然后回显到页面。

所以注入点可能在user-agent字段,然后后端的语句应该是insert

所以报错注入来一波:

BWAPP之SQL注入通关_第40张图片

如图所示,成功回显数据库名,然后再依次暴表名、字段名、字段值,姿势与上面类似这里不再赘述。


10、SQL Injection - Stored (XML)

BWAPP之SQL注入通关_第41张图片

点击any bugs然后抓包:

BWAPP之SQL注入通关_第42张图片

发现请求包的数据是一个xml格式。

于是尝试更改bee为单引号:

BWAPP之SQL注入通关_第43张图片

结果报错。

分析页面的功能,发现是重置秘密的,所以可能是update语句

于是报错注入来一波:

BWAPP之SQL注入通关_第44张图片

如图所示,成功爆出数据库名。后续脱库步骤与上面相仿。

源码分析:

//sqli_8-1.php
<script type="text/javascript">

        function ResetSecret()
        {
      
            var xmlHttp;
            // Code for IE7+, Firefox, Chrome, Opera, Safari
            if(window.XMLHttpRequest)
            {
      
                xmlHttp = new XMLHttpRequest();
            }
            // Code for IE6, IE5
            else
            {
      
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlHttp.open("POST","sqli_8-2.php",true);
            xmlHttp.setRequestHeader("Content-type","text/xml; charset=UTF-8");
            xmlHttp.send("login"])){echo $_SESSION["login"];}?>Any bugs?");  //利用Ajax技术将xml文件发送到sqli_8-2.php
        }

    script>
//sqli_8-2.php

$body = file_get_contents("php://input");  //访问请求的原始数据的只读流

// If the security level is not MEDIUM or HIGH
if($_COOKIE["security_level"] != "1" && $_COOKIE["security_level"] != "2")
{
     

    ini_set("display_errors",1);

    $xml = simplexml_load_string($body);  // 函数转换形式良好的 XML 字符串为 SimpleXMLElement 对象

    // Debugging
    // print_r($xml);

    $login = $xml->login;
    $secret = $xml->secret;

    if($login && $login != "" && $secret)
    {
     

        $sql = "UPDATE users SET secret = '" . $secret . "' WHERE login = '" . $login . "'";

        // Debugging
        // echo $sql;      

        $recordset = $link->query($sql);

        if(!$recordset)
        {
     

            die("Connect Error: " . $link->error);

        }

        $message = $login . "'s secret has been reset!";
    }

从上面的代码可以看出,sqli_8-1.php利用Ajax技术将xml数据发送到sqli_8-2.php后,进行xml解析,然后没有进行任何过滤直接将解析的数据拼接到sql语句中执行了,所以造成sql注入漏洞。修复方法:在拼接sql语句之前,将参数进行过滤或转义,或者使用PDO技术进行预处理和参数化。

相关函数:

file_get_contents(“php://input”) //访问请求的原始数据的只读流 详细

simplexml_load_string() //函数转换形式良好的 XML 字符串为 SimpleXMLElement 对象


11、SQL Injection - Blind - Boolean-Based

输入单引号直接报错:

image-20210417180426349 BWAPP之SQL注入通关_第45张图片

经过多次尝试,无论输入什么都只会回显The movie exists in our database!和The movie does not exist in our database!两种情况。如下图:

BWAPP之SQL注入通关_第46张图片 BWAPP之SQL注入通关_第47张图片
image-20210417180304352 BWAPP之SQL注入通关_第48张图片

于是判断是布尔盲注。


//猜解数据库名

先猜解数据库名长度

BWAPP之SQL注入通关_第49张图片 image-20210417182647890

测出数据库名的第一个字母ascii为96(b)

image-20210417181450961 image-20210417181504262

以此类推一共猜解5次测出数据库名为bwapp;


//猜解表名

先猜解数据库中表的数量

二分法测出表的数量为5

image-20210417182822493 image-20210417182829752

猜解第一个表的长度:

二分法猜解出表的长度为4

image-20210417183637184 image-20210417183646071

猜解第一个表的第一个字母

二分法测出为98(b)

image-20210417183230562 image-20210417183242726

然后通过更改substr的参数更换字母,逐个猜解出表名的每个字母;然后再更改limit的参数更换表名,重复上述过程猜解出每张表的表名。最后猜解出表名依次为blog,heroes,movies,users,visitors。


//猜解字段名,字段值与上述过程相仿。

总结猜解三步走:

1、猜解数量

例:and (select count(table_name) from information_schema.tables where table_schema=database())>6

2、猜解长度

例:and length(select table_name from information_schema.tables where table_schema=database() limit 0,1)>5

3、猜解值

例:and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>110

以上三步不断迭代方可制胜


12、SQL Injection - Blind - Time-Based

BWAPP之SQL注入通关_第50张图片 BWAPP之SQL注入通关_第51张图片
image-20210417210244431 BWAPP之SQL注入通关_第52张图片

如图所示,根据回显延迟的大小就可判断。只需将布尔注入的语句与if函数和sleep函数相结合便可完成注入。

扔进sqlmap中一会就完事。


收获

关于addslashes()函数绕过的三种方式

报错注入时一定要与concat()函数相结合,不然无法正常回显

报错注入的两种思路

盲注时三步走:猜解数量、猜解长度、猜解值

你可能感兴趣的:(sql注入,信息安全,mysql)