writing tictactoe wp (unfinished)

This commit is contained in:
taoky
2020-11-03 10:26:43 +08:00
parent 2ef2ec5fd2
commit 018ecc991e
+35
View File
@@ -1 +1,36 @@
# 生活在博弈树上
很明显这道题题面是根据 2020 年浙江的满分高考作文《生活在树上》魔改而来的,没有任何逻辑性可言的版本。打开题目后,就会发现它其实是一个井字棋,并且在算法(Minimax)实现正确的情况下,后手的人类是赢不了先手的电脑的。
既然是信息安全大赛,那肯定要用信息安全的思路去解题。如果用 CTF 的方式去分类的话,这应该算是一道典型的简单 pwn 题了。
## 始终热爱大地
打开源代码读过代码,我们就能轻易发现一个很危险的信号:
```c
printf("Your turn. Input like (x,y), such as (0,1): ");
gets(input);
x = input[1] - '0';
y = input[3] - '0';
```
尽管很多初学 C 语言的同学会使用 `gets()` 去读取一行字符串(至少我所观察到很多没有编程基础初学 C 语言的大一新生会这么做),但是这个函数是非常危险的:它不会限制输入的长度,可以构造出长度大于接受输入的数组长度的字符串,从而实现一些“意料之外”的事情。
为了获得第一个 flag,我们的目标是让程序运行 `success` 分支,输出 flag。正常下井字棋是肯定赢不了的(除非我代码写错了 :)),那么我们就需要在程序运行时想办法让 `success` 的值变为 `true` (1),然后就能立刻跳出 `while` 循环而胜利。可以注意到,在变量定义的时候,`success` 就贴在 `input` 数组的旁边。
```c
bool success = false; // human wins?
char input[128] = {}; // input is large and it will be ok.
```
那么我们能不能在 `gets` 的时候,就把 `success` 弄成 `true` 呢?答案是可以的!
[TBD]
## 升上天空
第一题的 flag 提示我们要 getshell 得到第二个 flag。使用 `checksec` 检查程序文件。
[TBD]