Entries tagged with “Fuzzor”.


I was playing a bit with FuzzOr and trying out different Oracle built-in schemas on 11g when I stumbled across something interesting in the parameters for MDSYS.SDO_JOIN. This caused FuzzOr to fail in fuzzing the function so I took a closer look.

SYS> select argument_name, type_owner, type_name, position, sequence from all_arguments where object_name = ‘SDO_JOIN’;

ARGUMENT_NAME         TYPE_OWNER     TYPE_NAME         POSITION SEQUENCE
--------------------- -------------- ----------------- -------- --------
TABLE2_PARTITION                                              8       10
TABLE1_PARTITION                                              7        9
PRESERVE_JOIN_ORDER                                           6        8
PARAMS                                                        5        7
COLUMN_NAME2                                                  4        6
TABLE_NAME2                                                   3        5
COLUMN_NAME1                                                  2        4
TABLE_NAME1                                                   1        3
                      MDSYS          SDO_ROWIDPAIR            1        2
                      MDSYS          SDO_ROWIDSET             0        1
10 rows selected.

So, do you notice anything weird here? SDO_ROWIDPAIR is listed as a parameter in the same position as TABLE_NAME1 but has no parameter name. Interesting. Initially, I thought that there might be something wrong with the view all_arguments but querying directly the argument$ table produced the same results.

Describing the function did not mention SDO_ROWIDPAIR at all:

SYS> desc MDSYS.SDO_JOIN
FUNCTION MDSYS.SDO_JOIN RETURNS SDO_ROWIDSET
 Argument Name                  Type           In/Out  Default?
 ------------------------------ -------------- ------- --------
 TABLE_NAME1                    VARCHAR2       IN
 COLUMN_NAME1                   VARCHAR2       IN
 TABLE_NAME2                    VARCHAR2       IN
 COLUMN_NAME2                   VARCHAR2       IN
 PARAMS                         VARCHAR2       IN      DEFAULT
 PRESERVE_JOIN_ORDER            NUMBER         IN      DEFAULT
 TABLE1_PARTITION               VARCHAR2       IN      DEFAULT
 TABLE2_PARTITION               VARCHAR2       IN      DEFAULT

The source code is wrapped but the header is:

FUNCTION SDO_Join (TABLE_NAME1 VARCHAR2, COLUMN_NAME1 VARCHAR2,
TABLE_NAME2 VARCHAR2, COLUMN_NAME2 VARCHAR2,
PARAMS VARCHAR2 DEFAULT NULL,
PRESERVE_JOIN_ORDER NUMBER DEFAULT 0,
TABLE1_PARTITION VARCHAR2 DEFAULT NULL,
TABLE2_PARTITION VARCHAR2 DEFAULT NULL)
RETURN MDSYS.SDO_ROWIDSET
AUTHID CURRENT_USER
PIPELINED IS

As you see, no mention of SDO_ROWIDPAIR which is in-fact mentioned later in the function as a declared local variable TAB_REC.

Anyway, this function is declared as AUTHID CURRENT_USER so even if can be injected (which I suspect that it can) it will not benefit the attacker.

Still, it’s an interesting case where the arguments table does not reflect the actual code and I suspect that there is a bug in populating this table.

Have you encountered similar cases?

Happy New Year everyone!

As promised, in this blog post I will deal with the PL/SQL fuzzer I’ve created in my spare time and during flights. The goal for creating it was to provide an easy tool for the DBA to test PL/SQL code inside the database. This tested code can be internally developed or by a 3rd party. Before describing the architecture of the fuzzer and showing examples, I would like to make the following clarifications / warnings:

  • Fuzzing on production is a BIG no-no.  Never run the fuzzer on any database you care about. Always use test copies because running the fuzzer may crash / corrupt the database.
  • The fuzzer cannot guaranty that the code is not vulnerable, it can only try and find existing vulnerabilities. Running the fuzzer on a procedure and receiving a clean result does not mean that this procedure is free of vulnerabilities because the fuzzor does not analyze the code and does not visit all the code paths.
  • The fuzzer is in no way shape or form a finished product. It will blow in your face. It will fail when running your code. It contains multiple bugs. USE RESPONSIBLY!!!

Now that the warnings part is over, let’s talk about the design.
I chose PL/SQL for the following reasons:

  • Easy to run SQL statements
  • Built-in the database
  • Cross platform
  • Good enough for the task
  • DBAs already speak it fluently
  • Can be easily scheduled as a DB job from inside the database

The design is fairly simple and is based on the following requirements:

  • Must use database tables to track executions across invocations and to change various fuzzing parameters
  • Must try and find interesting (dynamic) code using discovery
  • Must easily generate reports on the fuzzing results

(more…)