-
-
[原创]学习一下dom破坏!
-
发表于: 2025-7-16 13:59 2977
-
源码
分析
get传值somebody 直接给h2添加属性
payload
源码
分析
一样的get获取jeff的值 利用点在eval
我们可以闭合" 然后直接alert(1337)
payload
源码
分析
一样通过wey get传递值
但是经过了wey.replace(/[<>]/g, '') 过滤,过滤了 <>
然后通过innerHTML给uganda 赋值
因为不能通过 用户交互,所以我们不用on的点击时间
但是有一个自动获取焦点的函数 onfocus 并且这个函数有一个自动获取焦点的参数 autofocus
即可实现自动弹窗
payload
源码
分析
通过ricardo get传参 然后设置定时器 2秒自动提交给form表单
然后form 表单中有method 属性接收的GET 表单属性可以通过javascript: 伪协议解析alert
payload
源码
分析
get传承 markassbrownlee 获取值 , will.innerHTML = smith 添加属性,但是
smith.replace(/[\(\\)\\]/g, '') 过滤了()\
所以alert的这个括号 被过滤了,我们考虑通过实体编码绕过
因为我们在url地址栏传入的参数 先会经过浏览器进行decode 然后进入 js 接收到值后,通过了过滤函数,在进入html ,实体编码被解析为()
payload
源码
分析
过滤掉了大小写字母,还有数字
看见了eval函数 利用点就在这
现在就是考虑怎么绕过这个正则
想到了jsfuck
直接通过
这个编码,然后进行一下urlencode编码
payload
后面我们在 研究一下jsfuck 到底为什么可以通过这种方式来编码
源码
分析
这里限制了我们payload的长度不能超过50,且过滤了``' " + - ! \ [ ]` 所以这关完全限制了上一关的方法
而且他还过滤了 alert 所以我们不能用alert 但是我们还有另外两个可以用
confirm()、prompt()
这里我们可以直接利用,但是还有其他的办法
..toString() 可以将数字转换为字符
8680439:其实就是 30进制的alert
这里我们就是利用 这个函数
那为什么是30进制不是 其他进制 呢?
我们测试一下29进制
利用parseInt() 来看一下 转换alert是什么
这里可以看到 alert 的 t 转换回来消失了!!!
为什么呢?
A B C D E F G H I J K L M N O P Q R S T
这里我们知道A 是10进制可以进行转换
T 在第30位,我们合理的进行推测,T 是不是就是30进制呢?
所以我30~36都可以进行转换t
那么我们这个payload eval(8680439..toString(30))(1337)就完全可以绕过过滤,实现xss
这里我们可以清楚的理解到 是通过 location.hash.slice(1) 这个函数来传值,我们可以通过#来插入我们的恶意代码,但是我们的xss代码并不会进入正则过滤中
payload
因为js是严格区分大小写的 所以我们传入的ALERT 并不会被过滤,我们就要想办法将他转为小写
这里我们查官方文档了解一下Function()的作用
Function()是构造函数
在看看.source 是啥
返回正则表达式的文本内容(即 /pattern/flags 中的 pattern 部分),不包含分隔符和标志。
.toLowerCase()转小写
这个payload我们就知道先通过Function 构造函数 然后 传入 /ALERT(1337)/ 通过.source 获取到ALERT(1337 在通过 toLowerCase() 转成小写 ,最后()立即执行
这个payload的好处是我们可以绕过他的关键字匹配,构造自己的函数
payload
源码
分析
这里他引入了DOMPurify防御用户输入框架,这个框架至今都在维护,而且绕过的概率很低,所以我们不考虑绕过的方法
看到下面setTimeout(ok, 2000) 这里的ok并没有进行定义
那么我们可以使用dom clobbering称之为dom破坏技术
我们尝试传入这个来重新构造ok函数
但是发现被框架过滤了,我们去github上看一下,找一下白名单
/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))
这里测试发现
mailto|tel|callto|sms|cid|xmpp|matrix
全部都能够触发alert
payload
那么为什么我们会想到用A标签呢?
1.我们需要传入一个我们可控得字符,且他能被setTimeout 执行
toString
所以我们可以通过以下代码来进⾏fuzz得到可以通过toString⽅法将其转换成字符串类型的标签:
我们可以得到两种标签对象:HTMLAreaElement ()& HTMLAnchorElement (),这两个 标签对象我们都可以利⽤href属性来进⾏字符串转换。
HTMLAreaElement 是area但是他是一个空元素不能容纳任何内容,所以我们不考虑
那么就只剩下HTMLAnchorElement 这个的意思是锚点的意思,
也就是跳转,html中哪个标签可以跳转实现呢?
答案呼之欲出了:A标签的 href属性
所以这里dom破坏就是在a标签的herf属性上传入我们的xss代码!
<!-- Challenge --><h2 id="spaghet"></h2><script> spaghet.innerHTML = (new URL(location).searchParams.get('somebody') || "Somebody") + " Toucha Ma Spaghet!"</script><!-- Challenge --><h2 id="spaghet"></h2><script> spaghet.innerHTML = (new URL(location).searchParams.get('somebody') || "Somebody") + " Toucha Ma Spaghet!"</script><h2 id="maname"></h2><script> let jeff = (new URL(location).searchParams.get('jeff') || "JEFFF") let ma = "" eval(`ma = "Ma name ${jeff}"`) setTimeout(_ => { maname.innerText = ma }, 1000)</script><h2 id="maname"></h2><script> let jeff = (new URL(location).searchParams.get('jeff') || "JEFFF")