I have been working on a medium-sized development project lately and, came 
across a peculiar phenomenon where I could execute scripts on a page without 
the use of  less-than (<) or greater-than (>) symbols. Instead I used 
double-byte characters. For a little detail on the project, the technologies 
being used include Apache Struts 1.3.8, the Commons Validator plug-in, 
DHTMLSuite, and some other AJAX style controls to make the UI interactive. So 
now on to the findings.

To start out, the character encoding on all of the JSPs were set to ISO-8859-1 
<http://en.wikipedia.org/wiki/Iso-8859-1> .  In addition, validation was in 
place for all form fields although as it turns out, much to my chagrin, that 
clever people can bypass anything. Since the field in question was free form, a 
user could enter anything they wanted, as we developers had decided was ok 
since we would be vigilant in our use of output encoding. For more info on why 
this is should be ok, check out Jim Manico's blog article here 
<http://manicode.blogspot.com/2008/08/input-validation-not-that-important.html> 
. To accomplish our output encoding, we decided to use the <bean:write /> tag 
from the Struts 1.3.8 tag library as it has a fairly decent encoding practice, 
although it does leave a little - or quite a bit depending on your point of 
view - to be desired. 

Now as I stated before, validation was being done on the field. The specific 
regex in use was ^[^<>]$. This very simple regex allows all characters that do 
not contain the less-than or greater-than characters. As the value submitted 
was being displayed in a div as text and was being "properly encoded" we felt 
safe. Then we started discussing the possibility of users submitting foreign 
characters. By foreign characters I mean characters such as ܼ or ܾ or even ܯ. 
That is when things got a little interesting. I should also state here that due 
to the architecture of the site, all form submissions took place via AJAX calls 
instead of normal form submissions. The reason that this is important to 
mention is that AJAX submissions do not format the data in the same manner that 
a normal form submission does. More on this in a minute.

ISO-8859-1 character-set encoding is an 8-bit, so single byte, character 
encoding specification. The foreign characters I just showed you are all 
double-byte characters. As it turns out, when you display a double-byte 
character on a page that is coded to display single-byte characters, the second 
byte of the character gets truncated. As such, the character ܼ  becomes < when 
displayed. The key phrase here is when displayed. It passed the validation 
because ܼ is not <. 

Now you may be asking, what about the output encoding provided by <bean:write 
/>? In this case it is no good. When one inspects the actual encoding 
implementation used by ResponseUtils, it only encodes the five major characters 
considered sensitive in HTML. These are <,  > , ", ', and &. So, for the same 
reasons that the string passes validation, it was not being properly encoded.

So what happened? We wrote a simple page that output the first 1,000 characters 
in hex format (&#1234;) then sampled them to see what would be displayed when 
the character was truncated due to the ISO-8859-1 setting in the JSP. The 
resulting atteck string: 

ܼscriptܾalert(1);ܼܯscriptܾ 

This string, when echoed to the page was displayed as 
<script>alert(1);</script>. Hello XSS!.

Now I promised more info on the form encoding. First off, we discovered that if 
we submitted the form via an HTML submit button (the normal way) that the 
attack did not take place. So we fired up Burp <http://portswigger.net/suite/>  
Suite and here is what was submitted:

%26%231852%3Bscript%26%231854%3Balert%281%29%3B%26%231852%3B%26%231839%3Bscript%26%231854%3B

As you can see this is the URL encoded form of the attack string listed above. 
This resulted in the display of harmless text to the resulting screen. On the 
other hand, when we submitted the form through AJAX the data sent was like this:

%DC%BCscript%DC%BEalert(1)%3B%DC%BC%DC%AFscript%DC%BE

It is obvious for one to see the difference in the encoding used. Why the 
encoding is different is also simple to explain. When one submits a form 
through an HTML submit button, the data in the form is encoded by the browser, 
which by default, uses application/x-www-form-urlencoded. AJAX simply does not 
do this. As a result, the server on the backend decodes the information 
differently thus returning different response data to the client for display. 
This different response, when used in conjunction with the display character 
encoding issues described earlier, results in potential XSS.

So how did we fix this, if you are wondering? First off we changed all of our 
JSPs to utilize UTF-8 as the character-set encoding so we were safe there. In 
addition, we made our regex significantly stronger.

I hope this helps!

Posted by Matt Presson at  
<http://coding-insecurity.blogspot.com/2008/10/executing-scripts-with-non-english.html>
 2:30 PM 

 

 

[Ph4nt0m] <http://www.ph4nt0m.org/>  

[Ph4nt0m Security Team]

                   <http://blog.ph4nt0m.org/> [EMAIL PROTECTED]

          Email:  [EMAIL PROTECTED]

          PingMe:  
<http://cn.pingme.messenger.yahoo.com/webchat/ajax_webchat.php?yid=hanqin_wuhq&sig=9ae1bbb1ae99009d8859e88e899ab2d1c2a17724>
 

          === V3ry G00d, V3ry Str0ng ===

          === Ultim4te H4cking ===

          === XPLOITZ ! ===

          === #_# ===

#If you brave,there is nothing you cannot achieve.#

 

 


--~--~---------~--~----~------------~-------~--~----~
 要向邮件组发送邮件,请发到 [email protected]
 要退订此邮件,请发邮件至 [EMAIL PROTECTED]
-~----------~----~----~----~------~----~------~--~---

<<inline: image001.gif>>

回复