1

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 at 0xffffd1f6.
  • The Return Iinstruction Pointer (RIP) is located at 0xffffd2fc.
  • The offset of the RIP from the buffer's first element is 262 bytes.

Methodical Approach:

  1. The RIP has to be overwritten with buffers first element's address 0xffffd1f6.
  2. The shellcode has to be placed in the buffer location and should not exceed a length of 261 bytes, because from the 262th byte on, the RIP 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.

-2

The reason that we don't know the address, is that with ASLR the program can be loaded at a different address each time the program is run. Thus, if you reboot your os, the program may get loaded at a different Virtual Address.

  • No, that's not the reason in the 1996 article Smashing The Stack For Fun And Profit. The reason we don't know "the exact address of where in memory we want to jump to" is because the shellcode will be on the stack or heap, whose address is often not predictable. – Jason Geffner Oct 5 '15 at 18:59
  • @JasonGeffner "The shellcode will be on the stack or heap, whose address is often not predictable." What do you mean with this, why is it not predictable (by disabled ASLR)? [In this ](reverseengineering.stackexchange.com/questions/11020/…) former question, the exploit worked by overwriting the RIP, and in my book the RIPs address is used, too. So with disabled ASLR the stack should look exactly the same each time I execute the program, or? – JDoens Oct 5 '15 at 19:18
  • "So with disabled ASLR the stack should look exactly the same each time I execute the program, or?" - No, the stack's base may be located at a different address on each execution, even with ASLR disabled. – Jason Geffner Oct 5 '15 at 19:24
  • If you read the article about ASLR, there are several bits of entropy. This includes both the address of the stack AND the base address of the executable. IF ASLR is enabled, then the OS will randomize both the stack and the base address. Some OS's (Linux and Windows) re-use the same memory on subsequent runs of the program. But from the outside you don't know what where the stack, the heap or the program is loaded at. – Milhous Oct 6 '15 at 14:30

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.