간단한 pwn 문제입니다. 실행시키면 다음과 같이 동물 이름을 입력받습니다.
사용자가 입력한 값이 동물이름이면, 해당 동물에 맞는 울음소리를 출력해줍니다. 동물이름이 아니면 아무일도 일어나지 않습니다.. 디스어셈블링해보면 알겠지만, 동물 이름도 cow, sheep, goat, hen 네가지만 해당됩니다.
사용자의 입력은 [rbp-0x110] 에 저장되고, 그 값을 cow, sheep, goat, hen 비교했을 때, 네가지 중 한가지와 같다면 select_animals 라는 심볼을 가진 bss 영역에 저장됩니다. 주소는 0x6020a0 입니다. 한 번 테스트를 해보겠습니다.
첫 번째로 입력한 AAAAA는 동물 이름이 아니기 때문에 저장되지 않고, 두 번째, 세 번째로 입력한 cow와 hen은 bss 영역에 잘 들어가는 것을 확인할 수 있습니다.
이제 문제 파악이 어느정도 되었으면, 어떻게 플래그를 읽을지 궁리해봅니다. 프로그램의 후반부를 보면, 친절히 플래그를 읽어주는 기능이 있는 것을 확인할 수 있습니다. 한 번 조건을 살펴봅니다.
위의 플래그를 읽어주는 조건은, 아까 봤던 bss 영역에 동물 이름대신 "isoroku" 라는 단어가 들어가있으면 만족시킬 수 있습니다.
자, 여기서 문제는 cow, sheep, goat, hen 네 단어 외의 입력 값들은 bss 영역에 입력되지않고 검열된다는 점인데, 이걸 어떻게 우회할 수 있을까요?
우리는 두가지 취약점을 이용할 수 있겠습니다.
첫 번째로는, bss 영역은 한 번의 입력 당 8바이트씩 할당되지만, 우리는 한 번에 최대 16바이트의 입력을 줄 수 있다는 점이겠습니다.
두 번째는, bss 영역에 들어간 값이 동물 이름인지 확인할 때, strcmp 를 사용한다는 점입니다. strcmp는 NULL을 만나기 전까지만 체크하기때문에, 16바이트를 보내도 중간에 NULL을 넣는다면 16바이트 전체가 아닌 NULL을 만나기 전까지의 문자만 체크하게 될겁니다.
이제 취약점을 모두 알아보았으니, 플래그를 읽을 띵킹!을 생각해봅니다.
첫 번째나 두 번째의 입력에 "동물이름 + NULL + isoroku" 를 보내고 그 다음 입력 값은 bss 영역에 저장되지 않도록 AAAA 같은 동물 이름이 아닌 입력을 주면 되겠습니다. 참고로 isoroku 는 아스키 코드로 아래와 같습니다.
끝임미당.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | from pwn import * #r = process("./harekaze_farm") r = remote("problem.harekaze.com", 20328) r.recvuntil(": ") r.sendline("cow") r.recvuntil(": ") text = "isoroku" a = '\x69\x73\x6F\x72\x6F\x6B\x75' r.sendline("cow" + "\x00"*5 + a) r.recvuntil(": ") r.sendline("aaaaa") r.interactive() | cs |
'Write-up' 카테고리의 다른 글
[CODEGATE 2018] Super marimo write-up (339) | 2018.02.20 |
---|---|
[Harekaze CTF 2018] Lost_data writeup (0) | 2018.02.12 |
[CODEGATE 2018] BaskinRobins31 write-up (0) | 2018.02.06 |
[pwnable.kr] random write-up (0) | 2018.01.23 |
[pwnable.kr] blackjack write-up (0) | 2018.01.22 |