【pwnable.tw】 applestore
做到这道题的时候正赶上iPhone 8上市,撒花~(虽然不知道为啥)

程序分析:
先进到main函数,比较简单。

myCart位于bss段上,是一个长度为0x10。

主要的处理函数是handler函数:

这是一个标准的菜单类题目。挨个函数看下去 list:

这个是各种手机的价格,什么都没有。
再看第二个函数:

这个函数是一个添加购物车的函数,具体采用my_read函数,得到用户输入的商品号,然后用atoi函数进行判断。
my_read函数中存在一个问题,在read部分中以\0分割可以输入其他内容到栈上,并不影响运行结果,因为atoi函数是以\0为分割的。

再看create函数:

先malloc了一块空间,并返回,内容先不说。然后再看insert函数,首先在myCart上寻找,找到第3个字节为0的就将上面malloc的内存挂在上面。

当malloc、insert许多内存块后,大致就形成了链表。
delete函数

首先还是使用my_read函数,接受用户输入,根据输入判断删除的位置,进一步将被删除的内存块从链表中摘除,摘除的操作类似于smallbins的unlink操作。
cart函数,这是一个遍历链表并打印的过程,一遍来说,内存数据泄露都出现在这样的函数中。

checkout函数,这是一个结账函数,但是并不是真的结账,无论选择多少东西,函数都会告诉你下次结账吧。不过这里存在一个彩蛋,当选择商品的总价为7174时,会以1美元的价格在购物车里添加一台iPhone8.

漏洞位置:
位置就是在上面赠送的iPhone 8处,所谓的Free is the most expensive。
之前选择的商品都使用了malloc为商品创建了一块内存,但最后这个用了栈内的一块空间,距离ebp-2c个字节。

有了这点还不够,需要查看这块栈地址是否能被我们利用。
在其他函数中,距离ebp -0x20的位置都可以被用户自己修改。如,



以上位置,再加上my_read中的bug(上文提到的),就可以修改iPhone 8 内存块的任意结构了。
漏洞利用:
首先是7174价格的构造,简单的方法,所有的价格都以99结尾,然后价格以4结尾,总数应该是*6台,所以尝试用199*26 + 100 * 20 = 7174。即 6台 iPhone6 + 20台 iPhone 6s可以构造。
如此可以得到第27块是栈里的一块。
1. libc地址泄露。
在之前说过的,cart函数一般是地址泄露重要的突破点,这个也不例外,可以看到函数逻辑中,在打印部分是顺序遍历链表,若i+8不为空,就打印下一块的i,i+4部分:

前面构造的26块很正常,当第27块构造成如下结构时,即可泄露函数地址:

在用户输入时,别忘了buf是从-22开始的,即前面还有两个自己,这两个字节恰好填充为 “y\0”
如此便可泄露libc地址:

2. 泄露堆地址
仅仅泄露一个libc是不够的,还需要更多数据。
这个地址可以使用bss段上的myCart来泄露,因为bss端地址已知,其次myCart是链表头,具体可将内存块构造成如下这样:

同样,不要忘记前面的“y\0”

3. 泄露stack地址:
上面可以得到第一块malloc得到堆的地址。一定有这样的疑惑,有了第一块堆的地址,通过计算26次malloc(0x10)就可以计算出第26块的地址,才利用上面的方法泄露,不就可以得出了第26块上 i+8的地址了吗?(栈上地址)
最开始就是这么写的,但是实际跑的时候发现并没有这样分配,没有特别多的规律,所以我采用了每次得到下一块堆块的地址,然后泄露其i+8内容,不断迭代得到最后的栈地址。

以上就得到了全部的地址。如果有人知道为啥堆分配不是顺次+ 0x18的请告诉我
仅仅泄露堆栈等地址貌似没什么用,必须找到可以篡改的地方。
4. Dword shoot
DWORD SHOOT是堆漏洞的一个名词,意思是可以精确覆盖一个双字节地址的漏洞,常见的就是unlink漏洞。
上面说过,删除购物车里货物的方式类似于堆的unlink,因此存在的漏洞也类似于unlink的漏洞。
当我们修改第27块iPhone 8的后8字节时,对其进行删除就会有个DWORD SHOOT漏洞。
该漏洞如何利用呢?
覆写一般的地址会有一个四字节的副作用产生,因此常见的利用方法是覆盖下两层函数的ebp,进一步控制esp,控制eip。
详细的原理可以参考之前我写的一篇关于pwnable.kr中的unlink题目:http://www.cnblogs.com/p4nda/p/7172104.html
利用思路是覆盖ebp,控制esp,控制eip,可参看这一篇:http://www.cnblogs.com/p4nda/p/7280520.html
第27块堆块的内容如下:

这次前面两位填写“27”
关键就在于如何构造stack_addr地址,必须找到一块我们可以覆写的内存,且在main函数结束之前不被破坏。这里我选择的在handler函数中的nptr块,

将其构造为:

由于会在main函数退出时执行system('/bin/sh'),因此前两位填写“6\0”,使函数退出。
在这里还踩过一个坑在于使用子函数如cart内的nptr作为fake steak,但是不可以,有耐心的可以自行调一下为啥~
写这个的目的是网上好像没有这题的题解,写个思路就不放exp了。
【pwnable.tw】 applestore的更多相关文章
- 【pwnable.tw】 starbound
此题的代码量很大,看了一整天的逻辑代码,没发现什么问题... 整个函数的逻辑主要是红框中两个指针的循环赋值和调用,其中第一个指针是主功能函数,第二个数组是子功能函数. 函数的漏洞主要在main函数中, ...
- 【pwnable.tw】 alive_note
突然发现已经两个月没写过WP了,愧疚- -... 此题也算一道分数很高的题目,主要考察Shellcode的编写. 又是一道题目逻辑很简单的题. 首先提供了三个函数 查看,删除,添加 查看函数: 此函数 ...
- 【pwnable.tw】 death_note
题目逻辑比较简单,大概增加和删除和打印三个功能: show函数中,打印各日记内容,由于这题没有给出libc文件,应该不需要泄露地址,估计用处不大: delete函数中,正常的free,然后指针修改为n ...
- 【pwnable.tw】 seethefile
一开始特别懵的一道题. main函数中一共4个功能,openfile.readfile.writefile.closefile. 其中,在最后退出时有一个明显的溢出,是scanf("%s&q ...
- 【pwnable.kr】 asm
一道写shellcode的题目, #include <stdio.h> #include <string.h> #include <stdlib.h> #inclu ...
- 【pwnable.kr】 [simple login]
Download : http://pwnable.kr/bin/login Running at : nc pwnable.kr 9003 先看看ida里面的逻辑. 比较重要的信息时input变量再 ...
- 【pwnable.kr】 brainfuck
pwnable.kr第二关第一题: ========================================= Download : http://pwnable.kr/bin/bfDownl ...
- 【pwnable.kr】 unlink
pwnable.kr 第一阶段的最后一题! 这道题目就是堆溢出的经典利用题目,不过是把堆块的分配与释放操作用C++重新写了一遍,可参考<C和C++安全编码一书>//不是广告 #includ ...
- 【pwnable.kr】 memcpy
pwnable的新一题,和堆分配相关. http://pwnable.kr/bin/memcpy.c ssh memcpy@pwnable.kr -p2222 (pw:guest) 我觉得主要考察的是 ...
随机推荐
- 「JSOI2014」强连通图
「JSOI2014」强连通图 传送门 第一问很显然就是最大的强连通分量的大小. 对于第二问,我们先把原图进行缩点,得到 \(\text{DAG}\) 后,统计出入度为零的点的个数和出度为零的点的个数, ...
- WEB安全 - XSS,CSRF
1. CSRF参考 https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/ https://en.wikipedia.org/wiki ...
- 使用KVC键值编码
掌握KVC从不使用setter.getter.点语法开始. ----- 前言 对象的内部状态是由属性进行封装的.访问对象属性的方式平时在开发过程中用得最多的是getter方法和点语法.键值编程KVC也 ...
- Layui我提交表单时,table.reload(),表格会请求2次,是为什么?
重载两次是因为搜索按钮用的是button 改成<a class="layui-btn" data-type="reload">搜索</a> ...
- mapreduce课上测试
今天上课的时候进行了一个mapreduce的实验,但是由于课下对于mapreduce还有hive的理解不够透彻,因此导致了课上没能完成这次实验. 关于本次课堂上的实验的内容大致为: 1.对一个70k的 ...
- 4 JavaScript异常&debugger&保留关键字
try:语句测试代码块错误 catch:语句处理错误,一般提供一个对象如catch(err)用来存储错误信息 throw: 语句创建自定义错误,抛出的信息可以被catch捕获 JavaScript错误 ...
- 如何编写README.md
一.标题写法 1.在文本下方加上 =,文本变为大标题 2.在文本下方加上-,文本变为中标题 3.单独向输入 = ,则需要空一行 标题的另一种写法: # 一级标题 ## 二级标题 ### 三级标题 ## ...
- 3_04_MSSQL课程_Ado.Net_.ExcuteReader()(SQLDataReader)
ExcuteNonQuery(); 返回影响的行数 ExcuteSacalar();返回第一行第一列 ExcuteReader(): Reader,指针,指向表的表头.只是指向,数据仍在数据库中. S ...
- 记录下 k8s (1.14.2)使用kubeadm方式搭建和rancher搭建需要的镜像清单
kubeadm方式 之前一直用的1.12.2版本的,最近想试一下新的版本1.14.2 当然相应的组件镜像版本也需要更新了.镜像版本如下(网络插件使用flannel) k8s.gcr.io/kube-p ...
- Encoding.UTF8 与 new UTF8Encoding(false) 有什么区别?
System.Text.Encoding.UTF8 是一个静态实例,它省略了 BOM,而 new UTF8Encoding(false) 创建的实例是含有 BOM 的. BOM,即 Byte Orde ...