ICQ 2018 Christmas Pwn WereWolf



爱春秋圣诞CTF的一道Pwn题,漏洞比较简单,但是由于官方的libc问题,无法成功泄露出libc的版本,所以在漏洞利用上是比较繁琐的,这里采用了利用format-string将stack-frame劫持到heap空间中,Stack-pivot做ROP,最后Ret2syscall的方式,成功Getshell。

reverse

Adapted from ICQ-Baidu-February Pwn werewolf.
爱春秋2月场Werewolf改编而来,操作与2月的Werewolf基本一样,Binary开启了NX与Canary
题目中没有提供libc,所以不要妄想找到题目的libc,肯定需要用无libc的方式.
首先逆向分析题目:
题目模拟了”狼人杀”-Werewolf这款游戏,其中每个role-角色都建立一个action存储用户的行为。

在heap上建立了一个存储rope的list,分别储存*action与action的length。
共有一下四种操作:

  1. add: 增加一个role
  2. edit: 编辑已有的role的action
  3. show:打印一个已有的role的action
  4. kill:删除一个已有的role
  5. edit: 打印bye~后退出

整体来说题目流程是比较清晰的,不难逆向。

vulnerability

漏洞触发在show函数中,是一个比较容易发现的格式化字符串漏洞


原本在2月场中在kill中出现的double-free被修补

利用该format string,因为我们可以无限次地edit一个role,再通过show打印出来触发漏洞
从而我们拥有了无限读写的能力 no limit read or write.

我们不考虑确定libc的地址,因为ichun之前题目的环境也是比较..,从来找不到确定的libc版本,所以我们考虑ret2syscall,通过泄露的一个libc地址确定syscall的地址,再通过stack pivot到heap中ret2syscall rop,最后spawn shell。
这里需要解决几个问题:syscall地址 : 可以通过读write地址的,计算偏移得到syscall的地址

  • heap地址:通过printf前的stack结构,将0x6020A8写入栈,并通过foramtstring入出heap的地址
  • 如何stack-pivot:首先需要劫持rbp为heap地址,之后通过leave等改变rsp,从而进行栈偏移
  • 如何Rop:利用万能的_init_中的RopGadgtes

scenario

最终的exp基本是按照上述的思路进行:

  1. 通过泄露write_addr,进行偏移计算得到syscall的地址
  2. 泄露stack地址,为format-string打栈做准备
  3. 泄露heap地址
  4. 修改栈中value,将stack-pivot的目标heap地址写入栈中
  5. 修改两处返回地址,如下图,进行Rop
  6. 顺利劫持程序流后,通过Ropgagtes 执行read(0,elf.bss,0x3B)后令eax=0x3b,并将“/bin/sh”写入
  7. 再次通过Ropgagtes执行execve(“/bin/sh”,NULL,NULL)Spawn shell

最后,在写入栈中,我们用show函数中的rbp地址作为跳板,向栈中写入数据。
为了防止通信数据量过大造成阻塞,exp中全部用的%hhn进行写入。
注意通过rbp跳板向栈中写value要从高地址向低地址写,这是由于程序本身造成的,调试可见端倪,不再赘述。

结果:

发表评论