Pwnable.tw Appstore-Seethefile-Spirited_away



appstore

题目是一个选单程序,主要模拟了apple store购买物品并结账的过程。

程序共有五种操作

  1. applestore:打印所有的商品及其价格信息
  2. add:将相应商品的编号加入到shopping cart中
  3. remove:将商品从shopping cart中移除
  4. list:打印当前的cart
  5. checkout:结算账单

程序为cart每个商品分配一个note节点,其结构如下:

node通过fd,bk连接,构成双向循环链表,头指针连接在bss段0x804B070处。
其中主要分析两个delete,checkout两个函数:

可见delete实现了一个简单的,无check的unlink。
checkout:

checkout 首先通过cart打印账单信息,如果总金额达到7174元,则1元赠送一部iphone8
注意,这时的iphone8的node并不在heap中,而是在stack上。

程序在add,delete中都不存在能够利用的漏洞
根据题目提示,we need you to jailbreak the iPhone8,我们必须在iphone 8中做文章
将总金额凑够7174元,我们能够发现,iphone8的node在栈中,而该栈空间是被覆盖,不断变化的

通过调试,该栈空间恰好被my_read函数的输入buf覆盖,这样我们通过控制atoi(buf)就能够控制最后一个node的内容

首先,泄露地址,handle中输入GOT[‘__libc_start_main’]可以顺利进入list,因为__libc_start_main的最后一个字节是"4",atoi将字符串转化为4,进入list打印,可泄露出libc

计算出system等地址后,想到利用unlink,remove中的结果进行unlink,劫持GOT表,从而劫持控制流
但是,一般的unlink都是双向写,如果我们想将libc_system写入GOT[‘atoi’],势必会将libc_system附近的地址也造成更改,会触发Segment fault。
这里实现的是将ebp更改为GOT[‘atoi’]+0x22的解法,ebp更改为此后,在handle中

恰好控制nptrGOT[‘atoi’]地址处,这样my_read时即可写入GOT表,在aoit(nptr)时,即可控制执行
system(“{libc_system address};/bin/sh”)用;截断命令,即可顺利起Shell。

上述的方式比较巧妙,当然还有更加稳妥,通用的控制ebp的方式,总是这样的unlink需要创造双向同时更改的条件,进而一般在堆栈空间,elf的.bss段和libc的.bss段上做文章。

seethefile

典型的FSP

程序菜单有5个选项,分别是openfile,readfile,writefile,closefile与最后存在栈溢出的输入name

其中writefile并不是写入文件的操作,而是从文件中读入的内容写到终端界面上,整个文件操作的过程过滤掉了"flag"之类的字符串

容易发现,name溢出会覆盖到FILE fp指针,我们利用FSP可以构造fake FILE,从而使得接下来的fclose执行system(“/bin/sh”),不了解FSP的朋友可以参考:

于是,首先通过读/proc/self/maps泄露得到libc的地址,Bypass ASLR
在之后在name溢出的基础上,构造fake IOFILE_plusfake io_jump_t,Getshell

Script:

最后进入flag所在的目录,我们可知flag是无法直接读取的,需要使用官方的get_flag,简单读一下源码,即可顺利拿到flag的内容

spirited_away

典型的House-of-spirit

程序不难逆向,一共输入4项,分别是comment,age,name,reason,其中注意在sprintf处,存在一个off by one.

其在栈中结构如下,如下所示,当%d为3byte会stack overflow 1个byte,覆盖其为"n"


恰好覆盖的是nbyte变量的值又0x3c改变为0x6e,但是这个heap溢出很难利用,但是在栈中能造成free的*name指针被控制,于是想到house of spirit。
首先,由于堆栈未初始化,在输入reason时,可能控制输入长度,从而泄露出libc地址和stack地址
之后,如下的栈结构为了能够覆盖到返回地址,我们在reason上构造fake chunk

name指针更改为fake chunk的栈中地址,利用House of spirit

将fastbin劫持到栈中,由于溢出后nbyte=0x6e,所以可以在栈中溢出返回地址,从而ret2libc 拿到Shell

发表评论