Buffer: 두 판 사이의 차이

youngwiki
21번째 줄: 21번째 줄:
}
}
</syntaxhighlight>
</syntaxhighlight>
[[파일:Stack Frame Layout.png|대체글=Figure 1. Stack Frame Layout|섬네일|'''Figure 1. Stack Frame Layout''' ]]
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
jschoi@ubuntu:~$ ./bof
jschoi@ubuntu:~$ ./bof
38번째 줄: 37번째 줄:
Segmentation fault
Segmentation fault
</syntaxhighlight>
</syntaxhighlight>
위 코드에서 <code>gets(buf)</code>는 입력 크기를 검사하지 않으므로, 8바이트 초과 입력 시 버퍼를 넘쳐서 다른 데이터를 덮어 쓴다. 이때, 동일하게 8바이트 버퍼를 초과한 입력 "0123456789ABCDE"은 괜찮고, "0123456789ABCDEF"에서 비로소 오류가 생기는 이유는 아래 어셈블리 코드를 관찰하여 알 수 있다.
위 코드에서 <code>gets(buf)</code>는 입력 크기를 검사하지 않으므로, 8바이트 초과 입력 시 버퍼를 넘쳐서 다른 데이터를 덮어 쓴다. 이때, 동일하게 8바이트 버퍼를 초과한 입력 "0123456789ABCDE"은 괜찮고, "0123456789ABCDEF"에서 비로소 오류가 생기는 이유는 아래 어셈블리 코드를 관찰하여 알 수 있다:
[[파일:Stack Frame Layout.png|대체글=Figure 1. Stack Frame Layout|섬네일|'''Figure 1. Stack Frame Layout''' ]]
<syntaxhighlight lang="c">
(gdb) disassemble echo
0x401136: sub    $0x18,%rsp
0x40113a: lea    0x8(%rsp),%rdi
0x40113f: mov    $0x0,%eax
0x401144: call  0x401040 <gets@plt>
0x401149: lea    0x8(%rsp),%rdi
0x40114e: call  0x401030 <puts@plt>
0x401153: add    $0x18,%rsp
0x401157: ret   
 
(gdb) disassemble main
0x401158: sub    $0x8,%rsp
0x40115c: call  0x401136 <echo>
0x401161: mov    $0x0,%eax
0x401166: add    $0x8,%rsp
0x40116a: ret   
</syntaxhighlight>
이때 해당 코드는 figure 1과 같이 스택 프레임을 형성한다.


==각주==
==각주==
[[분류:컴퓨터 시스템]]
[[분류:컴퓨터 시스템]]

2025년 5월 20일 (화) 00:32 판

상위 문서: 컴퓨터 시스템

개요

버퍼(Buffer)란 데이터를 임시로 저장하는 배열이다. 예를 들면, 동영상 스트리밍 시, 끊김없는 재생을 위해서 일부 데이터를 저장하는 경우가 있으며, 이를 비디오 버퍼링(vedio buffering)이라고 한다. C언어에서는 보통 char buf[256];과 같이 선언되는 문자 배열을 의미하며, 사용자의 입력 문자열을 저장하는데 자주 사용된다.

Classic Buffer Overflow

스택 기반 오버플로우(Stack-based buffer overflow)란 스택 메모리에 존재하는 버퍼에 데이터가 초과되어 쓰이면서, 다른 메모리 영역까지 덮어쓰는 오류이다.[1] 해당 오류의 주된 원인은 gets(), scanf("%s"), strcpy(), strcat()와 같은 함수들을 배열 크기를 고려하기 않고 사용하는 것이다. 해당 오류는 해커가 이를 이용해 시스템을 공격하거나 악성코드를 주입할 수 있어서 보안상 매우 위험하다.

Example Program with BOF

아래는 스택 기반 오버플로우 오류가 발생할 수 있는 C언어 코드의 예시이다:

void echo(void) {
    char buf[8];
    gets(buf); //Never use this function. 너무 많은 BOF의 원인
    puts(buf);
}

int main(void) {
    echo();
    return 0;
}
jschoi@ubuntu:~$ ./bof
Hello
Hello
jschoi@ubuntu:~$ ./bof 
0123456789ABCDE 
0123456789ABCDE
jschoi@ubuntu:~$ ./bof
0123456789ABCDEF
0123456789ABCDEF
Segmentation fault

위 코드에서 gets(buf)는 입력 크기를 검사하지 않으므로, 8바이트 초과 입력 시 버퍼를 넘쳐서 다른 데이터를 덮어 쓴다. 이때, 동일하게 8바이트 버퍼를 초과한 입력 "0123456789ABCDE"은 괜찮고, "0123456789ABCDEF"에서 비로소 오류가 생기는 이유는 아래 어셈블리 코드를 관찰하여 알 수 있다:

Figure 1. Stack Frame Layout
Figure 1. Stack Frame Layout
(gdb) disassemble echo
0x401136:	sub    $0x18,%rsp
0x40113a:	lea    0x8(%rsp),%rdi
0x40113f:	mov    $0x0,%eax
0x401144:	call   0x401040 <gets@plt>
0x401149:	lea    0x8(%rsp),%rdi
0x40114e:	call   0x401030 <puts@plt>
0x401153:	add    $0x18,%rsp
0x401157:	ret    

(gdb) disassemble main
0x401158:	sub    $0x8,%rsp
0x40115c:	call   0x401136 <echo>
0x401161:	mov    $0x0,%eax
0x401166:	add    $0x8,%rsp
0x40116a:	ret

이때 해당 코드는 figure 1과 같이 스택 프레임을 형성한다.

각주

  1. 이를 stack smashing이라 부르기도 한다.