Gainover · 2014/02/24″
0x00 Translator’s words
This article is based on a 2013 paper by Mario Heiderich on mXSS Attacks: attacking well-secured web-applications by using innerHTML mutations. In my opinion, this type of mXSS attack is stealthy and cannot be prevented by regular XSS filters. After testing such problems in QQ space logs, I believe that mXSS still has great potential harm in WEB applications, so I decided to make a translation of this article. However, due to the limited level, I can only rely on my own superficial understanding to roughly translate. The pictures and codes in the article are re-elaborated on my own understanding, which may be easier for readers to grasp. Students who are good at English can read the original English version by themselves. Secondly, I personally only focus on the part of “attack”, the part of this article that I think is not very practical, and the large paragraphs on how to defend against such attacks, I did not translate, so readers who need to understand these parts need to know for themselves. In any case, I hope this paper can make domestic researchers have a basic understanding of mXSS.
0 x01 profile
Both server-side and client-side XSS filters assume that the filtered HTML source code should be the same as the HTML code rendered by the browser, or at least not significantly different (Figure 1). However, if the user-supplied rich text enters the innerHTML attribute through javascript code, some unexpected changes can make this assumption invalid: A seemingly innocuous string of HTML code escapes the XSS filter and ends up in the innerHTML of a DOM node, where the browser’s rendering engine renders innocuous HTML code into potentially dangerous XSS attack code. This attack code may then be output into the DOM by some other process in the JS code or rendered again in some other way, resulting in the execution of XSS. The XSS attack is the result of an unexpected mutation of the HTML content as it enters the innerHTML. It is called mutation-based XSS (mXSS, mutation-based cross-site-scripting), and the schematic diagram of the whole process is shown in Figure 2. As can be seen from the flow, the mutation occurs after the XSS filtering process, so the XSS filters on both the server and client side cannot effectively defend against such attacks.
Figure 1. Assumptions for XSS filtering
Figure 2. MXSS attack flow
Placing content in innerHTML is common in WEB application code. According to the author, about a third of the 100 million common WEB applications use the innerHTML attribute, which is a potential mXSS attack. From a browser perspective, mXSS has an impact on all three major browsers (IE, CHROME and FIREFOX). Table 1 lists the types of mXSS known to date, and the following sections discuss and explain each of them. It is recommended that you test the code in this article primarily using IE8. The specific test code is as follows:
#! <div id="testa">xx</div> <div id="testb">xx</div> <script> "-> \", \ -> \ var m=" Enter the HTML code to be tested here "; InnerHTML var x= document.getelementById ("testa"); x.innerHTML=m; Var HTML = x.innerhtml; //2. //3. Alert (HTML); Document.getelementbyid ("testb").innerhtml = HTML; </script>Copy the code
Table 1. Types of mXSS covered in this article
English | Chinese |
---|---|
Backtick Characters breaking Attribute Delimiter Syntax | MXSS caused by backquotes breaking property boundaries |
XML Namespaces in Unknown Elements causing Structural Mutation | MXSS caused by the XMLNS attribute in an unknown element |
Backslashes in CSS Escapes causing String-Boundary Violation | MXSS caused by backslash escape in CSS |
Misfit Characters in Entity Representation breaking CSS Strings | MXSS caused by double quoted entities or escapes in the CSS |
CSS Escapes in Property Names violating entire HTML Structure | MXSS caused by escape in CSS property names |
Entity-Mutation in non-HTML Documents | Entity mutation in non-HTML documents |
Entity-Mutation in non-HTML context of HTML documents | An entity mutation in an HTML document that is not HTML context |
0x02 Backquotes breaking attribute boundaries cause mXSS
This type of mXSS was one of the first to be discovered and exploited. It was proposed in 2007 and has since been effectively fixed so that the majority of current users’ browsers are not affected by this TYPE of mXSS. The usage code at that time is as follows:
#! <img SRC ="test.jpg" Alt =" onload= XSS ()" /> <IMG Alt = 'onload= XSS () SRC ="test.jpg"> You can see that the mutated form becomes a valid XSS attack code.Copy the code
MXSS caused by XMLNS attribute in unknown element 0x03
Some browsers don’t support HTML5 tags, such as IE8, which treat article, aside, menu, etc., as unknown HTML tags. Unknown tags for developers, but you can let the browser know what the XML namespace of these unknown tags is by setting the XMLNS attribute for them. In general, specifying the XMLNS attribute for these unknown tags doesn’t make any sense in HTML, nor does it change the way they look in the browser. However, when these tags, with the XMLNS attribute specified, enter innerHTML and are rendered by the browser, there are some changes that are spookily applied to XSS. Let’s start by looking at the normal setting of XMLNS.
#! HTML input format: <pkav XMLNS ="urn:wooyun">123 Mutant format: <wooyun:pkav XMLNS ="urn:wooyun">123</wooyun:pkav>Copy the code
Then the creep stream will quickly come up with the following code, which shows that success becomes the IMG tag with onError =alert(1).
#! XMLNS ="urn:img SRC =1 onerror=alert(1)//"> <img src=1 onerror=alert(1)//:pkav xmlns="urn:img src=1 onerror=alert(1)//">123</img src=1 onerror=alert(1)//:pkav>Copy the code
Extension: Careful students may notice that we do not have a closed tag in our code. A common scenario, then, is that the XSS filter will automatically complete closed tags as it parses HTML code. In this case, the following scenario would appear:
#! HTML input format: <pkav XMLNS ="urn:wooyun">123 Filtered form: <pkav XMLNS ="urn:wooyun">123</pkav> Mutant form: <? XML:NAMESPACE PREFIX = [default] urn:wooyun NS = "urn:wooyun" /><pkav xmlns="urn:wooyun">123</pkav>Copy the code
We are smart enough to think of a solution, and this is probably how the problem described in html5sec.org/?xmlns#97 was discovered (by Silin in 2011).
#! HTML input form: <pkav XMLNS ="><iframe onload=alert(1)">123</pkav> XML:NAMESPACE PREFIX = [default] ><iframe onload=alert(1) NS = "><iframe onload=alert(1)" /><pkav xmlns="><iframe onload=alert(1)">123</pkav>Copy the code
0x04 mXSS caused by backslash escape in CSS
In CSS, characters can be escaped using \, for example: Property :’v \61 lue’ for property:’value’, where 61 is the ASCII (hexadecimal) code of the letter A. Unicode can also be used after \, for example: \20AC for €. Normally, this escape should not be a problem. But when you hit innerHTML, something amazing happens. Look at the following code.
#! Font-family :'ar\27 \3bx\3a expression\28xss\28\29\29\3bial';" < p style=" max-width: 100%; clear: both; min-height: 1em; x:expression(xss()); ial'"></P>Copy the code
As you can see, in the mutant form, all escape forms in the input attribute value of the font-family are decoded back to their original form. Where \27 is decoded as a single quote, the font-family attribute is closed in advance, and our custom X attribute is inserted, using expression to execute Javascript code. If combined with some of the XSS tricks in CSS that we’ve seen before, the situation looks even worse. For example, in the following code, it looks like we can mess up expression.
#! <p style=" max-width: 100%; box-sizing: border-box! Important; 27 \3bx\3a ex\5cpre\2f**\2fssion\28 xss\28 1\29\29\3bial';" < p style=" max-width: 100%; clear: both; min-height: 1em; x:ex\pre/**/ssion(xss(1)); ial'"></P>Copy the code
0x05 mXSS caused by double quoted entities or escapes in CSS
Following the previous section, again the problem with CSS, since backslash escapes are decoded to their original form, the following situation occurs.
#! <p style=" max-width: 100%; clear: both; min-height: 1em; . ';" ">< p style=" max-width: 100%; clear: both; min-height: 1em; . ';" ></p>Copy the code
This way, can’t you insert any tag? That’s a good idea. But what about the reality?
#! <P style=" font-family: 'aaaa'><img onerror... .'"></P>Copy the code
Not as we thought, but as our \22 turned out to be single quotation marks, and according to the author of the original text, we can only speculate as to the reason for this strange result: \22 was decoded to “, but the browser rendering engine changed “to” to avoid this, considering that the double quotes would close the style attribute. Of course, this also means that, in addition to \22, \0022, HTML entities such as “. ” & # 34; Such double quotation marks can cause this problem.
0x06 mXSS caused by escape in CSS property name
In the case of CSS property values described in the previous two parts, what happens if a backslash escape occurs in the CSS property name? See the code below.
#! <img SRC =1 style=" font-family :' fam\22onerror\3d alert\28 1\29\20 ily:'aaa'; "> <IMG style=" max-width: 100%; clear: both; min-height: 1em;Copy the code
As you can see, we embedded the escaped content in the name of the font-family property. After the mutation, \22 is decoded back into double quotes and the style property is closed, so we can execute javascript code through the onError event. Note that =, parentheses, etc., also need to be escaped. We can also close the img tag by adding \3e after \22 and insert our own HTML tag after that.
Sometimes, we also encounter style attributes with single quotes as the boundary. In this case, the style boundary will be rendered back into double quotes, and our \22 will still do its job, for example:
#! <p style="fo'" "o: bar"></p>Copy the code
0x07 mXSS caused by Listing tag
In addition, in the PPT of the original author of this article, there is also a mXSS caused by the
#! HTML input form: <listing>< img src=1 onerror=alert(1) > <img SRC =1 onerror=alert(1) ></ listing>Copy the code
In WooYun: Qzone log storage XSS-15 caused by a function defect, the author used this tag to trigger mXSS (currently valid under IE8 and IE9). Readers can refer to the actual case to further understand the attack and mining process of mXSS.
0x08 Javascript code vulnerable to mXSS attacks
The different kinds of mXSS have been explained above, so what kind of code is vulnerable to mXSS attacks? According to the mXSS flow in Figure 2, user-supplied content must be put into the DOM at least twice in JS code before an XSS attack can be triggered. The author gives the following code scenario:
1) a.innerHTML = b.innerHTML ;
2) a.innerHTML += 'additional content';
3) a.insertAdjacentHTML ( 'beforebegin' , b.innerHTML ) ;
4) document.write (b.innerHTML) ;
Copy the code
The b.innerHTML in 1) and 4) contains the mutated content, which is output to the DOM again as innerHTML or document.write, triggering the mXSS. 3) The insertAdjacentHTML function (an enhanced version of innerHTML) is used to add b.INnerHTML with mutated content to A, resulting in mXSS. While 2) is more subtle, there is mutated content in A. innerhtml, when we append content to A. innerhtml with +=, A will be re-rendered, triggering mXSS.
0 x09 summary
There are two categories in the original text: entity mutation in non-HTML documents and entity mutation in NON-HTML context in HTML documents. I think the actual application scenario is not rich, SO I will not elaborate, interested researchers can understand by themselves. I hope that after reading this article, we can provide some ideas of things. Don’t forget to share with me if you find any surprises in this area: [email protected] (XSS is welcome).
0x10 References
1. Heiderich, M., Schwenk, J., Frosch, T., Magazinius, J., & Yang, E. Z. (2013, November). mXSS attacks: attacking well-secured web-applications by using innerHTML mutations. In Proceedings of the 2013 ACM SIGSAC conference on Computer & communications security (pp. 777-788). ACM.
2. Heiderich, m. The innerHTML Apocalypse. www.slideshare.net/x00mario/th… . Security Research / Penetration Testing at Cure53 on Apr 25, 2013