
ACTF2025 - only_read

本次ACTF2025我们0RAYS最后取得第7名,pwn方向差点爆零。
文件属性
属性 | 值 |
---|---|
Arch | amd64 |
RELRO | Partial |
Canary | off |
NX | on |
PIE | off |
strip | no |
libc | 2.39-0ubuntu8.4 |
解题思路
整个程序非常简单,main
就构造了一个很大的栈溢出,也没啥gadget,但至少没开PIE。
一旦能打栈迁移到bss,就有机会打dl_resolve,实现任意符号解析(但是控制不了参数)。
第一步控制rbp
到bss上,第二步向bss上读入要伪造的符号和rop链再次读入,
第三步执行伪造的write
泄露libc并把open shell的rop链写到bss上,执行拿shell。
第一步和第三步都没啥好说的,唯一比较麻烦的就是符号伪造。 还好我以前做过类似的题, 可以用来借鉴。
原博客对于reloc_arg
的描述有误,它是相对于__DT_JMPREL
的,
不是相对于__DT_SYMTAB
,现已更新。
这次我采用了人工构造的方式去伪造一个write
符号,即Elf64_Sym
和Elf64_Rela
,
接下来将图解我构造的结构体:
fake_sym
和fake_rel
需要分别对齐到从symtab
和jmprel
开始的0x18边界上,
否则_dl_fixup
不能正确读取我们的伪造的符号。可以看以下代码中的test_offsets
做参考。
当开始执行plt_init
时,就会运行_dl_runtime_resolve_xsavec
,随后执行_dl_fixup
,
将我们伪造的各种数据作为参数开始解析write
函数并运行,如下图所示:
由于在执行write
前,write@libc
就会被写入,因此执行时就会泄露libc,
之后再次读入payload时就可以构造execl("/bin/sh", "/bin/sh", NULL)
打开shell。
在这个过程中,rdi
和rdx
保持不变,因此会输出很多字节;由于对于远程来说,
fd = 0
和fd = 1
是完全一致的,都是socket,就像直接在终端打开,都是/dev/pts/1
,
因此,fd = 0
既可以读也可以写。但是pwntools不一样,使用process
打开进程,
fd = 0
会指向一个无名管道,而这个管道只能读不能写,因此向fd = 0
中write
数据不可行。
为了避免这个问题,我采用了用docker起一样的libc环境,然后由 xinetd 起一个 gdbserver,
这样就可以实现远程调试。具体见我StackLogout的出题博客。
docker调试相关文件
1 | service ctf |
1 | service debug |
1 | FROM ubuntu:24.04 |
1 |
|
patchelf会改变strtab和symtab
当我起了容器开始调试以后,突然发现在本地能打的脚本远程突然就打不了了,
一看是strtab
和symtab
变了。原来在patchelf的时候,strtab
和symtab
会变化,
变得更低一些。也是因为这个原因,patch过的人和没patch的人脚本就不一样,
所以官方靶机布置了4个,我由于在docker里还原了libc,跑的程序就没patch,
本地能跑通的脚本,放到远程只有3号机可以,其他均不行。
EXPLOIT
1 | from pwn import * |
赛后复盘
当初我还纳闷为啥 arandom 这么一道内核题怎么有这么多队出,看了星盟的博客,
原来是非预期。/
的uid是1000,我们可以mv /etc 1; mkdir /etc
来替换etc文件夹,
然后echo 'root::0:0:root:/root:/bin/bash' > /etc/passwd
来完成passwd替换,
就可以直接su bash
提权了...属实没想到,点竟然在根目录的权限设置上。
使用find / -user 1000 ! -path '/proc/*'
可以找用户为1000的文件,
并排除proc
目录下的文件。
还有AFL sandbox
,沙箱中允许了shmat
,同时afl-fuzz
调用了shmget
,
我还以为是要打共享的数据,搞了半天侧信道就可以了,有点无语...明明看题的时候又想到。
参考
- 标题: ACTF2025 - only_read
- 作者: RocketDev
- 创建于 : 2025-04-27 22:29:00
- 更新于 : 2025-04-27 22:29:00
- 链接: https://rocketma.dev/2025/04/27/only_read/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。