通过分析前端js引发的SQL注入fuzz绕过代码层面和waf层面的双重防御
2023-6-28 13:56:47 Author: 星冥安全(查看原文) 阅读量:33 收藏

从js入手,审计js找到接口到直接将管理员的用户名和密码写在了上面,发现还是弱口令,最后成功登录进去测试每个功能点发现存在SQL注入后进行fuzz绕过代码层面和waf层面的双重防御。

这里在挖掘某项目的时候,通过信息收集发现了一个站点,这里为内部系统,访问的时候直接跳转进入到内部的http://x.x.x.x/home,但是却因为没有权限而提示非法操作:

那么这里便通过F12对其中的js进行审计,其中发现了/login的一个接口,这里拼接后发现跳转到登录处,其中直接将管理员的用户名和密码写在了上面,这里F12将密码处的password属性删掉,发现还是弱口令:


这里点击登录后,如愿进入后台。这里在开心之余,便想着能不能在管理后台找到其它的漏洞,提升危害,于是这里便对内部的每个功能点进行点击抓包,其中在一个功能点发现了端倪。这是列出某门店排行榜的功能点,其中的busiModelList参数引起了我的兴趣。一开始它的参数值是空的:

然后自己添加上参数值:


在我加上单引号的时候,却开始报错:

然后再加上一个单引号又成功了:

我顿时虎躯一震,莫非,这里存在SQL注入?

那么这里开始fuzz数据库类型。其中带上注释符,--+不行而#却可以,这里数据库类型初步判断为MySQL


这里额外插入一下判断是否为MySQL数据库的小tips(这里采用别的站为例子来说明):
第一种证明方法:
用内联注入来证明这里是MySQL,因为内联注入是MySQL特有的注入:
这里先用’))来闭合,然后对后面的数字0进行注释,/*0*/,成功无数据:


可是这里进行内联注入,/*!0*/,成功执行后面那个数字0,成功导致交易进行错误的报错:

成功证明这里可以内联注入,所以这里为MySQL

第二种方法:
mysql在运行+号运算的时候,会将数字加起来不管是字符类型还是什么

像这里system参数在置空也就是我所认为的False的情况下也会返回数据

因为都是字符串所以加起来等于0也就是False返回了数据,跟上面那种置空的效果一样

那么这里后端的SQL语句大概如下,最后结果是0所以也返回了数据
SELECT xxx from xxx where xxx=xxx and dddd=dddd and system='jgxcl'+ database() +'a'

但是把最后的+'a改成数字的话,这样的结果最后就是返回数字就不会正常的返回数据
SELECT xxx from xxx where xxx=xxx and dddd=dddd and system='jgxcl'+ database() +'1'


跟填1同等效果

那么这里重新回到这个站,其中初步判断为MySQL后,这里我两眼放光,心中已经按捺不住的兴奋了。好久没在src碰到SQL注入了,今天在搞活动的时候却给我碰到了,真是好运来。然后这里只需要判断有无waf,如果没waf就可以直接一把梭了。正当我幻想着终于又能疯狂星期四的时候,这里却直接当头一棒打断了我的幻想。经过fuzz后,发现这里不仅用了阿里云waf,还有他们自己的代码层防御,真是雪上加霜。
像这里0 and 1虽然没被阿里云waf拦截,但是却被代码层防御了:


然后一波未平一波又起:这里带上sleep()函数直接被阿里云waf拦截:


其中代码层防御的绕过还算简单,像and换成&就能绕过了(功能不同是这个符号是与):


可是阿里云waf想绕过确实是要费点功夫。不过功夫不负有心人,这里最终用hpp传入多个同名参数+多行注释符/**/成功绕过:
注:HPP传入多个同名参数默认是.net环境可以,所以.net 环境下绕过一般可以采用hpp(即基本在windows服务器环境下可以使用绕过,linux一般不可以,但是也都可以试一试)

然后就是构造出true跟false两种状态,这里使用exp(1) 跟exp(710) 配合if ,注: exp(710) 在mysql会错误,这里1=1返回成功
'& if(1=1,exp(1),exp(710)) &'1

1=2页面错误
'& if(1=2,exp(1),exp(710)) &'1


最后通过substr一位一位获取ascii值

这里写个脚本:


关于脚本,其中需要注意的是这里因为用的是hpp传入多个同名参数绕过,即有多个相同参数名,不同的值。那么这里不能像往常一样**"busiModelList": "……","busiModelList": "……"**这样列出,这样它最终传入的只会是最后一个参数值。这里的解决方法是提前用Tuple元组依次存储参数值,然后传递给参数即可。这里也不能用{ },即dictionary,因为dictionary无法包含duplicate key,而且dictionary是无序的,所以无法满足要求。

然后这里写个proxy可以使用burpsuite对该python脚本的post请求抓包进行查看调试等等,其中如果遇到目标站点是https的,需要在requests.post处多写个verify=False

转载:https://forum.butian.net/index.php/share/2271作者:Johnson666欢迎大家去关注作者

欢迎师傅加入安全交流群(qq群:611901335),或者后台回复加群

如果想和我一起讨论,欢迎加入我的知识星球!!!

扫描下图加入freebuf知识大陆

师傅们点赞、转发、在看就是最大的支持

后台回复知识星球或者知识大陆也可获取加入链接(两个加其一即可)


文章来源: http://mp.weixin.qq.com/s?__biz=MzkxMDMwNDE2OQ==&mid=2247491321&idx=1&sn=c60aeff3a76ef7c64f2ea784018ac4eb&chksm=c12c283ff65ba1298aea634e9d0888a5c88f0b699e93b26a4fc67c49c44cd3f781918070d56e#rd
如有侵权请联系:admin#unsafe.sh