6.1.19 pwn HITBCTF2018 gundam

下载文件

题目复现

$ file gundam
gundam: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=5643cd77b84ace35448d38fc49e4d3668ef45fea, stripped
$ checksec -f gundam
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FORTIFY Fortified Fortifiable  FILE
Full RELRO      Canary found      NX enabled    PIE enabled     No RPATH   No RUNPATH   Yes     0               4       gundam
$ strings libc-2.26.so | grep "GNU C"
GNU C Library (Ubuntu GLIBC 2.26-0ubuntu2.1) stable release version 2.26, by Roland McGrath et al.
Compiled by GNU CC version 6.4.0 20171010.

保护全开,也默认 ASLR 开。libc 版本 2.26,所以应该还是考察 tcache(参考章节4.14)。

玩一下:

$ ./gundam
...                                     # 创建了两个 gundam
1 . Build a gundam
2 . Visit gundams
3 . Destory a gundam
4 . Blow up the factory
5 . Exit

Your choice : 2

Gundam[0] :AAAA
Type[0] :Freedom

Gundam[1] :BBBB
Type[1] :Strike Freedom

1 . Build a gundam
2 . Visit gundams
3 . Destory a gundam
4 . Blow up the factory
5 . Exit

Your choice : 3
Which gundam do you want to Destory:0   # 第一次销毁 gundam 0,成功

1 . Build a gundam
2 . Visit gundams
3 . Destory a gundam
4 . Blow up the factory
5 . Exit

Your choice : 3
Which gundam do you want to Destory:0   # 第二次销毁 gundam 0,成功

1 . Build a gundam
2 . Visit gundams
3 . Destory a gundam
4 . Blow up the factory
5 . Exit

Your choice : 2                         # 此时剩下 gundam 1

Gundam[1] :BBBB
Type[1] :Strike Freedom

1 . Build a gundam
2 . Visit gundams
3 . Destory a gundam
4 . Blow up the factory
5 . Exit

Your choice : 4                         # 销毁 factory
Done!

1 . Build a gundam
2 . Visit gundams
3 . Destory a gundam
4 . Blow up the factory
5 . Exit

Your choice : 2                         # gundam 1 没有变化

Gundam[1] :BBBB
Type[1] :Strike Freedom

1 . Build a gundam
2 . Visit gundams
3 . Destory a gundam
4 . Blow up the factory
5 . Exit

Your choice : 3                         # 第三次销毁 gundam 0,失败
Which gundam do you want to Destory:0
Invalid choice

根据上面的结果也能猜出一些东西。比如在没有销毁 factory 的情况下,可以多次销毁 gundam。而销毁 factory 不会对没有销毁的 gundam 造成影响。

题目解析

main

一个典型的 switch-case 跳转结构。

Build a gundam

通过分析这个函数,可以得到 gundam 结构体(大小为0x28)和 factory(地址0x002020a0) 数组:

另外 gundam->name 指向一块 0x100 大小的空间。gundam 的数量存放在 0x0020208c

从读入 name 的操作中我们发现,程序并没有在末尾设置 \x00,可能导致信息泄漏(以\x0a结尾)。

Visit gundams

该函数先判断 gundam_num 是否为 0,如果不是,再根据 factory[i] 和 factory[i]->flag 判断某个 gundam 是否存在,如果存在,就将它的 name 和 type 打印出来。

Destory a gundam

该函数用于销毁 gundam,它先将 gundam->flag 置为 0,再释放掉 gundam->name。

这里有几个问题:

  • 该函数是通过 factory[i] 来判断某个 gundam 是否存在,而在销毁 gundam 后并没有将 factory[i] 置空,导致 factory[i]->name 可能被多次释放

  • name 指针没有被置空,可能导致 UAF

  • 销毁 gundam 后没有将 gundam_num 减 1

Blow up the factory

该函数会找出所有 factory[i] 不为 0,且 factory[i]->flag 为 0 的 gundam,然后将该 gundam 结构体释放掉,factory[i] 置为 0,最后 gundam_num 每次减 1。

经过这个过程,销毁 gundam 留下的问题基本解决了,除了 name 指针依然存在。

Exploit

所以利用过程如下:

  1. 利用被放入 unsorted bin 的 chunk 泄漏 libc 基址,可以计算出 __free_hooksystem 的地址。

  2. 利用 double free,将 __free_hook 修改为 system

  3. 当调用 free 的时候就会调用 system,获得 shell。

leak

chunk 被放进 unsorted bin 时:

可以看到对应的 tcache bin 中已经放满了 7 个 chunk,所以第 8 块 chunk 被放进了 unsorted bin。

再次 malloc 之后:

可以看到程序并没有在字符串后加 \x00 隔断,所以可以将 unsorted bin 的地址泄漏出来,然后通过计算得到 libc 基址。

overwrite

触发 double free 时:

其 fd 指针指向了它自己。

接下来的 malloc 将改写 __free_hook 的地址:

pwn

Bingo!!!

exploit

完整的 exp 如下:

参考资料

Last updated

Was this helpful?