
# 常用注释
#: 注释#至行尾--: 注释--至行尾(2个-跟上空格或一个其他字符)/**/: 注释/*至*/之间的字符
# 寻找及确认SQL注入
'和"

and和or

# MySQL基本函数
@@version: 数据库版本@@basedir: 数据库路径mid(str, pos, len)和substring(str, pos, len): 对str从pos位置开始截取len个字符concat(str1, str2): 连接两个字符串database(): 当前数据库名length(str): 字符串长度user(): 当前用户名sleep(second): 睡眠second秒group_concat(): 将一列值连接成字符串limit offset, count: 显示从offset开始的count个结果
# 基于注入点值的属性
字符型需要闭合引号,数字型不需要
# 基于注入点的位置
注入点除了GET请求的参数及POST请求的body之外,也可能存在于Cookie或Headers中
# 基于注入的程度和顺序
- 一阶注入:注入语句直接对Web产生了影响
- 二阶注入:注入语句无法直接对Web产生影响,需要通过其他辅助间接产生危害
# 二阶注入示例
添加一个admin'#用户,登录该用户后修改密码,实际上能够修改admin的密码
修改该用户密码时的SQL语句如下
UPDATE users SET passwd="new_password" WHERE username='admin'#' AND password='old_password'
实际上#后的字符都被注释了,相当于执行
UPDATE users SET passwd="new_password" WHERE username='admin'
# 基于从服务器返回的响应
如果Web应用存在SQL注入,那么输入的payload总会导致响应上与正常的有所区别,可能体现在内容、长度、响应时间等方面
# 有回显
# 联合查询
UNION关键字可以合并多条SELECT语句的查询结果,需要满足以下两个条件
- 查询语句的返回列数必须相同
- 查询语句返回的每列的数据类型必须相同

# 报错注入
页面会返回报错信息,可以将需要查询的结果放在报错信息里回显出来

# XPath报错注入
涉及函数:
updatexml(XML_document, XPath_string, new_value): 更新xmlextractvalue(XML_document, XPath_string): 查询xml
XML_document是xml文档对象名,XPath_string是XPath路径,new_value是需要替换的字符串
注入语句:
update(1, concat(0x7e, (select 查询语句), 0x7e), 1)extractvalue(1, concat(0x7e, (select 查询语句), 0x7e))
# floor+group by报错注入
SELECT count(*), (concat(floor(rand(0)*2), '@', (SELECT version())))x FROM users GROUP BY x
floor(x)返回小于等于x的最大整数
group by语句会遍历某一列的值(group by的group_key),将结果保存在临时表中:
- 当读取到某行的值不在临时表中,会插入一条数据
- 当读取到某行的值在临时表中,会更新临时表中的对应数据
group by floor(rand(0)*2)中,由于group_key是随机数,group by在检测临时表是否存在某个值和将值插入临时表的时候会分别执行group_key,因此有可能临时表中存在1,group by检测时计算为0,而插入时计算为1的情况,最终导致插入主键重复的行而报错
# exp()溢出报错注入
MySQL > 5.5.5中,大于709的值传给exp()函数会引起溢出错误


# 堆叠注入
利用;拼接多条sql语句

# 无回显
# 布尔盲注
页面的内容会改变,但不包含有用信息
涉及到的函数:
length(): 字符串长度mid(),substring(): 取子字符串left(),right(): 取字符串的左/右n个字符ord(),ascii(): 取字符ASCII值
# 延时盲注
不关注页面的返回内容,而关注页面的响应时间差
涉及到的函数:
sleep(): 睡眠指定秒数benchmark(count, expr): 执行exprcount次if(expr1, expr2, expr3): 相当于三元运算符,expr1为真返回expr2,为假返回expr3WHEN condition THEN result1 ELSE result2: 批量的三元运算符,如SELECT case WHEN age=19 THEN 'yes' ELSE 'no' FROM usersA regexp() B: 正则表达式B是否可以匹配A

# 特殊业务场景
# INSERT/UPDATE/DELETE注入
注册、修改、删除信息时输入单引号返回异常信息,可能可以被利用




# LIKE注入
%闭合
# ORDER BY注入
# 基于IF语句(数字型)
在知道列名password的情况下,使用if(expr, id, password)

expr为True按照id排序,为False按照password排序
不知道列名的情况下,使用类似if(expr, 1, (SELECT id FROM information_schema.tables))
expr为True时返回正常页面,为False时会报错
# 基于rand()盲注(数字型)
order by rand(),排序结果可能不相同
# HTTP参数污染
给同一个参数赋多个值,可能导致Web应用以意外的方式去解释这个参数
不同的程序组件对这类问题的处理方法也各不相同
# SQL注入的读写
mysql.user表中包含了数据库的用户信息,其中file_priv表示了用户是否可以读写外部文件
此外,全局变量secure_file_priv也对文件读写进行了限制:
- 值为
null表示不允许导入导出 - 值为
/tmp表示只能在/tmp下进行导入导出 - 没有具体值则表示导入导出不受限制
通过load_file(path)函数读取文件,path是绝对路径
