pwnable.kr (bof)

c0wb3ll ㅣ 2020. 8. 29. 07:56

pwnable.kr (bof)

 

pwnable.kr bof

 

이전까지의 문제들과 달리 이번 접속은 nc를 통해 이루어지며 로컬에서 사용할 파일들을 제공해준다.

 

download bof, bof.c

 

다음과 같이 wget이라는 명령어 뒤에 링크를 붙여주어 다운받을 수 있다.

우선 소스코드를 봐보자.

 

bof.c

 

위에 소스코드에는 취약한 부분이 존재한다.

  • overflow 변수의 크기는 32byte이다.
  • gets 함수에는 입력받는 데이터의 제한이 없다.
  • 따라서 overflow 변수의 32byte가 넘는 데이터를 입력할 수 있다.
  • Buffer OverFlow!!

그럼 이 BOF를 가지고 무엇을 할 수 있냐면 key변수의 값을 덮어쓸 수 있다.

그 뜻은 if 문에 들어가는 key 변수의 값이 deadbeef가 아닌 0xcafebabe가 되게 할 수 있다는 뜻이다.

이렇게 하면 조건문을 통과하여 '/bin/sh'을 실행시킬 수 있을 것이다.

그럼 key변수와 overflow 버퍼의 거리를 재기 위해 메모리를 들여다보자. 나는 gdb-peda를 이용하여 분석하였다.

 

gdb bof - i fu

 

함수목록을 보면 소스코드에 있었던 main 함수와 func함수가 존재하는 것을 알 수 있다. main부분에서는 func함수로 뛰는 부분이 전부일 것이니 바로 func함수를 뒤져보도록 하자.

 

disas func

 

여러가지 함수들을 호출하는데 아직 파일을 실행하지 않아 정확히 어떤 함수들이 불려오는지 알 수가 없다. func함수에다 bp를 걸어주고 실행한 뒤 다시 보도록 하자.

 

disas func - overflow

 

gets함수 부분을 보면 buffer의 시작 위치가 [ebp-0x2c]라는 것을 알 수 있다.

 

disas func - key

 

또한 [ebp+0x8] 위치에서 0xcafebabe와 값이 같은지 확인하고 있다.

따라서 정리해보자면

  • overflow 버퍼의 시작 위치는 [ebp-0x2c]
  • key 버퍼의 시작 위치는 [ebp-0x8]
  • 0x2c + 0x8 만큼의 더미값을 준 뒤 0xcafebabe를 값으로 넘겨주면 조건문을 통과할 수 있다.

익스코드를 짜보자.

from pwn import *

# p = process('./bof')
p = remote('pwnable.kr', 9000)

# p.recvuntil(':')

stackcookie = 0xcafebabe

payload = b'A' * (0x2c + 0x8)
payload += p32(stackcookie)

p.sendline(payload)

p.interactive()

왜인지는 모르겠으나 'overflow me : '라는 문자열이 나오고 입력을 받아야 하는데 nc접속을 해보니 입력을 먼저 받고 'overflow me :' 문자열이 나온 뒤 무한으로 입력을 받는 상태가 되어버렸다;;;

그래서 이에 맞춰 소스코드를 따로 문자열을 받지 않고 그냥 바로 sendline으로 때려버렸더니 풀렸다.

 

flag