본문 바로가기
스터디/system

[GDB-Analysis] GDB 바이너리 디버깅 2

by 깝태 2011. 8. 17.

이번에는 버퍼 오버플로우 취약점으로 자주 등장하는 strcpy 함수를 디버깅 해보겠습니다.
너무 쉬워보일수도 있겠지만 모든것들이 패턴이 있습니다. 함수가 호출되기전에 어떻게 인자를
참조하는지 이 작업은 무엇을 의미하는지, 저 또한 공부한지 별로 안됬지만 조금 알것같습니다.
이런 밑거름들을 차근차근 해나가다가 나중에는 워게임 하나를 디버깅해 취약점을 찾아낸다는지..
가능할겁니다.

[gate@localhost tmp]$ cat t2.c

int main(int argc, char *argv[])
{
    char buffer[40];

    strcpy(buffer, argv[1]); // argv[1] 을 buffer 에 복사합니다.
    printf("%s\n", buffer); // 복사된 buffer 을 출력합니다.
}

[gate@localhost tmp]$ ./t2 buffer
buffer

고로 인자로 전달해주는 값에 따라 출력되어지는 값도 달라질겁니다.

[gate@localhost tmp]$ gdb -q t2
(gdb) disas main
Dump of assembler code for function main:
0x80483f8 <main>:       push   %ebp
0x80483f9 <main+1>:     mov    %esp,%ebp // 프롤로그

0x80483fb <main+3>:     sub    $0x28,%esp // 변수 40바이트 선언

0x80483fe <main+6>:     mov    0xc(%ebp),%eax // EAX 에 (EBP+12) 의 값을 복사한다. - (EBP+12) == Argv[0]
0x8048401 <main+9>:     add    $0x4,%eax // EAX+4 - Argv[0] + 4 == Argv[1]
0x8048404 <main+12>:    mov    (%eax),%edx // EDX 에 EAX 의 값을 복사한다.
0x8048406 <main+14>:    push   %edx // EDX푸시
0x8048407 <main+15>:    lea    0xffffffd8(%ebp),%eax // EAX 에 (EBP-40) 의 값을 복사한다.
0x804840a <main+18>:    push   %eax // EAX 푸시
0x804840b <main+19>:    call   0x8048340 <strcpy>
/*
strcpy(buffer, argv[1]); 호출작업입니다.
Argv[1] 을 푸시하기위해 EAX(Argv[0]) 에 +4 를 하고 EDX 에 옮긴 후 푸시했으며
Buffer 를 인자로 가져오기 위해 (EBP-40) 주소 값(Buffer 의 주소값) 을 참조합니다.
아마 EBP 는 현재 아무런 움직임을 가지지 않았으며 꼭대기에 그대로 있나봅니다.
*/
0x8048410 <main+24>:    add    $0x8,%esp // ESP + 8
0x8048413 <main+27>:    lea    0xffffffd8(%ebp),%eax // EAX 에 (EBP-40) 주소 값을 복사합니다.
0x8048416 <main+30>:    push   %eax // EAX 를 푸시합니다.
0x8048417 <main+31>:    push   $0x8048480 // "%s\n" 을 푸시합니다.
// 0x8048480 <_IO_stdin_used+4>:    "%s\n"
0x804841c <main+36>:    call   0x8048330 <printf>
// printf("%s\n", buffer);
0x8048421 <main+41>:    add    $0x8,%esp
0x8048424 <main+44>:    leave
0x8048425 <main+45>:    ret
/* 생략 */
End of assembler dump.

(gdb) b *main+19
Breakpoint 2 at 0x804840b
(gdb) r aaaa
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/gate/xodnr/tmp/t2 aaaa

Breakpoint 2, 0x804840b in main ()

(gdb) x/s $edx
0xbffffcaf:      "aaaa" // 우리가 입력해주었던 Argv[1] 이 존재합니다

두 번째로 Buffer 의 주소값을 참조하는 과정입니다.

(gdb) b *main+19
Breakpoint 5 at 0x804840b
(gdb) r aaaa
The program being debugged has been started already.
Start it from the beginning? (y or n)
Please answer y or n.
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/gate/xodnr/tmp/t2 aaaa

Breakpoint 4, 0x804840a in main ()

(gdb) x/s $ebp-40
0xbffffb40:      "hûÿ¿p©"
(gdb) x/s $eax
0xbffffb40:      "hûÿ¿p©" // 서로 같습니다.

이로써 이번 문제의 분석과정은 끝났습니다.
복사해야할 것을 먼저 푸시하고 붙여줘야되는곳을 푸시했습니다.

소스가 짧아서 그런건지 매우 쉬웠습니다.