Category - 2021广东大学生

两道经典菜单堆题。

BabyNote:

  1. 分配的堆块大小固定为0x60,最多可以分配32个。
  2. 释放堆块时没有清空指针,导致 use-after-free 或者 double free。
  3. 没有 show 功能,可以泄露低16比特的堆地址。

BabyNote_revenge 在 BabyNote 的基础上做了以下改动:

  1. 最多分配堆块数量减少为16个。
  2. 有条件泄露堆地址。输入 puts 地址后,可以泄露完整的堆地址,同时获取3次任意地址写机会,途中加载 ORW seccomp 沙盒。

方法一:double-free 法(通杀两题)

该方法无需泄露堆地址,只需分配9次堆块就能泄露 libc 地址。

题目libc版本是 2.31。新版本 2.27 以后,tcache 会对链表中的所有堆块进行 double free check,所以不能像以前这样直接利用 double free。

绕过方法很简单:只有当 chunk 的 key 字段(刚好位于 fd 后面)恰好等于 tcache 地址时,tcache 才会进行 double free check,所以我们通过 UAF 将前 0x10 字节直接清零就能绕过了。

思路与方法二十分相似,都是试图将一个 chunk 释放到 unsorted bin。

首先分配 4 个堆块:

  1. for i in range(4):
  2. alloc()

然后依次释放chunk #0、#1。此时 chunk #1 fd 指向 #0(低1字节是0xa0).

我们通过 UAF 将 #1 fd 低1字节修改为 0xb0,即把 fd 指针向下移动 0x10 字节。

  1. # tcache fd = chunk+0x10
  2. delete(0)
  3. delete(1)
  4. edit(1, p8(0xb0))
  5. alloc()
  6. alloc() # chunk #5

这样我们可以通过 chunk #0 控制 chunk #5 的头部。

将 chunk #5 的大小修改为 0x110。

  1. edit(0, flat([0, 0x111]))

Fake chunk:

binwalk -Me pig.gif 可以获得一个压缩文件,需要密码打开
enter image description here

把gif每帧拆分出来
enter image description here

找第一帧和其他帧的不同像素点,然后组合,可以得到一张二维码,识别结果是JUZFU2C2NJTTETKUKF3Q====,base32再base64解码

  1. from PIL import Image
  2. img1 = Image.open(f"frame1.bmp")
  3. res = Image.new("1", (650, 650))
  4. for k in range(2, 26):
  5. img2 = Image.open(f"frame{k}.bmp")
  6. for i in range(650):
  7. for j in range(650):
  8. if img1.getpixel((i, j)) != img2.getpixel((i, j)):
  9. res.putpixel((i,j), 255)
  10. res.show()

enter image description here

enter image description here

3faf86140就是压缩包密码,解压可得一张图,猪圈密码解密即可
enter image description here

strings dump | grep '^[[:alnum:]]{8}:' > result.txt 提取出hexdump

enter image description here

重新排序组合

  1. end = 0x003d7150
  2. file = open("result.txt", "r").readlines()
  3. out = open("recovery.txt", "w")
  4. dic = {}
  5. for line in file:
  6. s = line.split(": ")
  7. if len(s[1]) < 39:
  8. continue
  9. idx = int(s[0], 16)
  10. data = s[1][:39]
  11. dic[idx] = data
  12. for i in range(0, end, 16):
  13. out.write(dic[i]+'\n')
  14. out.close()

enter image description here

将排序后的数据复制粘贴到hxd,还原pcap文件

enter image description here

还原后的pcap文件用wireshark打开会报错,点ok可以继续打开,但是看了一下没找到有用的信息,后续用strings recovery.pcap > pcap_str.txt可以发现某些数据中含有/127.0.0.1/RAPID/T_ROB1/Module1/tgPos{}字串,字串后面就是位置信息

enter image description here

grep 'tgPos' -A 2 pcap_str.txt > pos.txt 提取全部位置信息

enter image description here

脚本还原

  1. import time
  2. # f = open("pos.txt", 'r').readlines()
  3. # pos = []
  4. # for i in range(2, len(f), 4):
  5. # pos += eval(f[i])
  6. pos = [92, 81, 0, 92, 81, 0, 93, 81, 0, 93, 80, 0, 95, 80, 0, 98, 80, 0, 100, 80, 0, 102, 80, 0, 107, 80, 0, 111, 81, 0, 114, 82, 0, 117, 83, 0, 119, 85, 0, 121, 86, 0, 123, 87, 0, 124, 88, 0, 125, 90,

binwalk -Me test.pcapng 分离出flag.txt

enter image description here

enter image description here

cyberchef一把梭
enter image description here