Q:

Is it possible to test for Postgres BlindSQL injection using pg_sleep() in a WHERE clause?

In mysql, I am familiar with using the following payloads to test for blindsql when the WHERE clause is vulnerable (all payload examples from fuzzdb):

1 or sleep(TIME)#
" or sleep(TIME)#
' or sleep(TIME)#

In postgres, my first instinct was to try the following:

1 or pg_sleep(TIME)--
" or pg_sleep(TIME)--
' or pg_sleep(TIME)--

Unfortunately, the postgres payloads don't work because pg_sleep() returns VOID and hence is disallowed in a boolean expression.
I have tried the following workarounds:

Casting pg_sleep() to some other data type (void -> bool type conversion is disallowed)
I have considered trying to create my own pg_sleep() function, but this doesn't work in the black box environment that I audit in..
ex: CREATE function pg_sleep(int) RETURNS int AS '/lib/libc.so.6', 'sleep' LANGUAGE 'C' STRICT

Any ideas?
I have tried looking in the docs for other functions that may be used in place of pg_sleep() that do not return void, but I have not had any luck.

A:

First of all, try the simple approach. Is this really a situation which only allows a completely blind injection? For SQL injection vulnerability in the WHERE part it is far more common that the application will react differently depending on whether it got at least one row or none at all. And it is likely that the injection can force an empty result set via AND 1=0 or an none empty result set via OR 1=1
If this approach fails because the data is not used for anything visible or you cannot force the empty/non empty set, only then it is time to look for blind injection techniques.
To include a SELECT clause into an WHERE part you can use a sub select or a function like strpos:
strpos(
    (SELECT CASE WHEN 1=1 
            THEN pg_sleep(10)
            ELSE pg_sleep(0) END
    )::text, '1'
) > 0;

There is an interesting paper on Advanced PostgreSQL SQL Injection and Filter Bypass Techniques.

