HITCON Training 이라는 유명한 워게임...이라기엔 좀 그렇고 포너블을 연습하기 좋은 문제 모음(?)이라고 보는게 더 맞을것 같습니다. 원래 유례를 찾아 보려고 했는데 잘 나오지 않아서 찾지 못했습니다. 다만 이름으로 추정해보면 매년 열리는 HITCON에서 Training을 진행하는데 거기서 따온것 같습니다. HITCON Training은 총 15문제로 이루어져있으며 아래 링크에서 다운받을 수 있습니다.
https://github.com/scwuaptx/HITCON-Training
문제 분석
일단 lab1 에 들어가보면 sysmagic이라는 바이너리와 소스코드 파일이 있습니다. 원래 Training 때도 소스코드가 공개 됐었는지는 모르겠지만 보고하면 재미 없을것 같으니 최대한 소스코드는 무시하면서 풀기로 했습니다. 일단 무작정 바이너리를 실행하고 아무런 값이나 넣어봤으나 별다른 반응이 없어서 바로 pwndbg로 까보기로 했습니다.
Dump of assembler code for function main:
0x08048774 <+0>: lea ecx,[esp+0x4]
0x08048778 <+4>: and esp,0xfffffff0
0x0804877b <+7>: push DWORD PTR [ecx-0x4]
0x0804877e <+10>: push ebp
0x0804877f <+11>: mov ebp,esp
0x08048781 <+13>: push ecx
0x08048782 <+14>: sub esp,0x4
0x08048785 <+17>: mov eax,ds:0x804a034
0x0804878a <+22>: push 0x0
0x0804878c <+24>: push 0x2
0x0804878e <+26>: push 0x0
0x08048790 <+28>: push eax
0x08048791 <+29>: call 0x8048460 <setvbuf@plt>
0x08048796 <+34>: add esp,0x10
0x08048799 <+37>: call 0x804859b <get_flag>
0x0804879e <+42>: mov eax,0x0
0x080487a3 <+47>: mov ecx,DWORD PTR [ebp-0x4]
0x080487a6 <+50>: leave
0x080487a7 <+51>: lea esp,[ecx-0x4]
0x080487aa <+54>: ret
End of assembler dump.
main 함수의 어셈블리 코드입니다. setvbuf와 get_flag를 호출하는것을 제외하면 특별하다라고 볼만한게 없습니다. 일단 이름에서부터 flag값을 알아낼 수 있을것 같은 get_flag 함수를 살펴보기로 합니다.
Dump of assembler code for function get_flag:
0x0804859b <+0>: push ebp
0x0804859c <+1>: mov ebp,esp
0x0804859e <+3>: sub esp,0x88
0x080485a4 <+9>: mov eax,gs:0x14
0x080485aa <+15>: mov DWORD PTR [ebp-0xc],eax
0x080485ad <+18>: xor eax,eax
0x080485af <+20>: mov DWORD PTR [ebp-0x3e],0x795f6f44
0x080485b6 <+27>: mov DWORD PTR [ebp-0x3a],0x6b5f756f
0x080485bd <+34>: mov DWORD PTR [ebp-0x36],0x5f776f6e
0x080485c4 <+41>: mov DWORD PTR [ebp-0x32],0x5f796877
0x080485cb <+48>: mov DWORD PTR [ebp-0x2e],0x745f796d
0x080485d2 <+55>: mov DWORD PTR [ebp-0x2a],0x6d6d6165
0x080485d9 <+62>: mov DWORD PTR [ebp-0x26],0x5f657461
0x080485e0 <+69>: mov DWORD PTR [ebp-0x22],0x6e61724f
0x080485e7 <+76>: mov DWORD PTR [ebp-0x1e],0x695f6567
0x080485ee <+83>: mov DWORD PTR [ebp-0x1a],0x6f735f73
0x080485f5 <+90>: mov DWORD PTR [ebp-0x16],0x676e615f
0x080485fc <+97>: mov DWORD PTR [ebp-0x12],0x3f3f7972
0x08048603 <+104>: mov WORD PTR [ebp-0xe],0x3f
0x08048609 <+110>: mov BYTE PTR [ebp-0x6f],0x7
0x0804860d <+114>: mov BYTE PTR [ebp-0x6e],0x3b
0x08048611 <+118>: mov BYTE PTR [ebp-0x6d],0x19
0x08048615 <+122>: mov BYTE PTR [ebp-0x6c],0x2
0x08048619 <+126>: mov BYTE PTR [ebp-0x6b],0xb
0x0804861d <+130>: mov BYTE PTR [ebp-0x6a],0x10
0x08048621 <+134>: mov BYTE PTR [ebp-0x69],0x3d
0x08048625 <+138>: mov BYTE PTR [ebp-0x68],0x1e
0x08048629 <+142>: mov BYTE PTR [ebp-0x67],0x9
0x0804862d <+146>: mov BYTE PTR [ebp-0x66],0x8
0x08048631 <+150>: mov BYTE PTR [ebp-0x65],0x12
0x08048635 <+154>: mov BYTE PTR [ebp-0x64],0x2d
0x08048639 <+158>: mov BYTE PTR [ebp-0x63],0x28
0x0804863d <+162>: mov BYTE PTR [ebp-0x62],0x59
0x08048641 <+166>: mov BYTE PTR [ebp-0x61],0xa
0x08048645 <+170>: mov BYTE PTR [ebp-0x60],0x0
0x08048649 <+174>: mov BYTE PTR [ebp-0x5f],0x1e
0x0804864d <+178>: mov BYTE PTR [ebp-0x5e],0x16
0x08048651 <+182>: mov BYTE PTR [ebp-0x5d],0x0
0x08048655 <+186>: mov BYTE PTR [ebp-0x5c],0x4
0x08048659 <+190>: mov BYTE PTR [ebp-0x5b],0x55
0x0804865d <+194>: mov BYTE PTR [ebp-0x5a],0x16
0x08048661 <+198>: mov BYTE PTR [ebp-0x59],0x8
0x08048665 <+202>: mov BYTE PTR [ebp-0x58],0x1f
0x08048669 <+206>: mov BYTE PTR [ebp-0x57],0x7
0x0804866d <+210>: mov BYTE PTR [ebp-0x56],0x1
0x08048671 <+214>: mov BYTE PTR [ebp-0x55],0x9
0x08048675 <+218>: mov BYTE PTR [ebp-0x54],0x0
0x08048679 <+222>: mov BYTE PTR [ebp-0x53],0x7e
0x0804867d <+226>: mov BYTE PTR [ebp-0x52],0x1c
0x08048681 <+230>: mov BYTE PTR [ebp-0x51],0x3e
0x08048685 <+234>: mov BYTE PTR [ebp-0x50],0xa
0x08048689 <+238>: mov BYTE PTR [ebp-0x4f],0x1e
0x0804868d <+242>: mov BYTE PTR [ebp-0x4e],0xb
0x08048691 <+246>: mov BYTE PTR [ebp-0x4d],0x6b
0x08048695 <+250>: mov BYTE PTR [ebp-0x4c],0x4
0x08048699 <+254>: mov BYTE PTR [ebp-0x4b],0x42
0x0804869d <+258>: mov BYTE PTR [ebp-0x4a],0x3c
0x080486a1 <+262>: mov BYTE PTR [ebp-0x49],0x2c
0x080486a5 <+266>: mov BYTE PTR [ebp-0x48],0x5b
0x080486a9 <+270>: mov BYTE PTR [ebp-0x47],0x31
0x080486ad <+274>: mov BYTE PTR [ebp-0x46],0x55
0x080486b1 <+278>: mov BYTE PTR [ebp-0x45],0x2
0x080486b5 <+282>: mov BYTE PTR [ebp-0x44],0x1e
0x080486b9 <+286>: mov BYTE PTR [ebp-0x43],0x21
0x080486bd <+290>: mov BYTE PTR [ebp-0x42],0x10
0x080486c1 <+294>: mov BYTE PTR [ebp-0x41],0x4c
0x080486c5 <+298>: mov BYTE PTR [ebp-0x40],0x1e
0x080486c9 <+302>: mov BYTE PTR [ebp-0x3f],0x42
0x080486cd <+306>: sub esp,0x8
0x080486d0 <+309>: push 0x0
0x080486d2 <+311>: push 0x8048830
0x080486d7 <+316>: call 0x8048440 <open@plt>
0x080486dc <+321>: add esp,0x10
0x080486df <+324>: mov DWORD PTR [ebp-0x74],eax
0x080486e2 <+327>: sub esp,0x4
0x080486e5 <+330>: push 0x4
0x080486e7 <+332>: lea eax,[ebp-0x80]
0x080486ea <+335>: push eax
0x080486eb <+336>: push DWORD PTR [ebp-0x74]
0x080486ee <+339>: call 0x8048410 <read@plt>
0x080486f3 <+344>: add esp,0x10
0x080486f6 <+347>: sub esp,0xc
0x080486f9 <+350>: push 0x804883d
0x080486fe <+355>: call 0x8048420 <printf@plt>
0x08048703 <+360>: add esp,0x10
0x08048706 <+363>: sub esp,0x8
0x08048709 <+366>: lea eax,[ebp-0x7c]
0x0804870c <+369>: push eax
0x0804870d <+370>: push 0x804884d
0x08048712 <+375>: call 0x8048480 <__isoc99_scanf@plt>
0x08048717 <+380>: add esp,0x10
0x0804871a <+383>: mov edx,DWORD PTR [ebp-0x80]
0x0804871d <+386>: mov eax,DWORD PTR [ebp-0x7c]
0x08048720 <+389>: cmp edx,eax
0x08048722 <+391>: jne 0x8048760 <get_flag+453>
0x08048724 <+393>: mov DWORD PTR [ebp-0x78],0x0
0x0804872b <+400>: jmp 0x8048758 <get_flag+445>
0x0804872d <+402>: lea edx,[ebp-0x6f]
0x08048730 <+405>: mov eax,DWORD PTR [ebp-0x78]
0x08048733 <+408>: add eax,edx
0x08048735 <+410>: movzx ecx,BYTE PTR [eax]
0x08048738 <+413>: lea edx,[ebp-0x3e]
0x0804873b <+416>: mov eax,DWORD PTR [ebp-0x78]
0x0804873e <+419>: add eax,edx
0x08048740 <+421>: movzx eax,BYTE PTR [eax]
0x08048743 <+424>: xor eax,ecx
0x08048745 <+426>: movsx eax,al
0x08048748 <+429>: sub esp,0xc
0x0804874b <+432>: push eax
0x0804874c <+433>: call 0x8048470 <putchar@plt>
0x08048751 <+438>: add esp,0x10
0x08048754 <+441>: add DWORD PTR [ebp-0x78],0x1
0x08048758 <+445>: mov eax,DWORD PTR [ebp-0x78]
0x0804875b <+448>: cmp eax,0x30
0x0804875e <+451>: jbe 0x804872d <get_flag+402>
0x08048760 <+453>: nop
0x08048761 <+454>: mov eax,DWORD PTR [ebp-0xc]
0x08048764 <+457>: xor eax,DWORD PTR gs:0x14
0x0804876b <+464>: je 0x8048772 <get_flag+471>
0x0804876d <+466>: call 0x8048430 <__stack_chk_fail@plt>
0x08048772 <+471>: leave
0x08048773 <+472>: ret
End of assembler dump.
코드가 굉장히 길지만 눈길을 끄는 녀석들만 골라서 추측해보자면 open함수로 뭘 열고 read로 뭘 읽고 scanf로 뭘 입력 받고 입력받은 값과 읽은 값을 비교(+375~+389)하는것 같습니다. 일단 제 추측이 맞는지 확인부터 해봅니다. 제대로 된 분석은 제 추측이 틀렸다는게 밝혀진 뒤에 해도 늦지 않습니다.
open 함수로 /dev/urandom 이라는 파일을 엽니다. 저 파일은 랜덤한 값들을 만들어주는 파일로 열어보시면 아래와 같은 값을 볼 수 있습니다. 아래는 편의를 위해 길이 제한을 걸어서 그렇지 만약 길이 제한 옵션이 없다면 사용자가 멈추기 전까지 무한으로 뽑아냅니다.
여기선 read 함수로 무엇인가를 하는 것을 확인할 수 있는데 read 함수에 대해 잘 모르시는 분들을 위해 간단하게 설명하고 넘어가겠습니다. 일단 기본적인 read 함수에서 사용하는 인자값들은 아래와 같습니다.
fd, *buf, count 3가지 인자값이 있는데 fd는 file descriptor를 뜻합니다. 이에 대한건 file descriptor를 검색하시면 더 자세한 내용이 나오는데 아주아주 간단하게 말씀드리자면 fd값은 0 -> stdin(표준 입력) / 1 -> stdout(표준 출력) / 2 -> stderr(표준 에러) 로 정해져 있고 실제 파일의 경우는 3번부터 부여됩니다. 위에서 open을 이용해 하나의 파일을 열었으니 fd가 3이 되고 이를 다시 정리하자면 위에서 열었던 '/dev/urandom' 파일에서 4바이트 만큼 값을 읽어서 0xffffd088 위치에 넣어준다는 뜻입니다.
위에서 확인할 수 있듯이 0xffffd088이라는 곳에 0x8a1f2559라는 값이 들어갔습니다.
그리고 제가 입력한 256이라는 값이 16진수로 EAX에 들어간 것을 확인할 수 있고 cmp를 통해 EDX에 있는 값(위에서 read를 통해 넣어준 값)과 비교해 분기를 결정합니다. 결국 랜덤한 4바이트 값을 맞춰서 입력해주면 풀리는 문제!
'Pwnable > HITCON Training' 카테고리의 다른 글
[HITCON Training] LAB3 ret2sc (0) | 2019.08.12 |
---|