赛博杯新生赛 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 进行许可。