2025dasctf-wp
题目链接
1 | https://github.com/yfor-yfor/-/tree/main/2025dasctf |
pwn1
没给libc,但是测一下泄露和double free就能知道是2.27的libc
之后就是简单的两次posion,泄露pie,libc等等,最后打hook为backdoor,注入shellcode即可
1 | from pwn import* |
pwn2
2.35的libc
先是有一个login,r00t和一个base64加密,输入特定内容即可
题目给了4个常规交互和一个backdoor
backdoor里面有uaf并且能泄露pie
毕竟限制了chunck的size大小,所以打house of botcake即可
值得注意的是,如果通过exit触发io的话会加沙箱,所以直接打stdout的house of apple2即可在menu中触发io,执行system(‘/bin/sh’)获得shell
1 | from pwn import* |
pwn3
vmpwn
程序流程
main函数中会打开vmcode文件,然后分别读取一些内容到s里和buf里,后续进入vm部分
1 | void __fastcall __noreturn main(__int64 a1, char **a2, char **a3) |
vm函数
1 | void __fastcall __noreturn vm(S *s) |
会根据s中的内容,转化为对应指令并且执行
区别于我们之前遇到的pwn题,指令由我们自己输入,这个pwn题的指令是由一开始的vmcode文件读入的,而他的功能也很简单
1 | write(1,"What's your name?",17) |
当输入的长度超过0x18时,其实就会覆盖一些opcode,导致程序出现异常,要么在init段无法正常分析出choice,要么导致ip或esp大小不满足条件,最终输出segment error并且退出
结构体
1 | struct S |
1 | struct sa |
攻击过程
在输入0x18个字符之后的四个字节会用来控制ip,控制他指向我们后续的opcode
后续只用到了case3和case0
其中case3的case3是给寄存器赋值一个32位的任意值
而case0是关键
1 | case 0x33: |
由于我们的结构体中没有rax,同时注意到sys的一参是offset
观察汇编可以发现,程序在进入sys前,用rdi存储rax,rsi存储rdi等等,再进入sys后,又复制回来执行syscall
虽然这么多case都对应了syscall,但是每个都是不同的
因为我们的结构体中,各个寄存器都是32位的,无论我们后续要打execve还是orw,必然要有一个寄存器的值是一个地址指针,而在这个开启了pie的题目中,32位的值不足以作为一个地址
但是题目之前既然可以自如的使用read,write,就说明这些syscall中有些特殊,观察case 0x34对应的汇编可以发现
1 | .text:000000000000171E mov rax, [rbp+var_8] ; jumptable 000000000000152B case 52 |
也就是说,在进入sys前,这一段操作,令rsi变成了一个64位数,并且值是buf+offset
而rsi在进入sys后会把值给rdi,这也就说明,只要rdi的值是/bin/sh在buf上的偏移,在进入sys后,rdi的值就会是buf+偏移(即/bin/sh的指针)
除此之外,在进入case0前,init中还有一步会循环处理我们的offset,为了使他最终是我们需要的0x3b,选择依顺序传入0,0,0x3b,最终offset就能是0x3b了
1 | for ( i = 0; i <= 2; ++i ) |
exp
1 | from pwn import* |
- Title: 2025dasctf-wp
- Author: yfor
- Created at : 2025-12-07 12:36:39
- Updated at : 2025-12-07 12:36:33
- Link: https://yfor-yfor.github.io/2025/12/07/2025dasctf-wp/
- License: This work is licensed under CC BY-NC-SA 4.0.