赛博杯新生赛 2024 - corrupted 出题博客
前段时间在看ELF头,正好新生赛到了,可以拿来出一道简单题,类似于ret2shell。
想看题解的可以跳过出题思路部分。
出题思路
首先可以使用ImHex来探查一下文件的结构。加载elf.hexpat:

大部分内容在ctf-wiki 都说得很清楚,我这里就不再赘述了,大家可以参考学习。我的想法主要是如果修改了ELF文件头, 会发生什么呢?
对于程序头phdr来说,如果p_type == PT::LOAD,那么它就是负责加载程序段的。
对于本题的情况,我把原来加载代码段的rx改成了rwx,这样代码段就变成可读可写可执行了。

我还尝试改过段头shdr,但是发现改完后对于程序的加载没有任何影响,甚至把整个shdr
全部删掉,程序依然能够运行。
用gdb直接调试没有段头的程序,会提示可执行文件格式错误,这也是反调试的一种手段。
接着讲回phdr,在程序头中,存在2个程序安全特性:PT::GNU_STACK和PT::GNU_RELRO。
对于前者,p_flags可以设置程序栈区的权限(可以为x,即调整NX);对于后者,
调整了权限也没用,程序仍然会将GOT表设为只读。删除PT::GNU_STACK
会让内核自行选择是否需要开启NX,删除PT::GNU_RELRO则会使程序从Partial RELRO
或Full RELRO回落到No RELRO。
隐藏的构造器
有些同学可能看见randdata放在bss上,就以为randdata里面是空的,只要推算出全0的
SHA256结果就能过verify。然而,程序中还有一个函数loadBuf,被标记了constructor
属性,在程序运行main之前会将从/dev/random中的随机数据读入randdata中,
因此如果正常猜的话选手是不可能猜中randdata的值的。
题解
程序可以输入4次qword,并且可以指定相对于match的偏移量,但是检查时不严格,
可以为负数。

在输入完4次qword后,会运行到verify函数。运行起来查看vmmap,程序代码段是可写的,
再检查verify的地址,刚好和match差了0x2b90个字节,可以通过设置偏移量为-1394修改
verify函数的内容。

可以修改4次,总共32字节,足以写一shellcode了,直接拿shell。

EXPLOIT
1 | from pwn import * |
参考
- 标题: 赛博杯新生赛 2024 - corrupted 出题博客
- 作者: RocketDev
- 创建于 : 2024-12-18 19:37:00
- 更新于 : 2024-12-22 10:47:00
- 链接: https://rocketma.dev/2024/12/18/corrupted/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。