Pwn学习随笔(13)

  • 直接地址索引 , 就相当于直接给定了地址 。
  • 一般来说 , 我们会有如下的覆盖需求
    • 覆盖函数返回地址 , 这时候就是直接看 EBP 即可 。
    • 覆盖栈上某个变量的内容 , 这时候就需要更加精细的计算了 。
    • 覆盖 bss 段某个变量的内容 。
    • 根据现实执行情况 , 覆盖特定的变量或地址的内容 。
    之所以我们想要覆盖某个地址 , 是因为我们想通过覆盖地址的方法来直接或者间接地控制程序执行流程 。
    基本ROP随着 NX 保护的开启 , 以往直接向栈或者堆上直接注入代码的方式难以继续发挥效果 。攻击者们也提出来相应的方法来绕过保护 , 目前主要的是 ROP(Return Oriented Programming) , 其主要思想是在栈缓冲区溢出的基础上 , 利用程序中已有的小片段( gadgets )来改变某些寄存器或者变量的值 , 从而控制程序的执行流程 。所谓gadgets 就是以 ret 结尾的指令序列 , 通过这些指令序列 , 我们可以修改某些地址的内容 , 方便控制程序的执行流程 。
    ROP 攻击一般得满足如下条件
    • 程序存在溢出 , 并且可以控制返回地址 。
    • 可以找到满足条件的 gadgets 以及相应 gadgets 的地址 。
    如果 gadgets 每次的地址是不固定的 , 那我们就需要想办法动态获取对应的地址了 。
    ret2textret2text 即控制程序执行程序本身已有的的代码(.text) 。其实 , 这种攻击方法是一种笼统的描述 。我们控制执行程序已有的代码的时候也可以控制程序执行好几段不相邻的程序已有的代码(也就是 gadgets) , 这就是我们所要说的ROP 。
    返回system("/bin/sh")这样的危险函数的地址
    这时 , 我们需要知道对应返回的代码的位置 。当然程序也可能会开启某些保护 , 我们需要想办法去绕过这些保护 。
    例子
    首先 , 查看一下程序的保护机制
    ?ret2text checksec ret2textArch:i386-32-littleRELRO:Partial RELROStack:No canary foundNX:NX enabledPIE:No PIE (0x8048000)可以看出程序是 32 位程序 , 其仅仅开启了栈不可执行保护 。然后 , 我们使用 IDA 来查看源代码 。
    int __cdecl main(int argc, const char **argv, const char **envp){int v4; // [sp+1Ch] [bp-64h]@1setvbuf(stdout, 0, 2, 0);setvbuf(_bss_start, 0, 1, 0);puts("There is something amazing here, do you know anything?");gets((char *)&v4);printf("Maybe I will tell you next time !");return 0;}在 secure 函数又发现了存在调用 system("/bin/sh") 的代码 , 那么如果我们直接控制程序返回至 0x0804863A , 那么就可以得到系统的 shell 了 。
    下面就是我们如何构造 payload 了 , 首先需要确定的是我们能够控制的内存的起始地址距离 main 函数的返回地址的字节数 。
    .text:080486A7leaeax, [esp+1Ch].text:080486ABmov[esp], eax; s这其实就是 push eax 的一个同义写法可以起到混淆作用.text:080486AEcall_gets; 调用 gets 函数参数 即 变量v4的地址 为 esp + 0x1c可以看到该字符串是通过相对于 esp 的索引 , 所以我们需要进行调试 , 需要找出其相对于ebp的索引 , 将断点下在 call 处 , 查看 esp , ebp , 如下
    gef?b *0x080486AEBreakpoint 1 at 0x80486ae: file ret2text.c, line 24.gef?rThere is something amazing here, do you know anything?Breakpoint 1, 0x080486ae in main () at ret2text.c:2424gets(buf);───────────────────────────────────────────────────────────────────────[ registers ]────$eax: 0xffffcd5c→0x08048329→"__libc_start_main"$ebx: 0x00000000$ecx: 0xffffffff$edx: 0xf7faf870→0x00000000$esp: 0xffffcd40→0xffffcd5c→0x08048329→"__libc_start_main"$ebp: 0xffffcdc8→0x00000000$esi: 0xf7fae000→0x001b1db0$edi: 0xf7fae000→0x001b1db0$eip: 0x080486ae→<main+102> call 0x8048460 <gets@plt>

    经验总结扩展阅读