From MySQL documentation :

"The SELECT ... INTO OUTFILE 'file_name' form of SELECT writes the selected rows to a file. The file is created on the server host, so you must have the FILE privilege to use this syntax. file_name cannot be an existing file, which among other things prevents files such as /etc/passwd and database tables from being destroyed. As of MySQL 5.0.19, the character_set_filesystem system variable controls the interpretation of the filename."

The INTO OUTFILE operator can be used during sql injection exploiting to write php shell on remote host. Unfortunately (fortunately?) this is only possible in some (very) race conditions :


* mysql user must have the FILE privilegie;

* the operator requires a "quoted" file pathname, so the web application should not escape/filter them;

* httpd and mysql should be installed on the same machine, or (if you can) the file will be written on the dbms machine;

* You need to know the fullpath name of the web root.



Now we suppose that all the above conditions were verified on the test machine, and let's start to explore the operator's characteristics. I'll show a series of characteristics that I noticed while I was playing with it :


* It is possible to control the content of the file to write in this way :
[hide=15]

Code:
{begin of injection} AND 1=0 UNION SELECT 1,1,1,'my code here' INTO OUTFILE '/www/htdocs/shell.php/'/*

A file named "shell.php" will be created, and its content will be the follow :


1 1 1 my code


First of all : I used an "AND 1=0" because in this way I was able to make the first query returns 0 rows (so no data from the original query will be inserted in shell.php). Second : we can notice that in shell.php there are some undesired data (1 1 1). To avoid their presence we can use "null" or ''.



* If INTO OUTFILE is used in a subquery, we will create the file but we will not control its content. That's because if we inject something like :


Code:
AND (SELECT '' INTO OUFILE '/.../shell.php')/*

shell.php will contains the data selected by the injecatable query and not our ''



* If you want display the whole (current)table content you can inject this query :


[code]