문서의 임의 삭제는 제재 대상으로, 문서를 삭제하려면 삭제 토론을 진행해야 합니다. 문서 보기문서 삭제토론 버퍼 오버플로 (문서 편집) [include(틀:다른 뜻1, other1=프로그래밍 관련 질의 응답 사이트, rd1=Stack Overflow)] [목차] == 개요 == '''{{{+1 Buffer Overflow}}}''' [[버그]]의 일종. 또는 이를 이용한 공격 방법. [[프로그램]]이 실행될 때 입력받는 값이 [[버퍼]]를 가득 채우다 못해 넘쳐흘러 버퍼 이후의 공간을 침범하는 현상. 쉽게 말해 양동이(버퍼)에 물(값)을 받을 때(입력 받기) 물을 너무 많이 받아 바닥에 흘러 넘쳐버리는 것이라고 생각하면 된다. 주로 [[프로그램]]이 사용자에게 데이터(주로 [[문자|문자열]])을 입력받을 때 사용자가 말을 곧이곧대로 듣지 않고 이미 준비된 버퍼보다 더 많은 양의 데이터를 입력할 때 발생하나, [[해커]]가 임의로 [[프로그램]]의 [[메모리]]의 값을(주로 [[스택]]) 변조할 때에도 쓰인다.[* 이를 임의 코드 실행이라고 하며, 고전 게임 등지에서 버그를 통해 메모리 값을 변조시키는 행위를 할 때도 이 용어를 사용한다.] 주로 이 문제는 스택에서 발생하기 때문에 '스택 오버플로(Stack Overflow)'라고도 부른다. == 왜 문제가 되는가 == 버퍼 오버플로가 발생 시[* 버퍼 오버플로 공격은 C와 같은 프로그래밍 언어에서 strcpy(문자열복사) 등 문자열에 관련된 함수가 경계조건을 검사하지 않기 때문에 발생한다.] [[버퍼]]에 다 담지 못한 값들은 [[버퍼]] 이후의 공간에 들어차게 된다. 문제는 이 들어차는 방식이 밀어내기가 아닌 '''덮어쓰기'''라는 것. 가령 8칸짜리 [[메모리]]가 있고, 그 안에 4칸짜리 [[버퍼]]가 있을 때, [[파일:attachment/buffer_overflow.png|width=300]] 이와 같이 사용자가 [[버퍼]]를 초과하는 값을 입력하면 [[버퍼]] 이후의 값이 바뀌게 된다. 문제는 이걸 프로그램은 '''전혀 모르고 있는 상태'''라는 것.[* 물론 이는 과거 로우 레벨까지 [[프로그래머]]가 [[C언어|세세하게 코딩해야 됐었던 때]]의 이야기고, 요즘은 디버깅시 컴파일러가 버퍼 앞뒤에 오버플로우 방어용 1~4바이트짜리 값을 넣어 (카나리 라고 한다. 어원은 [[카나리아(조류)]] 문서 참조) 침범되었을 경우 [[예외 처리|예외]]를 때려버리거나 코딩 단계에서 '이 함수는 버퍼 오버플로의 위험이 있음' 이라고 경고를 해준다. 물론 이 현상이 사라진건 아니므로 [[프로그래머]]는 여전히 버퍼에 들어가는 값을 체크 해야 된다.] 심지어 버퍼 이후의 값이 바뀌어도 프로그램은 이를 전혀 사용자에게 통지하지 않는다! 중요하지 않은 10줄~50줄짜리 소규모 예제 [[프로그램]]이라면 이는 딱히 신경쓰지 않아도 되지만, 중형이나 대규모 프로젝트라면 이야기가 달라진다. 이 원리를 통해 '''[[해킹]]이 가능하기 때문.''' 간단한 예를 들자면 10자리 비밀번호를 치고 들어가는 시스템이 있다고 하자. 그리고 비밀번호를 저장하는 값 바로 뒤에 로그인 여부를 묻는 값이 있다고 하자.(0=실패, 이외의 값=성공) 이 상황에서, 끝자리가 0이 아닌 11자리 비밀번호를 입력하면 틀리더라도 뚫을 수 있게 된다! 만약 버퍼를 초과하여 쓰여지는 값이 [[프로그램]]의 RETN[* 현재 함수의 실행이 끝나면 호출 스택을 타고 상위 함수로 올라가는데, 이때 쓰이는 값]값을 덮어쓰게 된다면, 사용자가 프로그램의 진행 상황을 통제할 수 있게 된다. 만약 특정한 [[함수]]가 있고, 이 [[함수]]의 주솟값을 알고 어떤 입력이 버퍼 오버플로 공격이 가능하다면, 그냥 '입력받는 문자열 + 4[* 32비트 프로그램일 경우]/8[* 64비트 프로그램일 경우]바이트(SFP 덮어쓰기용) + 해당 함수 주소'를 입력값에 쑤셔넣어 입력 함수가 끝나면 자신이 원하는 함수로 점프할 수가 있게 된다. 가장 유명한 사례로는 [[하트블리드 사태]]와 스타크래프트 1의 [[EUD]]가 있다. == 대처법 == 요즘은 컴파일러 레벨에서 이 오버플로에 대한 처리를 다 해준다. [[Visual Studio]] 같은 경우에는 컴파일러가 버퍼 생성시 앞뒤로 2바이트짜리 영역을 만들어 [[디버깅]]시 이 위치의 값이 바뀌면 버퍼 오버플로가 발생한 것으로 판단하고 [[예외 처리|예외]]를 때려 버리며, 아예 버퍼 오버플로가 발생하기 쉬운 함수(strcpy 등)는 이를 방어 가능한 함수(strcpy_s 등)으로 교체하라고 경고[* VS 2013부터 경고(warning)에서 에러(error)로 변경되어서 컴파일이 안 된다. 설정을 통해 다시 경고 수준으로 바꾸거나, {{{#define _CRT_SECURE_NO_WARNINGS}}} 구문을 소소코드의 맨 위에 넣어주면 된다.]를 해준다. 물론 이렇게 다 해준다고 마냥 안심하고 있긴 어려운 것이, 버퍼 오버플로는 [[프로그램]]이 Input을 받는 모든 곳에서 발생할 수 있으므로 [[프로그래머]]도 값을 입력받을 때 갖가지 예외 처리를 통해[* 가령 main 함수의 argv 문자열 값으로 넘어오는 값이 버퍼를 초과할 수 있으므로 int형 변수를 먼저 선언하고 다른 변수를 선언해 argv-int-다른 변수 순으로 쌓이는 스택의 특성을 이용하여 int형 변수의 값이 바뀌면 이를 버퍼 오버플로라 판단해 차단해버리는 스택 가드 기법이 있다.] 이 값이 과연 올바른 값인지 꼼꼼히 따져봐야 한다. == 관련 문서 == * [[오버플로]] [[분류:해킹/기법]][[분류:버그]] 스택과 힙이 있다. * [[버퍼 오버플로/스택]]저장 버튼을 클릭하면 당신이 기여한 내용을 CC-BY-NC-SA 2.0 KR으로 배포하고,기여한 문서에 대한 하이퍼링크나 URL을 이용하여 저작자 표시를 하는 것으로 충분하다는 데 동의하는 것입니다.이 동의는 철회할 수 없습니다.캡챠저장미리보기