我的第一个真实环境二进制漏洞复现:CVE-2018-1160利用
0x00 关于本文 其实我是想复现CVE-2022-23121的,但二进制水平还不够,所以决定先踩着 前人的脚步 复现相同产品的另一个漏洞CVE-2018-1160,多学点东西。 在这次复现过程中我得到了 @povcfe 的许多帮助,在此表示感谢。 文中涉及的代码已放在 Github 。 0x01 环境搭建 这篇文章 介绍了如何搭建环境,但我的系统不是Ubuntu18.04,其运行的新版本Glibc会导致漏洞利用更加困难,因此我需要切换回老的Glibc。 搭建一个Ubuntu18.04的虚拟机并且在上面把各种调试工具装好是最朴素的做法,但这样太麻烦,并且要是下次我需要一个Ubuntu16或者别的版本那又得重头再来。因此我的办法是用Docker启一个Ubuntu18.04的容器,并将它的548端口映射到宿主机上,在这个容器中编译Netatalk并运行。由于容器本质上是受到严格限制的进程而不是虚拟机,我可以直接用宿主机上的调试工具attach到容器内部的进程来调试而不需要在容器内安装这些调试工具。 说了这么多,其实启动这个容器就一行命令的事 docker run -p 548:548 -i -t ubuntu:18.04 /bin/bash 后续的东西按着本段开头的那个文章搭就好了,当然pwntools和pwndbg这些搞pwn必备的东西也是要在宿主机上安装的。 0x02 Netatalk是怎么跑起来的&如何调试它 Netatalk的源码的调用关系在 这里 写的有。简单地说,它对于每一个新的连接都用dsi_tcp_open fork出一个子进程并接收参数,并返回到dsi_getsession中处理连接建立和关闭的过程,而与这个连接后续的交互过程都在afp_over_dsi中实现。基于这个特性,我们可以通过在gdb中追踪子进程来调试Netatalk对连接的处理。 我们可以通过gdb一行命令实现这件事。其中pgrep用于找到它的pid,而设置follow-fork-mode child可以让gdb选择跟踪子进程,directory指令可以设定源码的路径,这样我们在调试的时候可以看C代码而不用啃太多汇编。 gdb -q -p `pgrep -n afp` --ex "set