sql注入

原理:

SQL注入就是把SQL命令插入到Web表单然后提交到所在页面请求(查询字符串),从而达到欺骗服务器执行恶意的SQL命令。

防御:

黑名单,白名单(preg_match),转义(magic_quotes_gpc)(addslashes),

预编译:使用预编译相当于是将数据于代码分离的方式,把传入的参数绑定为一个变量,用?表示,攻击者无法改变SQL的结构。预编译则是将传入的 admin’ or 1=1# 当做纯字符串的形式作为username执行,避免了上面说到的SQL语句中的拼接闭合查询语句等过程,可以理解为字符串与sql语句的关系区分开,username此时作为字符串不会被当做之前的SQL语句被带入数据库执行,避免了类似sql语句拼接、闭合等非法操作

预编译在服务端进行

缺点:相当于一个固定的模板,当一些值不同了就会很影响效率

sql读写文件

读:load_file(“路径”)

写:into outfile :将查询的数据写入文件中

UDF

用户自定义函数

步骤:

1.查看mysql有写入文件的权限即secure_file_priv()函数的值

2.image-20220808111125926

3.利用sqlmap中现成的udf文件,用clock.py进行解码得到dll(windows),so(linux)

4.用load_file写入

5.创建自定义函数sys_eval就可以命令执行了

过滤绕过

空格

两个空格代替一个空格,用Tab代替,%a0 %20 %09 %0a %0b %a0 %00 /**/

用括号包裹,括号两端可以没有空格

引号绕过

使用16进制,将查询的字符串变为16进制

逗号绕过

join语句绕过

1
2
union select 1,2     #等价于
union select * from (select 1)a join (select 2)b

from for (substr,mid)

1
2
select substr(database() from 1 for 1);
select mid(database() from 1 for 1);

即在database()中从第1位截取1长的字符

offset(limit)

1
2
3
select * from news limit 0,1
# 等价于下面这条SQL语句
select * from news limit 1 offset 0

大于小于等于符号

使用greatest()、least():(前者返回最大值,后者返回最小值)

strcmp(str1,str2) 当str1=str2,0,当str1>str2,1,小于-1

between and 选取介于两个值之间的数据范围

or and xor not

and=&& or=|| xor=| not=!

注释符被过滤

用**’1**闭合后面的单引号

=

like代替或者使用<>等价于!=,再加一个!表示等于

union select where等

使用注释符插入,大小写绕过,内联注释绕过,双写,编码绕过

宽字节注入

当特殊字符前面会被加上转义字符,而数据库在使用宽字节GBK编码时会认为两个字符为一个汉字,所以在构造时将特殊字符前加一个ascii码大于128的字符,就可以将其与转义字符组合为一个汉字,从而达到注入的目的

盲注

时间盲注:笛卡尔积,sleep(延时) benckmark,md5,hex(重复执行加密达到延时的效果) get_lock加锁

被过滤了acsii:使用ord()代替

报错注入

updatexml

将第二个参数的值传递为不符合格式的参数,mysql就会报错

floor() 报错注入(主键冲突)

FLOOR(x) 函数返回小于 x 的最大整数值 比如floor(1.2),返回值为1

COUNT(*) 函数返回在给定的选择中被选的行数。

MySQL RAND()函数调用可以在0和1之间产生一个随机数。

所以floor(rand()*2)会随机产生01的组合,但是 floor(rand(0)*2)使用了固定的随机数种子则是固定的011011的组合

group by进行分组排序相同名字合并

MySQL8的注入

TABLE:列出表中全部内容

VALUES:列出一行的值

需要注意的地方:

当前判断的所在列的后一列用字符表示,不能用数字,否则最后一个字符会判断不出

最好用<=而不用<

sqlmap–os–shell

实际上是往服务器上写入两个php文件,第一个是利用mysql的into outfile写入一个文件上传的页面,然后第二个php则是通过这个上传页面去post一个可以让我们执行系统命令的后门

mysql密码存在哪

存在user表的authentication_string中

储存方式:先sha1,再unhex,再sha1

mysql反引号

区分保留字