首页 > 代码库 > 无需密码攻击 Microsoft SQL Server

无需密码攻击 Microsoft SQL Server

最近的一次渗透测试里,在我们捕获的一些数据包中发现了一些未经加密的 Microsoft SQL Server(MSSQL) 流量。起初,我们认为这样就可以直接嗅探到认证凭证,然而,MSSQL 加密了认证的流量,这就意味着我们需要先解密才能获取到认证凭证。如果安装的是一个自签名证书,就很容易进行破解。

不幸的是,破解 MSSQL 加密不在授权范围之内,我们不得不先放下好奇心完成对客户的渗透测试。不过,因为心里总想着一件事以至于无法继续正常进行工作,我们可以在没有用户凭证的情况下攻击 SQL Server 吗?带着疑问我们开始进行实验。

最终,我们发现使用中间人攻击可以通过利用一些数据包达到无需用户凭证直接控制 Microsoft SQL Server。

中间人攻击

回到实验室,我们开始进行了更多的研究。实验环境为,在 Windows Server 2012 R2 上运行 MSSQL Server 2014,工作站为在 Windows 10 系统上运行 MSSQL Management Studio 2014,攻击机为新版的 Kali 2.0 Linux。所有的系统都处在同一个子网内,以模拟进行内网攻击。这些设置与我的客户几乎一致。

这种攻击被称为中间人(MITM)攻击。典型的攻击方式就是进行一些重定向,例如,ARP缓存投毒攻击,迫使两个系统之间的通信被重定向到攻击者的机器上,这就允许攻击者不仅可以看到被攻击者之间的通信,也可以对通信流量进行篡改。而这正是我们下面想要干的事情。

理解数据

我们要做的第一件事情就是查看 MSSQL 查询操作产生的流量。为了使实验更加有趣,我们使用 “SA” 进行登录。SA 账户是 SQL Server 的系统管理员账户,可以进行任何操作。如果我们试验成功,那我们可以使用 SA 账户的权限进行很多有趣的事情。

技术分享

登录后,我们在服务器上开启 Wireshark 2.0 进行抓包。我们配置 Wireshark 显示过滤 “tds.query”,这样就可以过滤除 TDS 查询数据包以外的数据包(顺便一提,我们注意到在低版本的 Wireshark 上面没有 “tds.query” 这个过滤对象)。

随着开始进行抓包,我们切换回了工作站然后在特别准备的数据库中执行查询语句,这个数据库名为 testdb 包含一个名为 Products 的表,Products 表中有两列分别名为 ProductID 和 ProductName。表内没有任何实际数据只用作测试,所以不用担心。查询操作的目的是显示表中的所有数据。

技术分享

查询执行成功后返回了一个空表给我,你可以在下面的截图中看到。回到 Wireshark,我们停止了抓包并开始着手分析数据包,我们发现了一个 TDS 查询数据包,点开数据包后我们发现它包含所有的信息,这表明 MSSQL Server 2014 Express 默认没有对数据进行加密处理,也就是说数据可以很容易被获取到。

技术分享

仔细查看下方解码后的数据,我们可以很容易的识别出查询操作,里面甚至包含回车和换行符。有趣的事是,每个字符之间都有一个 Unicode 的空字节(0×00),查看十六进制视图时这点尤为明显,这意味着 Wireshark 周期性的显示这些字节,它们实际上不是真为空的,所以我们不能直接查找一个简单的字符串,如”select”。我们之后对数据进行搜索需要把这些 Unicode 空字节也加入考虑之中。

有趣的 Ettercap Filters

我们已经了解了数据的样子,下面就该对这些数据进行操作了,这里我们决定使用 Ettercap。Ettercap 是一个专门用来进行 MITM 攻击的工具,其内置了一个名为 Ettercap filters 的功能,这个功能允许我们搜索特点的数据包随后处理数据。我们可以在 Ettercap 里写一个过滤,这样 Ettercap 在每次匹配到的时候会自动帮我们替换数据。这个功能稍有限制,但足以用于我们的 POC 了。

过滤代码里我们打算使用的主要函数为搜索和替换函数,搜索函数将在数据包内搜索指定的数据,替换函数其实就是先搜索指定数据然后替换成其他数据,这也是整个项目的关键点。

由于 TDS 查询数据中包含一些空字节和不可打印的字节,这意味着我们不能只简单搜索字符串并使用另一个字符串替换它。我们需要一种方法搜索非空的不可打印字符,但是我们又无法通过键盘输入,因此需要其他的方法。幸运的是,Ettercap 过滤支持十六进制编码,例如,搜索字母 ‘s’可以使用”\x73″,搜索空字节可以使用”\x00″。Kali 里有一个名为 hexdump 的程序可以将字符串转换成十六进制,我们使用这个程序将字符串”select”转换成十六进制。

技术分享

在有了我们需要的数据后,写下了下面这个名为 “mssql.filter” 的第一个过滤代码:

技术分享

第一行代码确过滤只运行在端口号为 1433 的 TCP 流量上,如果匹配成功,过滤器会输出调试信息到控制台,让我们知道它发现了 SQL 流量。下一个 “if” 语句则是用于搜索十六进制数据的,这个十六进制翻译过来是 “select”。如果过滤器定位到这个字符串,会将调试信息输出到控制台。

最后,会替换执行命令为另一个字符串 “ssssss”。这只是一个测试,看这个脚本是否可以正常工作,但需要注意的是,当你替换 TCP 中数据的时候必须替换相同数量的字节数,如果数据包大小发送变化,则 TCP 连接会被断开。

过滤代码写完后记得要进行编译,使用 etterfilter 命令可以很容易完成编译。

技术分享

没有报错,所以我们的过滤器已经准备好进行测试了。我们首先启动 Ettercap 图形化界面并对 MSSQL 服务器和客户机发起 ARP 欺骗攻击,在开启 Wireshark 进行验证看流量是否在两个目标间发送。然后,在 Ettercap 菜单 “Filters -> Load a filter”里选择我们的过滤器,这时我们就在控制台中获得了一个 “Content filters loaded” 消息。几乎在开启的一瞬间我们就收到了 “SQL Traffic Discovered” 的消息,一切看起来跟我们预想的一样。

下一步就是切换回工作站并尝试执行查询操作。如果一切正常,则 “select” 字符串会被替换成 “ssssss” 并造成查询失败。在执行查询操作后,这次没有在收到空表的结果,相反收到了一个报错。

技术分享

“Incorrect syntax near ‘ssssss’.”很好,过滤器如预期一样的正常工作了,替换 “select” 字符串为 “ssssss”。而 MSSQL 服务器不知道如果处理就返回了一个报错。这是我们通向成功的第一步,下一步就是替换整个查询字符串,以更好的进行攻击。

新建账户

我们决定在服务器上增加一个账户,对攻击者来说这是很常见的操作,特别是在目标的登录账户为 “SA” 时,为了新建一个账户我们需要在 MSSQL 服务器上执行如下查询:

CREATE LOGIN anitian WITH PASSWORD=‘YouGotHacked1#‘; 

这样会在 MSSQL 服务器上新建一个名为 “anitian” 密码为 “YouGotHacked1#” 的账户。在将一切数据转换为十六进制后,我们更新了 mssql.filter 过滤器以包含新的数据。

技术分享

这个过滤会查找字符串 “select ProductID, ProductName from Products where ProductID=1;” 并替换字符串为 “CREATE LOGIN anitian with PASSWORD=’YouGotHacked1#“。前面特意提醒过,必须要替换同等数量的 TCP 数据,那么现在新的查询数据比源数据短该怎么办?只需要在查询语句的末尾添加一些空格补齐即可。然后,像之前一样重新编译过滤器并加载到 Ettercap,我们就可以从工作站提交查询了。

技术分享

这里注意下我们使用 Ettercap 过滤器前后响应的区别?之前会返回一个空表,而现在服务器则返回一个 “Command(s) completed successfully”的消息。如果数据库管理员看到这个,他们可能将其归为一些奇怪的错误而直接忽略掉。但不幸的是,一切都晚了,我们已经在数据库系统中增加了自己的账户。好了,真正的 Hack 现在才即将开始。

在 Windows 10 工作站上首先将 SA 账户登出,然后尝试使用我们刚刚创建的 anitian 账户进行登录。

技术分享

技术分享

登录成功!我们现在登录了自己的账户,不过不幸的是当前的账户没有太多的权限,我们没法做太多的事情。但这都不是事,下一步将准备使用 Ettercap 过滤器进行下一次攻击来提升当前账户的权限。

在这里我们可以很容易的做到这些,但是手动进行十六进制转换并增加空字节非常的枯燥乏味,谁愿意这样做啊?这是一个很好的 POC 吗?

没办法,我们还不想那么快就放弃。那么,为什么我们不可以使用一个自动化脚本来完成所有的这些工作呢。

自动化攻击

SQLinject.sh 脚本可以在这里下载到:http://pastebin.com/Nge9rx7g

这个脚本会全自动的将 SQL 查询转换为十六进制并进行 ARP 攻击和加载 Ettercap 过滤器。这就使得整个攻击过程变的非常简单。

使用脚本需要以下四个信息:

1.MSSQL 服务器的 IP 地址

2.MSSQL 客户端的 IP 地址

3.想要替换的原始查询语句

4.想要注入的新的查询语句

通常,我们已经知道了一切除想要注入的 SQL 查询语句,我们想要给予 anitian sysadmin 权限,在快速的查看 SQL 命令后,我们得出如下的查询语句:

ALTER SERVER ROLE sysadmin ADD MEMBER anitian; 

这样我们的新账户 anitian 就获得了 sysadmin 权限,进而获得到任何我们想干事情的权限。现在,我们知道了所有四个信息,可以像如下这样执行脚本:

./SQLInject.sh –o “select ProductID, ProductName from Products where ProductID=1;” –i “ALTER SERVER ROLE sysadmin ADD MEMBER anitian;” –s 192.168.1.114 –c 192.168.1.100 –f mssql.filter 

使用这个脚本,我们不必在担心那些烦人的进制转换或空字节了,脚本会帮我们处理这些,先进行进制转换然后将输出一个 Ettercap 过滤器到 mssql.filter(文件名基于 -f 参数)。随后,会运行 etterfilter 编译过滤器为 mssql.filter.ef。最后,脚本执行命令行界面的 Ettercap 对服务器和客户机进行 ARP 欺骗攻击。这个脚本甚至会比较新旧查询的长度,并会提醒新的查询长度是否过长。如果新的查询长度较短,则会自行填充一些空格使其长度保持一致。所有的这一切都只需要一行命令。

执行完脚本后,我们切换到工作站。在执行了相同的查询语句后,我们再次接受到了 “Command(s) completed successfully” 的消息。这对我们攻击来说是件好事,我们刚注销了 SA 账户并使用 anitian 账户重新登录进来。

技术分享

现在,通过截图你可以发现 anitian 账户已经变为了 sysadmin 权限用户。有了这个权限的用户,我们就可以访问任何想要访问的系统了,并提供给我们一个很好的跳板来攻击其他系统。当然这里假设数据库里没有包含我们想要的如银行卡或者个人身份证等信息。

不过这个脚本最大的问题在于,你需要事先知道用户即将执行的 SQL 语句。幸运的是,SQL 服务器经常会有批处理或者定时任务执行查询。查看一段时间的 Wireshark 抓包结果我们总可以抓到一个目标语句。当然,我们也可以进行一个更彻底的攻击,直接进行中间人攻击代理所有的网络流量,查找 TDS 查询数据包并自动替换数据而无需事先知道原始的查询语句,但这就是另一个项目了。

抵御 SQL 中间人攻击

类似的这种中间人攻击带来的威胁是毁灭性的,如你所见,攻击者可以完全获取到进入目标系统的权限,而其他一些专一的黑客可能不会遵循我们这样的操作。此外,他们也可以日复一日的自动化运行脚本,只为等待合适攻击目标的出现。

最简答你的抵御手段就是对通信数据进行加密。然而,仅仅只是启用加密还是不够的。还要确保使用一个有效可信的数字证书。攻击者可以很轻易的伪造一个自签名的证书。

另一个抵御的方法是确保远程用户不允许使用具有特权的账户登录,例如 SA 账户。所有的数据库查询操作,特别是来自程序的查询操作,都应当只使用一个账户以最少的访问量来完成操作。以确保攻击者即使能够建立连接,他们也不能使用伪造的账户进行登录,像本例中这样。

最后,确保你的基础设施定期安装补丁。此外,将数据库系统同企业内网进行隔离,这是最好的做法,这就使得中间人类型的攻击很难在奏效。

无需密码攻击 Microsoft SQL Server