Thursday, 24 March 2011

Debunking the FUD: PostgreSQL for Microsoft Windows Payload Execution

If you follow Twitter for keywords like "postgres" or "postgresql", you may well have seen a number of tweets over the last day or so regarding a so-called "Payload Execution" exploit in PostgreSQL. This supposed attack was apparently first described in this paper, and has hit Twitter after code to demonstrate the issue was added to Metasploit.

The "attack" works like this:
  1. A user uploads a payload as a large object to the database. This can be done using the client side lo_create() and lo_import() functions.
  2. The user then uses the server-side lo_export() function to export the payload to the server's filesystem.
  3. The user then executes the payload, by creating an SQL level function to wrap the C function in the payload, eg:
    CREATE FUNCTION do_bad_stuff() RETURNS int4 AS '$libdir/bad_stuff.dll' LANGUAGE C;
  4. The user then executes the payload:
    SELECT do_bad_stuff();
Here's the problem with the "exploit":

You need to be a superuser for it to work.

That's right - steps 2 and 3 above both require that you are a superuser - in other words, you already have complete, unfettered access to the database server.

But wait - that doesn't get you very far into the OS either! One oft-criticized feature of PostgreSQL (for users that unwisely like to do all their work as root) is that it refuses to run under an account with superuser privileges - in fact on Windows, we irrevocably remove unwanted privileges from our security token at startup. The reason for this, is to ensure that once our L337 H4X0r has uploaded his payload (using his existing superuser privileges), he cannot escalate those privileges to the operating system's superuser accounts and compromise other parts of the system.

As a side note - as superuser in most installations there are far easier ways of achieving the results above that avoid the need to know the architecture of the system or to write code in C - for example, you can simply create a function using one of the untrusted procedural languages, like pl/perlu. 

So the bottom line is, this is not an exploit - it requires that you are already a database superuser with all the power that entails, and doesn't gain you anything you didn't already have the ability to do, or give you a way to gain OS level privileges beyond those already held by the low-privilege user account the server runs under.