Wednesday, April 21, 2010

Fooling B64_Encode(Payload) on WAFs and filters

When dealing with Web Application Firewall, IDSs or application filters trying to block attacks there are always two big problem:
  • Completeness
  • Correctness
We know Regexp could be faulty, but let's suppose there's some sort of encoding in the payload which is furtherly decoded on some server side layer and then used in clear text to pass it to another layer.
A good defense should be to let the WAF/Filter decode it and check for attack patterns (using regexp..).
Now the question is how can I implement a decoder to get the input back in clear?
Let's talk about Base64.

Base64 encoding and decoding are implemented in many ways and many languages.
For example PHP base64_decode() is:
  • Very greedy.
  • Goes ahead even if something goes wrong

Even some Java Implementation is kind of greedy:
com.sun.org.apache.xerces.internal.impl.dv.util.Base64

public static byte[] decode(String paramString) {
if (paramString == null) {
return null;
}
char[] arrayOfChar = paramString.toCharArray();
int i =
removeWhiteSpace(arrayOfChar);


The question is: How to rely on WAF or filters controls if they miss some
behaviour?

NoScript checks for Base64 encoded Xss.
ModSecurity implements Base64 decoding using the following rule:

SecRule ARGS:b64 "alert" "t:base64decode,log,deny,status:501"

So the following payload is caught by both:
b64_encode("<script>alert(1)</script>");

PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==

Mod_Security:

NoScript:



But since the real decoder is on another layer, let's try with PHP's decoder
using the illegal character '.':

P.HNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==

Here's what happens:



ModSecurity (v. 2.5.6-1) and NoScript (v. 1.9.9.61) are bypassed.
Same happens for other illegal character.
Now NoScript is fixed (v. >= 1.9.9.62) and I expect ModSecurity to be fixed soon.

The question still remains.
How to rely on WAF or filters controls if they miss some behaviour?

WAFs and IDSs are good for defense in depth.
So don't rely too much on those.
Apply SSDLC by implementing correct filters and controls and
Test, Test, Test in your own environment!

6 comments :

  1. Nice write up! I've often wondered why base64 decoding is so forgiving. I suppose a good WAF will have to consider all possible variations... ugh.

    ReplyDelete
  2. Yes, endless variations. Please see my response here:

    http://blog.modsecurity.org/2010/04/impedance-mismatch-and-base64.html

    ReplyDelete
  3. @thornmaker, thanks.

    Altough Noscript actually fixed it, it seems they're not going to fix it.
    http://blog.modsecurity.org/2010/04/impedance-mismatch-and-base64.html
    Their suggestion is about using a positive rule.
    I wrote about it 5 years ago (http://www.wisec.it/sectou.php?id=438064b3e5ea4 ) and I still don't see it using correctly on WAFs.

    My suggestion still remains in implementing good secureSDLC.

    ReplyDelete
  4. Brian, I didn't see your comment sorry.
    You're stating that companies should not rely on modsecurity b64 decoder and that they should add a positive rule?

    It seems to me a choice for them as well as it is a choice implementing controls on application after the payload is decoded on the correct layer..

    ReplyDelete
  5. http://www.ietf.org/rfc/rfc2045.txt
    Page 25:
    Any characters outside of the base64 alphabet are to be ignored in base64-encoded data.
    ...
    That's about the rfc implementation.

    ReplyDelete
  6. The final of the history:
    it seems that ModSecurity people agreed about the too strict implementation of Apache APR base64 decoder.
    So probably they will give us two B64 decoders:
    strict and flexible..

    I'm very proud and satisfied now! :)
    @Brian, thanks for the interesting discussion on this topic.

    ReplyDelete