95c1cc33abfe192d974385c81e0459bf8f8b9f01
ctf/IERAE CTF 2024 writeup.md
... | ... | @@ -249,7 +249,7 @@ if __name__ == '__main__': |
249 | 249 | |
250 | 250 | ## derangement |
251 | 251 | |
252 | -``` |
|
252 | +```python |
|
253 | 253 | def is_derangement(perm, original): |
254 | 254 | return all(p != o for p, o in zip(perm, original)) |
255 | 255 | ``` |
... | ... | @@ -407,4 +407,43 @@ if __name__ == "__main__": |
407 | 407 | ``` |
408 | 408 | |
409 | 409 | </p> |
410 | -</details> |
|
... | ... | \ No newline at end of file |
0 | +</details> |
|
1 | + |
|
2 | +# Pwn |
|
3 | +## This is warmup |
|
4 | +pwnは初挑戦! |
|
5 | +解くことはできなかったが、pwnを解く手順が少しだけ分かった気がする。 |
|
6 | + |
|
7 | +[【入門】はじめてのバッファオーバーフロー](https://qiita.com/Kuroakira/items/82446f083ee2fd05e925)を参考に解いてみた。 |
|
8 | +gdbで変数の中身を覗くくらいはやったことがあったのだが、gdbだけでは難しいようで、`gdb-peda`というラッパーツールを使う。 |
|
9 | +stackの中身を表示しながらデバッグできる。 |
|
10 | + |
|
11 | +gdb-pedaの出力から`win`関数へのアドレスは分かった。 |
|
12 | +どこかに不正な入力を入れ、バッファオーバーフローを起こし、stackのリターンアドレスを書き換えようとした。 |
|
13 | + |
|
14 | +```c |
|
15 | +printf("Enter number of rows: "); |
|
16 | +scanf("%llu", &nrow); |
|
17 | +``` |
|
18 | + |
|
19 | +このscanfに不正な値を入れ、バッファオーバーフローを起こすのだと思ったのだが、バッファオーバーフローを起こせる文字列を特定できなかった。 |
|
20 | +例えば、unsigned long long int (=64bit)の最大値を超える数値を入れると、`0xffffffffffffffff`となり、stackに64ビットを超えて書き込むことができなった。 |
|
21 | + |
|
22 | +```c |
|
23 | +if (nrow * ncol < nrow) { // this is integer overflow right? |
|
24 | + puts("Don't hack!"); |
|
25 | + exit(1); |
|
26 | +} |
|
27 | +``` |
|
28 | + |
|
29 | + |
|
30 | +このチェックは、nrowを0とすればncolがどんな値でも通過できると思ったのだが、そうすると |
|
31 | +```c |
|
32 | +for (unsigned long long int i=0; i<nrow; i++) { |
|
33 | + for (unsigned long long int j=0; j<ncol; j++) { |
|
34 | + matrix[i*ncol+j] = (i+j) % 2; |
|
35 | + } |
|
36 | +} |
|
37 | +``` |
|
38 | +のループが実行できず、SEGVは起こせないことに気が付いた。 |
|
39 | + |