ciscn2024_半决赛_东北
ret2shellcode

没有NX保护
有沙盒但不完全


有栈溢出和格式化漏洞
exp
1 | from pwn import * |
patch
改栈溢出漏洞,把read的0x80改小


附件
通过网盘分享的文件:ciscn2024_华东北.zip
链接: https://pan.baidu.com/s/1QhM_CNsAq3ztwfa7FRpMFg?pwd=GAME 提取码: GAME
stdout


int setvbuf(FILE *stream, char *buf, int mode, size_t size);控制 FILE 流的缓冲方式
- 全缓冲:0,缓冲区满 或 调用fflush() 后输出缓冲区内容。
- 行缓冲:1,缓冲区满 或 遇到换行符 或 调用fflush() 后输出缓冲区内容。
- 无缓冲:2,直接输出。
此时puts的内容都写进缓冲区了。没有真正显示,此时的输入是对下面 read(0, buf, 0x10u);的输入
printf
| 函数参数顺序 | 含义 | 寄存器 | 对应格式化参数 |
|---|---|---|---|
| 第1个 | format | RDI | ❌ 不参与 %n$ |
| 第2个 | arg1 | RSI | %1$ |
| 第3个 | arg2 | RDX | %2$ |
| 第4个 | arg3 | RCX | %3$ |
| 第5个 | arg4 | R8 | %4$ |
| 第6个 | arg5 | R9 | %5$ |
| 第7个+ | 栈(rsp) | stack | %6$ 以后 |
sprintf
| 函数参数顺序 | 含义 | 寄存器 | 对应格式化参数 |
|---|---|---|---|
| 第1个 | dest | RDI | ❌ 不参与 %n$ |
| 第2个 | format | RSI | ❌ 不参与 %n$ |
| 第3个 | arg1 | RDX | %1$ |
| 第4个 | arg2 | RCX | %2$ |
| 第5个 | arg3 | R8 | %3$ |
| 第6个 | arg4 | R9 | %4$ |
| 第7个+ | 栈(rsp) | stack | %5$ 以后 |
发送b’a%6$llna’ + p64(0x404070)执行sprintf(buf, buf);
| 格式符 | 写入类型 | 写入字节数 | 等价C类型 |
|---|---|---|---|
%n |
int* | 4字节 | int |
%hn |
short* | 2字节 | short |
%hhn |
char* | 1字节 | char |
%ln |
long* | 8字节(x64) | long |
%lln |
long long* | 8字节 | long long |
偏移是6
1 | from pwn import * |
patch
改这个溢出漏洞

heap
凑one_gadget的条件

凑成了有效 argv 数组
\*(rsp+0x38) == 0(数组要有 NULL 结尾,至少 argv[1] 是 NULL)\*(rsp+0x30)是一个“可读的指针”(能当作字符串地址,读取到\0结束)
也就是最小 argv:

exp
2.23的堆题
1 |
|
patch

找到最开始的赋值处,改溢出的大小

cpp
结构体


输入都不限制大小
对str取地址

对c_str取地址

思路:通过c_str的溢出覆盖str为good的got表地址
再把got表地址覆盖为后门地址
exp
1 | from pwn import * |