网络安全7

一.复现单个循环,过滤标签的属性。

<html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <title>Document</title>
    </head>
    <body></body>
    <script>
// http://127.0.0.1/domfilter/demo6.html#<img src=1 οnerrοr=alert(1)>
    const data = decodeURIComponent(location.hash.substr(1));
    const root = document.createElement("div");
    root.innerHTML = data;
//这里模拟了xss过滤的过程,方法是移除所有属性
    for (let el of root.queryselectorA11("*")) {
        for (let attr of el.attributes){
            el.removeAttribute( attr.name);
        }
    }   
        document.body.appendChild(root);
    </script>
</html>

过滤方式:截取#后面的值,创建一个div,把#后面的值赋值给div,然后抓div的子元素,获取它的属性,再把子元素的属性全部删除。

我们先输入#aaa看看 

 

 在输入<script>alert(1)</script>看看结果

 这里是因为用innerHTML添加的<script>无法执行

我们再用单步执行看看里面是怎么运行的
 这里data已经抓取到img标签 

 

 这里已经获取到了第一个src

 但是到了下一步,却获取不到onerror了

最后跳出了循环,没有删除onerror
这其中的原因是:本来是要删除2个,第一个src,第二个onerror,当他删除掉了第一个src的同时,第二个便往前移了移位,变到了现在的一个,for循环现在要删掉第二个时,发现第二个已经没有了,本来的第二个现在跑到了第一个,所以直接循环结束,没有删除onerror。

所以我们可以利用这一机制,将img标签中放入其他的属性,删除其他的属性来让我们要输出有用的属性进行输出。下面来验证这一想法,输入<img src=1 onerror=alert(1) title=aaa> 

 可以看到我们的想法确实可以实现,但是src也被删除了,所以我们再添加一个属性,然后换个位置,输入<img x=1 src=1 title=aaa onerror=alert(1)>

 

 可以看到输出了哦我们要输出的属性并且成功弹窗
其他答案:<svg/a/onload=alert(1)>

二.两次循环,过滤标签里的属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>

</body>
<script>
    const data = decodeURIComponent(location.hash.substr(1));;const root = document.createElement( 'div ' );
    root.innerHTML = data;
    //这里模拟了xss过滤的过程,方法是移除所有属性,sanitizer
    for (let el of root.querySelectorA11('*')) {
    let attrs = [];
    for (let attr of el.attributes){attrs.push(attr.name);
    }
    for (let name of attrs) {el.removeAttribute(name);}
    }
    document.body . appendchild(root);
</script>
</html>
    

 这里有两种思路(1)不进循环 (2)进循环不删除有用的属性

先试试一次循环的答案放在这里看是什么样子

 可以看到输入的<img src=1 οnerrοr=alert(1)>里面的元素都没了,只剩了一个img标签。

进循环不删有用的数据 

如果有一个元素可以拦截el.attributes,有可能删除的不是el而是里面的子元素,比如说在div标签里有form和img两个元素,将img的值删掉让form弹窗;要想进循环只有一个元素肯定不行,所以要想办法变成一个数组来进入循环,所以可以写进2个img 

 可以看到确实进入了循环,但是form没有触发,这里就需要用onfocus,而onfocus是input的属性,form没有,但是也要把焦点对到input里面,所以要用到tabindex(tabindex 全局属性 指示其元素是否可以聚焦,以及它是否/在何处参与顺序键盘导航)<form tabindex=1 οnfοcus="alert(1)" autofocus="ture"><input 20name=attributes><input name=attributes></form> tabindex=1聚焦在input的子元素上;autofocus="ture“自动聚焦

 弹窗可以但是这无限聚焦所以点了确定依旧弹窗,所以要加上执行一次就删除onfocus即<form tabindex=1 οnfοcus="alert(1);this.removeAttribute('onfocus');" autofocus="ture"><input 20name=attributes><input name=attributes></form> 便可以实现

不进循环

<svg><svg/οnlοad=alert(1)> 

 我们在循环前后都打上断点,发现是没有进入循环直接输出了

 2个svg会提前执行,一个却不会
JS会把dom树阻塞,如果一个img或者1个svg都会在js执行后才会执行且属性以及被删除了;而2个svg里的最内侧svg是在html赋值的瞬间就把onload事件加载了所以就没有进入到js的删除事件里
img和其他payload的失败原因在于sanitizer执行的时间早于事件代码的执行时间,sanitizer将恶意代码清除了。由于js阻塞dom树,一直到js语句执行结束后,才可以引入img,此时img的属性已经被sanitizer清除了,自然也不可能执行事件代码了。最内层的svg先触发,然后再到下一层,而且是在DOM树构建完成以前就触发了相关事件;最外层的svg则得等到DOM树构建完成才能触发。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值