writing tictactoe wp (unfinished)
This commit is contained in:
@@ -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]
|
||||
Reference in New Issue
Block a user