CVE-2020-9273 利用的学习方法
Phrack 第 72 期的一篇译文:dukpt 把 ProFTPd 的 CVE-2020-9273 从一个释放后重用做成完整接管,绕过 NX 与 ASLR,靠内存布局控制和信号处理器把堡垒从内部打开。译文保留了原文的教学笔记体,看重的是方法,不是结果。

Phrack 第 72 期 · 第 8 篇
这是一份精彩绝伦的“黑客教学笔记”,它详细拆解了一次极其复杂和巧妙的网络攻击。作者 “dukpt” 像一位大师级的钟表匠,带领我们一步步地“组装”起一个精密的攻击机器。让我们一起深入这个由代码、内存和逻辑漏洞构成的迷宫。
混乱中的艺术:拆解一次让服务器“自我毁灭”的大师级黑客攻击
想象一下,你是一名黑客,你的目标是一座固若金汤的数字堡垒——一台运行着ProFTPd软件的服务器。这座堡垒有两道坚不可摧的防线:
坚固的墙壁 (NX):你无法在墙上(内存的数据区)写上“炸毁这里”然后引爆,所有数据区都禁止执行代码。
移动的迷宫 (ASLR):堡垒内部的地图每天都在随机变化。就算你知道“军火库”(关键代码)的存在,你也不知道它今天到底在哪个房间。
硬闯是不可能了。但你,像所有顶尖的黑客一样,不靠蛮力,靠智慧。你发现了一个隐藏在堡垒设计图纸深处的、极其微小的逻辑缺陷。这个缺陷,就是你打开一切的钥匙。
这篇由黑客“dukpt”撰写的《利用ProFTPd中CVE-2020-9273漏洞的学习方法》,正是这样一份详细的“劫案”复盘报告。它记录了作者如何在一个被他搁置了近四年的项目上,最终完成了一次堪称艺术品的攻击。
一、 混乱的根源:“用后即焚”却没烧干净的“房间”
这次攻击的核心,是一种叫做“用后释放”(Use-After-Free, UAF)的漏洞。这听起来很专业,但用一个“酒店房间”的比喻就很好理解:
程序向系统“预订”一个房间(申请内存)来处理一项任务,比如存放临时数据。
任务完成后,程序告诉系统“我用完了,可以退房了”(释放内存)。
漏洞就在这里:系统虽然把这个房间标记为“空房”,但程序自己手里还偷偷留着一把“旧钥匙”。
过了一会儿,你(攻击者)也来预订房间,系统恰好就把这个刚刚被标记为“空房”的房间分给了你。你带着自己的“行李”(恶意代码)住了进去。
最关键的一步:那个还拿着“旧钥匙”的程序部分,此刻突然想回来办点事,它用旧钥匙打开了房门,把你——新的住客——当成了之前的老主顾,并开始按照你“行李”里的指示去办事。
至此,程序就被你劫持了。
作者发现,ProFTPd服务器里就存在这样一个“健忘的酒店经理”。通过一个极其刁钻的操作,就能触发这个漏洞。
二、 “声东击西”:如何制造完美的混乱?
要利用这个漏洞,就必须先制造一场完美的混乱,让服务器的内存管理陷入“短路”。作者设计的步骤,就像一部高智商犯罪电影:
第一步:建立两条“战线”。攻击者首先作为普通用户登录FTP服务器,这是“主战线”(控制连接)。然后,他命令服务器准备接收一个文件,这会打开第二条“辅战线”(数据连接),专门用来传输文件内容。
第二步:主战线“佯攻”。在辅战线已经打开、等待接收文件数据的同时,攻击者在主战线上发送几条无关紧要的假指令。
第三步:突然“撤退”! 这是最关键的一步。攻击者突然切断了“主战线”的连接。服务器会认为“主顾”已经离开,于是开始执行“退房清理”程序,释放主战线占用的所有内存(酒店房间)。
第四步:辅战线“总攻”。就在服务器刚刚完成清理,脑子还一团乱麻的时候,攻击者立刻通过“辅战线”,将精心准备的恶意数据(新住客的“行李”)发送过去。
由于服务器内部处理流程的混乱,它会把这批新数据,恰好塞进那个刚刚被释放掉的、用来处理指令和响应的“房间”里。UAF漏洞,成功触发!攻击者成功地将自己的数据,伪装成了服务器的内部指令结构。
三、 连环计:从一个微小的控制点到完全接管
仅仅把“行李”放进房间还不够,你需要精确地告诉程序去执行你想要的指令。这需要一步步地扩大战果,整个过程就像一架精密的鲁比·戈德堡机械。
第一环:获得“地图”。堡垒内部是随机迷宫(ASLR),没有地图寸步难行。作者利用了服务器的另一个功能
mod_copy,这个功能像个“内部快递服务”。他欺骗这个快递服务,把一份服务器自己的“内存地图”(/proc/self/maps文件)打包,寄到了一个他有权访问的文件夹里。然后,他再像普通用户一样把这份“地图”下载下来。现在,堡垒的内部结构一览无余。第二环:写入一个“假指针”。通过UAF漏洞,攻击者已经可以控制一小块内存。他利用这个微小的控制点,进行了一次“指针转移”,让程序在后续操作中,把一个关键结构的地址,写入到了另一个由他控制的位置。这相当于,他把通往“总控制室”的钥匙,藏在了自己指定的一个花盆底下。
第三环:最终的“致命一击”——主动求死。这是整个攻击中最反直觉、也最精彩的部分。在万事俱备之后,攻击者并没有直接尝试执行代码,而是故意让程序崩溃(触发SIGSEGV信号)!
为什么? 因为直接执行的时机和环境都很差,很容易失败。但程序崩溃后,会进入一个“紧急关停预案”(信号处理程序)。这个预案中有一项任务,就是执行一系列“清理工作”(
run_cleanups),比如关闭文件、释放资源等。而攻击者通过前面一系列的铺垫,已经神不知鬼不觉地篡改了这份“清理工作”的清单。他把清单上的第一项任务,从“打扫卫生”,换成了“执行黑客留下的代码”。
于是,服务器在“弥留之际”,为了体面地“死去”,忠实地执行了这份被篡改的遗言。它以为自己在清理现场,实际上却是在为攻击者打开通往系统最高权限的大门。
四、 所以呢?这堂“大师课”告诉了我们什么?
这篇论文与其说是一份漏洞报告,不如说是一次关于“黑客思维”的深刻教学。
首先,它揭示了现代漏洞利用的真实面目。它不是一招制敌的魔法,而是一场基于对系统深刻理解的、严谨的“系统工程”。每一步都环环相扣,需要精确的计算和对时机的完美把握。
其次,它展现了“混乱”本身就是一种可利用的资源。攻击者并没有创造新的东西,他只是利用了程序在处理异常(连接突然中断)时产生的短暂混乱,将这种混乱变成了自己攻击链条中的一环。
最后,它强调了即使有重重防御,逻辑上的微小瑕疵也可能是致命的。ASLR和NX这样的现代防御机制非常强大,但它们保护的是执行的“地点”和“权限”,却无法阻止程序因自身的逻辑缺陷而“自愿”地走向被劫持的道路。
“dukpt”的这篇文章,就像一部精彩的侦探小说,让我们看到了一个顶尖高手是如何抽丝剥茧,将一个看似难以利用的微小内存错误,最终放大成一场颠覆整个系统的完美风暴。这不仅是技术的展示,更是思维的胜利。
原载于微信公众号「网安志异」,2025-10-23 · 原文
留言