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 | + |