Blind Return Oriented Programming (BROP) Attack - 攻击原理

0x00 写在前面


第一次在WooYun发文章,不知道是否符合众客官口味,望轻拍。

这篇文章翻译至我的这篇博客,主要介绍了一种叫做BROP的攻击,该文章主要介绍原理部分,对该攻击的重现可以参看我的另外一篇博客

BROP攻击基于一篇发表在Oakland 2014的论文Hacking Blind,作者是来自Standford的Andrea Bittau,以下是相关paper和slide的链接:

paper

slide

以及BROP的原网站地址:

Blind Return Oriented Programming (BROP) Website

可以说这篇论文是今年看过的最让我感到兴奋的论文(没有之一),如果要用一个词来形容它的话,那就只有“不能更帅”才能表达我对它的喜爱程度了!

这篇文章假设读者已经了解Return-Oriented Programming (ROP) 的基本概念,所以只是介绍BROP的实现原理,如果还不清楚什么是ROP,请先出门左转,看看Wiki的相关介绍。

BROP的实现真的是让人感到非常“cool”和“smart”,我希望能够通过这篇文章把它讲清楚。

0x01 BROP攻击的目标和前提条件


目标:通过ROP的方法远程攻击某个应用程序,劫持该应用程序的控制流。我们可以不需要知道该应用程序的源代码或者任何二进制代码,该应用程序可以被现有的一些保护机制如NX, ASLR, PIE, 以及stack canaries等保护,应用程序所在的服务器可以是32位系统或者64位系统。

初看这个目标感觉实现起来特别困难。其实这个攻击有两个前提条件的:

  • 必须先存在一个已知的stack overflow的漏洞,而且攻击者知道如何触发这个漏洞;
  • 服务器进程在crash之后会重新复活,并且复活的进程不会被re-rand(意味着虽然有ASLR的保护,但是复活的进程和之前的进程的地址随机化是一样的)。这个需求其实是合理的,因为当前像nginx, MySQL, Apache, OpenSSH, Samba等服务器应用都是符合这种特性的。

0x10 BROP的攻击流程 1 - 远程dump内存


由于我们不知道被攻击程序的内存布局,所以首先要做的事情就是通过某种方法从远程服务器dump出该程序的内存到本地,为了做到这点我们需要调用一个系统调用write,传入一个socket文件描述符,如下所示:

write(int sock, void *buf, int len)

将这条系统调用转换成4条汇编指令,如图所示:

write gadgets

所以从ROP攻击的角度来看,我们只需要找到四个相应的gadget,然后在栈上构造好这4个gadget的内存地址,依次进行顺序调用就可以了。

但是问题是我们现在连内存分布都不知道,该如何在内存中找到这4个gadgets呢?特别是当系统部署了ASLR和stack canaries等保护机制,似乎这件事就更难了。

所以我们先将这个问题放一放,在脑袋里记着这个目标,先来做一些准备工作。

攻破Stack Canaries防护

如果不知道什么是stack canaries可以先看这里,简单来说就是在栈上的return address下面放一个随机生成的数(成为canary),在函数返回时进行检查,如果发现这个canary被修改了(可能是攻击者通过buffer overflow等攻击方法覆盖了),那么就报错。

那么如何攻破这层防护呢?一种方法是brute-force暴力破解,但这个很低效,这里作者提出了一种叫做“stack reading”的方法:

假设这是我们想要overflow的栈的布局:

stack layout

我们可以尝试任意多次来判断出overflow的长度(直到进程由于canary被破坏crash了,在这里即为4096+8=4104个字节),之后我们将这4096个字节填上任意值,然后一个一个字节顺序地进行尝试来还原出真实的canary,比如说,我们将第4097个字节填为x,如果x和原来的canary中的第一个字节是一样的话,那么进程不会crash,否则我们尝试下一个x的可能性,在这里,由于一个字节只有256种可能,所以我们只要最多尝试256次就可以找到canary的某个正确的字节,直到我们得到8个完整的canary字节,该流程如下图所示:

stack reading

我们同样可以用这种方法来得到保存好的frame pointerreturn address

寻找stop gadget

到目前为止,我们已经得到了合适的canary来绕开stack canary的保护, 接下来的目标就是找到之前提到的4个gadgets。

在寻找这些特定的gadgets之前,我们需要先来介绍一种特殊的gadget类型:stop gadget.

一般情况下,如果我们把栈上的return address覆盖成某些我们随意选取的内存地址的话,程序有很大可能性会挂掉(比如,该return address指向了一段代码区域,里面会有一些对空指针的访问造成程序crash,从而使得攻击者的连接(connection)被关闭)。但是,存在另外一种情况,即该return address指向了一块代码区域,当程序的执行流跳到那段区域之后,程序并不会crash,而是进入了无限循环,这时程序仅仅是hang在了那里,攻击者能够一直保持连接状态。于是,我们把这种类型的gadget,成为stop gadget,这种gadget对于寻找其他gadgets取到了至关重要的作用。

寻找可利用的(potentially useful)gadgets

假设现在我们找到了某个可以造成程序block住的stop gadget,比如一个无限循环,或者某个blocking的系统调用(sleep),那么我们该如何找到其他 useful gadgets呢?(这里的“useful”是指有某些功能的gadget,而不是会造成crash的gadget)。

到目前为止我们还是只能对栈进行操作,而且只能通过覆盖return address来进行后续的操作。假设现在我们猜到某个useful gadget,比如pop rdi; ret, 但是由于在执行完这个gadget之后进程还会跳到栈上的下一个地址,如果该地址是一个非法地址,那么进程最后还是会crash,在这个过程中攻击者其实并不知道这个useful gadget被执行过了(因为在攻击者看来最后的效果都是进程crash了),因此攻击者就会认为在这个过程中并没有执行到任何的useful gadget,从而放弃它,这个步骤如下图所示:

useful gadget but crash

但是,如果我们有了stop gadget,那么整个过程将会很不一样. 如果我们在需要尝试的return address之后填上了足够多的stop gadgets,如下图所示:

stop gadgets usage

那么任何会造成进程crash的gadget最后还是会造成进程crash,而那些useful gadget则会进入block状态。尽管如此,还是有一种特殊情况,即那个我们需要尝试的gadget也是一个stop gadget,那么如上所述,它也会被我们标识为useful gadget。不过这并没有关系,因为之后我们还是需要检查该useful gadget是否是我们想要的gadget.

最后一步:远程dump内存

到目前为止,似乎准备工作都做好了,我们已经可以绕过canary防护,并且得到很多不会造成进程crash的“potential useful gadget”了,那么接下来就是该如何找到我们之前所提到的那四个gadgets呢?

find write gadgets

如上图所示,为了找到前两个gadgets:pop %rsi; retpop %rdi; ret,我们只需要找到一种所谓的BROP gadget就可以了,这种gadget很常见,它做的事情就是恢复那些callee saved registers. 而对它进行一个偏移就能够生成pop %rdipop %rsi这两个gadgets.

不幸的是pop %rdx; ret这个gadget并不容易找到,它很少出现在代码里, 所以作者提出一种方法,相比于寻找pop %rdx指令,他认为可以利用strcmp这个函数调用,该函数调用会把字符串的长度赋值给%rdx,从而达到相同的效果。另外strcmpwrite调用都可以在程序的Procedure Linking Table (PLT)里面找到.

所以接下来的任务就是:

  • 找到所谓的BROP Gadget
  • 找到对应的PLT项。
寻找BROP Gadget

事实上BROP gadgets特别特殊,因为它需要顺序地从栈上pop 6个值然后执行ret。所以如果我们利用之前提到的stop gadget的方法就可以很容易找到这种特殊的gadget了,我们只需要在stop gadget之前填上6个会造成crash的地址:

find brop gadget

如果任何useful gadget满足这个条件且不会crash的话,那么它基本上就是BROP gadgets了。

寻找PLT项

PLT是一个跳转表,它的位置一般在可执行程序开始的地方,该机制主要被用来给应用程序调用外部函数(比如libc等),具体的细节可以看相关的Wiki。它有一个非常独特的signature:每一个项都是16个字节对齐,其中第0个字节开始的地址指向改项对应函数的fast path,而第6个字节开始的地址指向了该项对应函数的slow path:

plt structure

另外,大部分的PLT项都不会因为传进来的参数的原因crash,因为它们很多都是系统调用,都会对参数进行检查,如果有错误会返回EFAULT而已,并不会造成进程crash。所以攻击者可以通过下面这个方法找到PLT:如果攻击者发现好多条连续的16个字节对齐的地址都不会造成进程crash,而且这些地址加6得到的地址也不会造成进程crash,那么很有可能这就是某个PLT对应的项了。

那么当我们得到某个PLT项,我们该如何判断它是否是strcmp或者write呢?

对于strcmp来说, 作者提出的方法是对其传入不同的参数组合,通过该方法调用返回的结果来进行判断。由于BROP gadget的存在,我们可以很方便地控制前两个参数,strcmp会发生如下的可能性:

arg1 | arg2 | result
:--: | :--: | :--:
readable | 0x0 | crash
0x0 | readable | crash
0x0 | 0x0 | crash
readable | readable | nocrash

根据这个signature, 我们能够在很大可能性上找到strcmp对应的PLT项。

而对于write调用,虽然它没有这种类似的signature,但是我们可以通过检查所有的PLT项,然后触发其向某个socket写数据来检查write是否被调用了,如果write被调用了,那么我们就可以在本地看到传过来的内容了。

最后一步就是如何确定传给write的socket文件描述符是多少了。这里有两种办法:1. 同时调用好几次write,把它们串起来,然后传入不同的文件描述符数;2. 同时打开多个连接,然后使用一个相对较大的文件描述符数字,增加匹配的可能性。

到这一步为止,攻击者就能够将整个.text段从内存中通过socket写到本地来了,然后就可以对其进行反编译,找到其他更多的gadgets,同时,攻击者还可以dump那些symbol table之类的信息,找到PLT中其它对应的函数项如dup2execve等。

0x11 BROP的攻击流程 2 - 实施攻击


到目前为止,最具挑战性的部分已经被解决了,我们已经可以得到被攻击进程的整个内存空间了,接下来就是按部就班了(从论文中翻译):

  • 将socket重定向到标准输入/输出(standard input/output)。攻击者可以使用dup2close,跟上dup或者fcntl(F_DUPFD)。这些一般都能在PLT里面找到。
  • 在内存中找到/bin/sh。其中一个有效的方法是从symbol table里面找到一个可写区域(writable memory region),比如environ,然后通过socket将/bin/sh从攻击者这里读过去。
  • execve shell. 如果execve不在PLT上, 那么攻击者就需要通过更多次的尝试来找到一个pop rax; retsyscall的gadget.

归纳起来,BROP攻击的整个步骤是这样的:

  • 通过一个已知的stack overflow的漏洞,并通过stack reading的方式绕过stack canary的防护,试出某个可用的return address;
  • 寻找stop gadget:一般情况下这会是一个在PLT中的blocking系统调用的地址(sleep等),在这一步中,攻击者也可以找到PLT的合法项;
  • 寻找BROP gadget:这一步之后攻击者就能够控制write系统调用的前两个参数了;
  • 通过signature的方式寻找到PLT上的strcmp项,然后通过控制字符串的长度来给%rdx赋值,这一步之后攻击者就能够控制write系统调用的第三个参数了;
  • 寻找PLT中的write项:这一步之后攻击者就能够将整个内存从远端dump到本地,用于寻找更多的gadgets;
  • 有了以上的信息之后,就可以创建一个shellcode来实施攻击了。

0x100 后记


以上就是BROP攻击的原理,在这篇博文中重现了这个攻击,有兴趣的可以去看看。

其实在整个攻击过程中最酷的要数第一个步骤:如何dump内存,之后的步骤其实就是传统的ROP攻击了。明白了原理之后,其实最好的了解该攻击的方法就是看源代码了,这个对了解整个ROP会有非常大的帮助。


原文地址: http://drops.wooyun.org/tips/3071

一、项目简介 本项目(HF24075 SDFeatureRivertraining)是一套以多路 PWM 多彩 LED 灯光控制为核心的固件方案,基于 PADAUK PMS 系列单片机。方案对蓝、青、粉等多色 LED 进行独立 PWM 调光,实现呼吸、渐变、流水等细腻灯光效果,并支持按键切换与传感器交互。其 PWM 调光结构清晰,是学习单片机 PWM、色彩混合与灯光算法的理想范例。 核心应用场景: 1. 氛围灯 / 流水灯产品开发 2. PWM 调光与色彩混合学习 3. 电子类课程设计 / 毕业设计 4. 灯光艺术与 DIY 项目 适配使用场景:学习练手、毕业设计、课程设计、创业售卖、实操实训,突出实用性与可落地性。 二、硬件核心配置 · 主控芯片:PADAUK(应广科技)PMS 系列 8 位 OTP 单片机 · 外接外设: - 多色 LED 灯组(蓝 / 青 / 粉等多路独立 PWM) - 轻触按键(模式切换) - 传感器(交互触发) · 操控设备: - 机身实体按键操控 三、核心功能介绍 1. 多路独立 PWM 调光:蓝、青、粉等 LED 各自独立占空比控制,实现精准亮度; 2. 呼吸 / 渐变 / 流水效果:通过 PWM 变化曲线营造丰富灯光律动; 3. 按键切换模式:轻触在多种灯效间循环切换; 4. 传感器交互:外部传感信号触发或联动灯光变化; 5. 低功耗设计:闲置进入低功耗,按需唤醒。 6. 参数可配:亮灭周期、渐变速度等可调,便于定制。 四、项目优势与亮点 · 灯光细腻:多路独立 PWM,效果远胜简单开关灯。 · 算法清晰:呼吸 / 渐变实现简洁,易于理解与移植。 · 扩展性强:可轻松增加颜色与模式,适配各类灯饰。 ·
一、项目简介 本项目(HF24069 Smart Gecko Platform,发射端 TX)是一套智能遥控平台发射端方案,主控采用 PADAUK PMS152 单片机。方案定位于'平台级'遥控输入端:集成多路按键扫描、传感器数据采集与 2.4G 无线发射,支持对码配对,可作为多种遥控产品的通用发射底座,亦适合作为 2.4G 发射端与输入处理的专项学习案例。 核心应用场景: 1. 通用遥控发射平台开发 2. 2.4G 发射端与按键矩阵学习 3. 单片机毕设 / 课设 4. 产品遥控输入端快速定制 适配使用场景:学习练手、毕业设计、课程设计、创业售卖、实操实训,突出实用性与可落地性。 二、硬件核心配置 · 主控芯片:PADAUK PMS152 8 位 OTP 单片机 · 外接外设: - 多路轻触按键(功能 / 方向输入) - 传感器接口(多路采集,约 161 处引用) - 2.4G 射频发射模块 - EEPROM 存储(对码地址) - LED 状态指示 · 操控设备: - 2.4G 无线发射遥控 - 机身实体按键操控 三、核心功能介绍 1. 多按键扫描:完善的按键状态机,支持单击、长按、组合键识别; 2. 传感器数据采集:内置多路传感读取,为遥控端智能化提供数据; 3. 2.4G 无线发射:稳定发射控制指令,与接收端对码配对; 4. 对码配对:上电进入配对,地址掉电保存,多设备互不干扰; 5. 低功耗设计:待机与间歇工作策略,延长遥控端电池寿命。
内容概要:《赛普斯Surpex用户操作手册》详细介绍了粗糙点云处理平台Surpex 2026B的功能与使用方法,涵盖从原始点云导入到三维建模的完整工作流程。软件包含八大核心模块:点云预处理、JRC节理粗糙度计算、粗糙面后处理、轮廓线后处理、面纹理参数计算(ISO 25178)、随机粗糙面生成、岩石碎片拼接及粗糙面实体建模,支持多格式数据导入与模块间数据流转,通过“工作台”实现全局数据管理与协同分析。各模块提供分步操作指引、参数说明与可视化设置,适用于岩石力学、工程地质与表面计量等领域的三维形貌分析与建模需求。; 适合人群:从事岩石力学、工程地质、摩擦学、表面计量等领域的科研人员、工程师及高校研究生,具备三维点云基础处理能力的技术人员;; 使用场景及目标:① 对岩石节理面或工程表面进行JRC粗糙度与ISO 25178面纹理参数的自动化计算;② 实现点云数据的去噪、摆正、裁剪与可视化出图;③ 生成符合目标统计特征的随机粗糙面用于数值模拟;④ 将破碎岩样碎片点云自动拼接还原为完整试件;⑤ 构建带有真实粗糙面的封闭三维实体模型,用于有限元仿真或3D打印; 阅读建议:建议结合手册附带的视频教程(模块1sy.mp4~模块8sy.mp4)对照学习,重点关注各模块间的衔接逻辑与数据卡片的保存加载机制,实际操作中应遵循推荐工作流以确保分析准确性与效率。
内容概要:本文针对辐照度与温度(辐温)双重扰动下独立光伏储能直流供电系统的建模与控制问题,提出了一种多模块耦合建模方法与双级电力电子变换器协同调控策略,并基于Simulink平台完成了系统级仿真验证。研究系统地整合了光伏阵列、储能电池、DC-DC变换器等关键子系统的动态特性,构建了能够反映环境扰动影响的耦合模型,有效刻画了系统内部能量流动关系。在此基础上,设计了结合最大功率点跟踪(MPPT)与储能系统双向充放电控制的双级协同调控架构,实现了在光照和温度剧烈波动条件下对直流母线电压的精确稳定控制与系统功率的动态平衡,显著提升了独立运行系统的供电可靠性与运行效率。; 适合人群:具备电力电子、新能源发电或自动控制等相关专业知识背景,从事光伏储能系统、微电网或分布式能源系统研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于独立光伏储能直流系统的建模仿真与动态性能分析;②为应对复杂环境扰动下的系统稳定性问题提供先进的控制策略设计与理论依据;③支撑科研项目攻关、高水平学术论文复现或实际工程系统开发中的仿真验证与方案优化需求。; 阅读建议:建议结合提供的Simulink仿真模型进行同步学习与验证,重点关注多模块耦合建模的物理机理与数学推导过程,深入理解双级协同控制策略的设计逻辑与参数整定方法,可进一步拓展至不同气候条件和负载工况下的鲁棒性测试与控制算法优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值