Thursday, March 14, 2013

Brute-Forcing Scripts in Google Chrome

A while ago I found leaking document.referrer vulnerability and even used it to hack Facebook.

It's Chrome's XSS Auditor again (severity = medium, no bounty again). Can be used with websites serving X-XSS-Protection: 1;mode=block header.

TL;DR there is a fast way to detect and extract content of your scripts.

Even after fixing document.referrer bug it is still possible to detect if Auditor  banned our payload checking location.href=='about:blank' (I remind you that about:blank inherits opener's origin).

XSS Auditor searches every string between "<script>" and first comma or (first 100 characters) against POST body, GET query string and location.hash content.

Scripts, events on* and javascript:* links often contain private information.

Following values can be extracted:
<a onclick="switch_off()"
<script>username='homakov',
<script>email='homakov@gmail.com',
<script>pin=87542,
<script>data={csrf_token:'aBc123dE',
<a href="javascript:fn(123)

I simply send tons of possible payloads and if some page was banned (payload was found in the source code) then we found which bunch contains the real content of script.

'map-reduce'-like technique:
  1. open 10 windows (10 for simplicity, we can use 25 windows. if target has no X-Frame-Options it can be way faster with <iframe>s) containing specific bunches of possible payloads:
    <script>pin=1<script>pin=2<script>pin=3<script>pin=4...
    from 1 to 1000000, from 1000000 to 2000000, from 2000000 to 3000000 etc
  2. if, say, second window was banned we should do the same procedure and open new windows with:
    from 1 000 000 to 1 100 000, from 1 100 000 to 1 200 000 etc and so on
  3. finally let's open 10 windows with  1 354 030, 1 354 031, 1 354 032, 1 354 033 ... and detect exact value hidden inside of <script> on the target page.
Definitely pwns your privacy but is it..

Feasible to brute force CSRF token?
1) XSS auditor is case insensitive, it makes bruteforce simpler: a-z instead of a-zA-Z.
2) csrf tokens happen to be quite short, 6-10 symbols.
3) 36 ^ 6 = 2176782336
4) every bunch checks 5 000 000 variants, We need 500 bunches
5) 25 windows per 10 seconds.  - 200 seconds.
6) now we found bunch containing real value — keep map-reducing this bunch and find the exact value - another 50-60 seconds
8) this value is case insensitive - to exploit it you should provide all possible cases of letters. around 50 requests and one of them will be successful.

200s (find 5 000 000 bunch containing real token)
+ 50s (detect real token in specific bunch)
+ 10s (send 50 malicious requests using <form>+iframe with all possible cases)
= 260s

approximately, exploitation time for different token size:
6 characters — 4.5 minutes
7 characters — 120 minutes
8 characters — 72 hours
Saving checked bunches in the cookie (next time you will continue with other bunches) + using location.hash (it is not sent on server side and can be very long) = plausible CSRF token brute force.

PoC — extract "<script>pin=162621"

Moral:
  • use 8+ characters in the CSRF token
  • all kinds of detections are bad. There is no innocent detections. A small weak spot can be used in a dangerous exploit.
    Today I found a way to brute-force 25 000 000 URLs / minute using location.hash detection (WontFix!). And keep making it faster. 
Bonus, how to keep malicious page opened for a long time:

No comments:

Post a Comment