innerHTML与outerHTML属性在xss挖掘当中的实际作用

0x00 前言

本篇文章主要是呼应一下我前两天向Hook_JS库当中推送的Hook_innerHTML以及昨天晚上推送的Hook_outerHTML这两个脚本,单独拎出来写一篇文章是因为我觉得有必要向一些没学过js的朋友们介绍一下该怎么通过标题这两个属性和我那两个脚本快速挖掘到一个xss,我本人也是用hook innerHTML属性的那个脚本挖到过xss,不过可惜不是存储,具体看下文。

0x01 正文

先给大家看一下我自己写的一段demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>留言板</h2>
    请输入内容:<input type="text" id="ipt">
    <button id="btn">提交</button>
    <div id="tempdiv"></div>
<script>
    var btn = document.getElementById('btn');
    btn.onclick = function () {
        var ipt = document.getElementById('ipt');
        var div = document.getElementById('tempdiv');
        var temp1 = document.createElement('div');
        temp1.innerHTML = ipt.value;
        div.appendChild(temp1);
    }
</script>
</body>
</html>

d2b5ca33bd20250221003151

d2b5ca33bd20250221003159

这是一个留言板功能,输入内容点击提交后就会自动插入到下面的div中。我在代码中实现主体插入功能的部分是在button的点击事件中:

d2b5ca33bd20250221003207

我创建了一个div,但是还没有插入到页面中,然后给这个div设置了innerHTML属性值,它的值就来自于input里的值,然后就会插入到button下面的div中,效果:

d2b5ca33bd20250221003224

那么到底该如何利用这个innerHTML属性去挖掘xss,我给大家看一下MDN里对innerHTML属性的介绍大家就明白了:

d2b5ca33bd20250221003230

讲人话就是我们可以通过它来获取某个元素内部的全部内容(包括标签),我简单演示一下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <div id="test">
    <h1>测试</h1>
    <strong>test</strong>
  </div>
</head>
<body>

</body>
</html>

 

d2b5ca33bd20250221003253

我在div中写了h1和strong这两个标签,然后我获取一下div的innerHTML属性值:

var div = document.getElementById('test');
console.log(div.innerHTML);

d2b5ca33bd20250221003312

可以看到我在div标签内部写的内容全都被打印出来了,包括它们的标签,这也就是说当我们给某个元素设置innerHTML属性值时,如果设置的值里面携带了html标签,那么就会被解析,我用上面那个留言板给大家演示一下:

<img src="x" onerror="alert(1)">

d2b5ca33bd20250221003331

d2b5ca33bd20250221003337

成功解析,所以一旦有网站通过innerHTML属性设置了我们向后端传入的值,那么就会造成xss。接下来我用我前两天发布的Hook_innerHTML脚本再给大家看一下插入后的效果:

d2b5ca33bd20250221003808

当设置了innerHTML属性值时就会打印出该元素,所以我们可以通过这个脚本来探测哪些位置将我们传到后端的值拿来设置了innerHTML属性。

不过innerHTML还有一个名称长得差不多一样的属性,那就是innerText,这个属性不会解析标签,例如我还拿上面那个测试案例给大家演示一下:

var div = document.getElementById('test');
console.log(div.innerText);

d2b5ca33bd20250221003408

可见并没有输出标签内容,而是将该标签内部的文本内容打印出来了,也就是说这个属性只会获取其元素内部的文本内容,MDN介绍:

d2b5ca33bd20250221003415

回到正文,还有一个属性和innerHTML差不多,那就是标题中提到的outerHTML:

d2b5ca33bd20250221003435

那么这俩有什么区别,我演示一下大家就明白了:

d2b5ca33bd20250221003441

可以看到outerHTML属性将整个元素内容以及它自己都输出了,而innerHTML只会输出它元素内部的内容,这就是outerHTML和innerHTML属性之间的区别。所以但当我们在通过outerHTML属性替换目标元素内容时,会将目标元素的所有内容都替换掉,例如:

var div = document.getElementById('test');
div.outerHTML = 1;

d2b5ca33bd20250221003501

d2b5ca33bd20250221003506

可见替换后就剩了个1,现在我将刚刚的那段xss拿过来进行测试:

d2b5ca33bd20250221004104

d2b5ca33bd20250221003513

d2b5ca33bd20250221003520

成功触发。

所以我也写了一个脚本来获取网站用这个属性设置的值,不过该脚本只会输出网站设置它的值以及调用堆栈:

d2b5ca33bd20250221003529

效果和上面那个hook innerHTML属性的脚本不太一样,所以这点需要读者们使用时注意一下。

本文提到的两个脚本地址:https://github.com/0xsdeo/Hook_JS/tree/main/Hook_xss

© 版权声明
THE END
喜欢就支持一下吧
点赞46赞赏 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容