Testing Web Applications With Embedded Tokens

Not a long time ago most web applications did not have any kind of protection against Cross-site Request Forgery attacks and life was easy for pen-testers. Using a tool like the Burp Suite a tester could locate all the forms in an application and use the automated fuzzer to look for low-hanging fruit like simple XSS instances, SQL injections and all sorts of information disclosure and problems with cookies. This situation has changed lately and nowadays many frameworks give you the possibility of embedding single-use tokens into hidden form fields and URLs. Most automated fuzzers do not have any notion of tokens and they are of little or no use in this new scenario. Using a dumb fuzzer all we get is a redirection to a default page and the potentially hazardous parameters are never retrieved.

Here I provide an extension for the Burp Suite that aims to solve or at least mitigate this problem. As always, here is the source code:

burp_extension.tar.bz2

The working of the extension is really simple. By right-clicking on a packet in any of the tools we can access a dialogue named set dynamic token file. From this dialogue we can select a plain-text file that contains the types and names of the tokens we are interested in. The test.txt file in the tarball has the following content:

POST __TestToken1
GET _TestToken2
GET __TestToken3
POST TestToken4

The format should be self-descriptive. The first word indicates the type of request the token will be used in and the second is it’s actual name. Before you ask, nothing stops us from having two entries with the same name and different types and they will work as expected. However, entries with the same type and name will do nothing but slowing down Burp and will not generate any kind of warning.

After a token file has been loaded the extension works behind the scenes parsing every response in scope and keeping track of the value of all the tokens we are interested in. If, at any time, we want to use a tool like the Repeater or the Intruder we just go about it as usual and the extension will automatically substitute the correct value for the tokens. This way we can use our fuzzer the same way we were used to and it will magically work.

I think the code is quite simple so I will not explain it here. All questions, comments, and suggestions are welcome.

Take care and Happy Hacking!

[11-01-2011] I have just updated the extension with some bugfixes and the ability to generate timestamps for fields that require it. The link in the post now points to the updated tarball.

Comments (8)

  1. 6:18 pm, January 11, 2011am  / Reply

    Hello man,

    This is sort of off-topic but i’m trying anyway, perhaps you can help me…..
    I saw you have commented here : http://blog.nibbles.fr/1837
    and i was curious if you understand everything from that article and you could answer me to some questions about that…..

    Thanks a lot!

  2. 11:50 pm, January 11, 2011digital  / Reply

    I’m not sure I will be able to help you but ask your questions and I’ll do my best to answer them.

  3. 6:40 am, January 12, 2011am  / Reply

    Thanks a lot! I’ll write them here:

    Regarding the reading part:

    a)
    for($i = 0; $i < 5; $i++) {
    $v[$i]=$fakezval.$i; // we repeat the same value several times to overwrite the zval that was freed
    }

    $fakezval.$i will overwrite the freed zval? Can you give some more details?

    b) in the last example, how is the parameter to 'system' passed?

    c)
    also i'm trying to create manually a serialized string:

    $a= unserialize('a:1:{i:0;C:16:"SplObjectStorage":173:{x:i:2;i:0;,a:10:{i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:10;};O:8:"stdClass":0:{},i:1;;m:a:2:{i:1;S:19:"0100AAA01101\x00BBCCC";i:2;r:11;}}}
    ');

    It gives me an error because of the string "0100AAA01101\x00BBCCC"

    but if i try to unserialize this string separately:

    $s = 'S:19:"0100AAA01101\x00BBCCC"';

    echo unserialize($s) . ' ccccc';

    it doesn't give me any error. any idea why?

    Thanks again!

  4. 8:23 am, January 13, 2011am  / Reply

    don’t know any of these ?….

    • 11:50 am, January 13, 2011digital  / Reply

      a) If you look at the big comment before that code you will see that after r:1;,s:4:”BBBB” is parsed the reference to “AAAA” is no longer valid. This happens be
      cause a duplicate is detected and the reference count is decreased. The referenc
      e is not valid but the data is still on the stack, waiting to be overwritten by the creation of a new variable.

      In $v[$i]=$fakezval.$i PHP will change the stack pointer to make room for the ne
      w variable using the same address that was used for “AAAA”. Note that “BBBB” is
      still pointing there so effectively anything we write to $v will be referenced o
      n access to “BBBB”.

      b) In the last code snippet there are two $fakezval variables. If you read the p
      ost carefully you will see he has got control over the instruction pointer. He k
      nows the address of the system function, which takes it’s parameter from the sta
      ck. Using the same trick as in the previous question he gets the string “sh” ont
      o the stack (that is the first integer in $fakezval2 (translate those hex values into ASCII) so that when system gets called it will find it and take it as it’s first parameter.

      c) I haven’t had the time to try this yet, at first sight it looks like the reference at the end on the string might be wrong (r:11;). If I have the time to look into it I will let you know.

  5. 7:02 pm, January 13, 2011am  / Reply

    “In $v[$i]=$fakezval.$i PHP will change the stack pointer to make room for the ne
    w variable using the same address that was used for “AAAA”.”

    can you give me some hint about how/where is the stack pointer changed?

    so $fakezval. $i will be allocated at he adress of ‘AAAA’ ?
    Again, can you point me to the php sources where to take a look?

    Note that “BBBB” is
    still pointing there so effectively anything we write to $v will be referenced o
    n access to “BBBB”.

    You mean, that with the code
    $objst->rewind();$objst->next();

    we will go to the secondd element (‘BBBB’) which has a reference to the ‘AAAA’ and now we will find at that address everything that is written into $v array? I understood correctly?

  6. 3:21 am, March 29, 2011Andre Gironda  / Reply

    Burp Pro 1.4beta now has support for anti-CSRF token and other anti-automation for all modules (e.g. Intruder, Scanner, Spider, Sequencer, et al).

    However, previous to Burp 1.4beta, one could implement automation against anti-automation, including anti-CSRF tokens by using the recursive grep Intruder payload set. This is only available in the Intruder module, but it suffices.

    recursive grep is easy to configure, as well. You go into the options, extract grep portion of the configuration and add the relevant portion of the response, probably as regex ending ni the token name (along with the equals sign if it’s there), which is typically found in either the HTTP header response or the HTML body as a body parameter. Set the stop capturing field, which is below the extract grep configuration. Usually this would be a quote or double-quote character. You may also need to set the max-length (some CSRF tokens and other anti-automation varies, so it’s best to collect a few before you settle on a maximum length).

    Back in the intruder payloads section, the `select “extract grep” item to use’ field should be automatically set to the extract grep field added in the options tab. Configure the first payload as the first token found (usually the one in the intruder positions tab that was sent via the proxy history). Put it to work by using intruder menu, “start attack” as normal. That’s it — and I know you’re thinking this sounds like a mouthful, but really it’s not that bad. In some ways, I almost prefer it to the new Burp Pro 1.4beta macro language that is necessary (although it’s worth it to be able to use Spider, Scanner, and the other tools).

  7. 11:25 am, March 29, 2011digital  / Reply

    Thanks for your comment, I’ll give the new Burp a try. I had no idea about the recursive grep option so thanks for that too.

    The nice thing about the extension was that it handled anti-CSRF tokens for all the tools transparently instead of having something specific for the intruder. Not that you can’t do any job just with the intruder but it’s just easier to use.

    I dropped an email to portswigger the day after I wrote this post but never got a response back, we’ll never know if he reused my code but I want to think that at least it helped :-)

Leave a Reply

Allowed Tags - You may use these HTML tags and attributes in your comment.

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Pingbacks (0)

› No pingbacks yet.