2012-06-17 3 views
6

스택 오버플로 예제를 사용하고 있습니다. 이 예는 다음과 같습니다.딜레마 (버퍼 오버플로 포함)

void return_input (void){ 
    char array[30];  
    gets (array); 
    printf("%s\n", array); 

} 

main() { 
    return_input();  
    return 0;  
} 

이 코드는 모두 overflow.c라는 파일에 있습니다. return_input이라는 취약한 함수가 있는데, 특히 30 바이트 문자 배열입니다. I 출력 다음 그것을 컴파일 GDB에 취약한 함수를 열고있어 :

(gdb) disas return_input 
0x08048464 <+0>: push %ebp 
0x08048465 <+1>: mov %esp,%ebp 
0x08048467 <+3>: sub $0x48,%esp 
0x0804846a <+6>: mov %gs:0x14,%eax 
0x08048470 <+12>: mov %eax,-0xc(%ebp) 
0x08048473 <+15>: xor %eax,%eax 
0x08048475 <+17>: lea -0x2a(%ebp),%eax 
0x08048478 <+20>: mov %eax,(%esp) 
0x0804847b <+23>: call 0x8048360 <[email protected]> 
0x08048480 <+28>: lea -0x2a(%ebp),%eax 
0x08048483 <+31>: mov %eax,(%esp) 
0x08048486 <+34>: call 0x8048380 <[email protected]> 
0x0804848b <+39>: mov -0xc(%ebp),%eax 
0x0804848e <+42>: xor %gs:0x14,%eax 
0x08048495 <+49>: je  0x804849c <return_input+56> 
0x08048497 <+51>: call 0x8048370 <[email protected]> 
0x0804849c <+56>: leave 
0x0804849d <+57>: ret  
End of assembler dump. 

우리가 hex48 예약 기능 프롤로그 (DEC 72)에서 보듯이 지역 변수에 대한 스택에 바이트. 우선 취약한 배열이 스택에서 시작되는 주소를 찾으려고했습니다. 나는 그것이 -0x2a (% ebp)라고 생각한다. 맞습니까? Hex2a는 십진수 42입니다. 이해할 수 있듯이 스택에 저장된 EBP를 덮어 쓰기 시작하기 전에 42 바이트를 안전하게 쓸 수 있음을 의미합니다.

[email protected]:~/temp/ELF_reader$ ./overflow 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
Segmentation fault (core dumped) 

어떻게 충분히 37 바이트 버퍼 오버 플로우하는 것입니다 :이 예제를 실행하지만 그것은 세그먼트 오류를 ​​얻을 오른쪽에만 37 바이트로 충분하다? 로컬 char 배열이 저장된 EBP에서 -42 바이트 인 경우

+0

관련이 없지만 [이 질문] (http://stackoverflow.com/questions/9249315/what-is-gs-in-assembly)은 * 매우 유사합니다. – huon

+0

C에서 30 바이트 배열에 31 바이트를 쓰면 해당 배열을 오버플로하기에 충분하며 (정의되지 않은 동작이 발생합니다). – pmg

답변

6

함수의 전체 디스 어셈블리를 보지 않고도 말하기 어렵습니다.

그러나 내 생각에 스택 보정이 감지되면 깨끗한 종료를 유발하는 032c (% ebp)에 저장된 % gs : 0x14가 stack canary 일 수 있습니다. 그래서이 값은 -0xc (% ebp)에 저장됩니다. 즉, 버퍼가 실제로는 30 바이트 만 커야하고 이후에 오는 값이옵니다.

+0

감사합니다. gcc 스택 보호없이 다시 컴파일하면 어셈블리 코드가 모든 값을 올바르게 제공합니다. –

관련 문제