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.
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 | union select 1,2 #等价于 |
from for (substr,mid)
1 | select substr(database() from 1 for 1); |
即在database()中从第1位截取1长的字符
offset(limit)
1 | select * from news limit 0,1 |
大于小于等于符号
使用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反引号
区分保留字