Tuesday, April 15, 2008

Worm-like Intranet/Proxy Hacks

Remote file include worms are nothing new. Santy worm, for example, abuses PHP applications that allow user specified locations to be passed to require() and include() functions. When attacker controlled URLs are passed to these functions, the attacker can serve code to the application which will then be executed on the victim server.

Intranet hacking vulnerabilities, like the one RSnake recently found, share some characteristics of these vicious PHP application flaws. Both flaws take user specified resources and fetch them automatically without any validation. This means you can tell the application to go get http://www.cnn.com, or http://localhost/app/web.config, and the application will generate an HTTP request for that resource.

What sets the two issues apart, is that the PHP vulnerability consists of an automated request AND arbitrary code execution - that's why it is so easily wormable. Intranet-hacking type vulnerabilities, in general, only provide an attacker a method to automate and proxy requests (propagation), without any vector for remote code execution. Unless, there is some other vulnerability in the same script...

If in the same URL that has the arbitrary request vulnerability, there is a persistent XSS/SQL injection/command injection vulnerability, you now have a vector to execute malicious code, as well as a method to propagate it.

Below is one theoretical example. But first, lets get some assumptions out of the way :-)

Assumption 1: The application has a pre-auth vulnerability allowing users to specificy URLs which the application will fetch without validation.

Assumption 2: The same code that doesn't validate the user specified URL also doesn't validate other querystring data it is sent.

Assumption 3: All querystring data gets written to a log or database, without being encoded, where it can be viewed in a web browser by an administrator or some privileged user.

Initial attacker generated request:
http://somewebapp/app/fetch?path=[URL]&XSSpayload=<script>alert(document.cookie)</script>

In the above request, [URL] = http://someotherwebapp/app/fetch%3Fpath%3D[URL2]%26XSSpayload%3D<script>alert(document.cookie)</script>

[URL] contains the first automated request that will be generated, [URL2] contains the next one, and so on . . .

Another differentiator is that while the malicious PHP worm code can find targets on its own using Google searches, with Intranet hacking it is up to the attacker to identify targets and build his exploit URL. In the end, he'll have a very long URL that contains the target and payload for every server you wish to attack. Not pretty, but it should get the job done.

Something else to be aware of is how the execution path of the victim code. When the code makes the remote request, it will probably hang until it gets a response, or until it times out (depending on how many requests are made and how long it takes for them to be fulfilled).

If, in our above example, the persistent XSS is written to the database before the request is made, your attack should still work. If it is written to the database after the HTTP request, you could be out of luck if the request times out and the code takes an alternate execution path.

Again, this is all theory. Next step would be a PoC . . . or maybe actually find something like this in the wild.

No comments: