I know that there are lot of (good) tutorials regarding this topic, but after reading them, I really cant follow their thoughts (e.g.: Smashing The Stack For Fun And Profit):
The problem is that we don't know where in the memory space of the program we are trying to exploit the code (and the string that follows it) will be placed. One way around it is to use a JMP, and a CALL instruction. The JMP and CALL instructions can use IP relative addressing, which means we can jump to an offset from the current IP without needing to know the exact address of where in memory we want to jump to. If we place a CALL instruction right before the "/bin/sh" string, and a JMP instruction to it, the strings address will be pushed onto the stack as the return address when CALL is executed. All we need then is to copy the return address into a register. The CALL instruction can simply call the start of our code above.
Given the following "crackme" (this example is used as demo, you can skip it and read the question below):
#include <stdio.h>
#include <string.h>
void funktion(char *args) {
char buffer[250];
strcpy(buff, args);
}
int main(int argc, char *argv[]) {
if (argc > 1)
funktion(argv[1]);
else
printf("Kein Argument!\n");
return 0;
}
Target: I want to execute a very basic shellcode within that process.
Vulnerability: Classical potential Stack-Bufferoverflow, due to misuse of strcpy(...)
.
Required Information:
(gdb) info frame 0
Stack frame at 0xffffd300:
eip = 0x8048449 in funktion (stack_bof2.c:7); saved eip = 0x8048474
called by frame at 0xffffd330
source language c.
Arglist at 0xffffd2f8, args: args=0xffffd575 "A"
Locals at 0xffffd2f8, Previous frame's sp is 0xffffd300
Saved registers:
ebp at 0xffffd2f8, eip at 0xffffd2fc
(gdb) print/x &buffer
$1 = 0xffffd1f6
- The
buffer
starts at0xffffd1f6
. - The
R
eturnI
instructionP
ointer (RIP
) is located at0xffffd2fc
. - The offset of the
RIP
from thebuffer
's first element is262 bytes
.
Methodical Approach:
- The
RIP
has to be overwritten withbuffer
s first element's address0xffffd1f6
. - The shellcode has to be placed in the
buffer
location and should not exceed a length of261 bytes
, because from the262th byte
on, theRIP
is being overwritten.
Question: I don't know why all sources state we don't know where in the memory space of the program we are trying to exploit the code. I mean, I know it. It's obviously the buffer
, where the shellcode is placed in. So the RIP
has to point to it. No JMP
, CALL
and relative addressing...
Downloadlink of the crackme.