버퍼 오버플로우란?
버퍼 오버플로우 : 메모리에 할당된 버퍼의 양을 초과하는 데이터를 입력하여 프로그램의 복귀 주소(return address)를 조작하는 공격
버퍼(buffer) : 프로그램 처리 과정에 필요한 데이터가 일시적으로 저장되는 공간
메모리의 스택(stack) 영역과 힙(heap) 영역이 버퍼에 속하며 스택 오버플로우와 힙 오버플로우로 나누어진다.

하나의 프로그램은 수많은 서브 루틴들로 구성되는데 이런 서브 루틴이 프로그램에 의해 호출될 때, 함수 변수와 서브 루틴의 복귀 주소(return address) 포인터를 스택(stack)이라는 논리적 데이터 구조에 저장하게 된다. 스택은 실행중인 프로그램이 필요로 하는 정보를 저장하는 메모리 영역이다. 서브 루틴이 종료될 때 운영체제는 그것을 호출한 프로그램에 제어권을 반환해야 하기 때문에, 복귀 포인터를 통해서 프로그램이 서브 루틴의 실행을 마치고 나서 되돌아갈 주소를 가리키게 된다.
버퍼는 할당된 메모리 공간의 높은 주소에서 낮은 주소로 채워지며, 스택 영역에 마지막으로 들어가 데이터가 제일 먼저 빠져 나오는 LIFO(Last in, First out) 특정을 가지고 있다. 이런 LIFO 특성에 의해 가장 먼저 들어가 것(복귀 포인터)이 스택에서 가장 나중에 제거된다는 것을 기억해야 한다. 서브 루틴이 실행을 마치면 가장 나중에 행해지는 것은 복귀 포인터를 스택에서 제거하여 서브 루틴을 호출한 함수로 반환하는 것인데, 만약 이 포인터가 사용되지 않는다면 서브 루틴이 실행을 마쳤을 때 프로그램은 더 이상 어디로 진행해야 할지를 알 수 없을 것이다. 포인터(pointer)는 메모리의 위치를 저장하는 변수이다. 프로그램 실행을 위한 목적으로 다른 코드로 이동할 때 어디에서 떠났는지를 기억하기 위해 포인터를 사용해야 하며, 만약 포인터를 사용하지 않는다면 서브 루틴의 실행이 끝나고 어디로 돌아와야 할지를 알 수 없을 것이다.
프로그램이 변수의 할당된 공간에 저장될 데이터의 크기를 검사하지 않고 크기에 제한을 두지 않는다면, 변수 공간은 넘치게 될 것이다. 즉, 버퍼에 오버플로우가 발생하면 저장된 데이터는 인접한 변수 영역도 침범할 것이며 결국에는 포인터 영역까지 침범하게 될 것이다. 해커는 이러한 데이터의 길이와 내용을 적절히 조정함으로써 버퍼 오버플로우를 일으키고 운영체제의 스택을 붕괴시켜 특정 코드가 실행되도록 한다.
해커가 보낸 데이터는 대개의 경우 특정 시스템에서 실행될 수 있는 기계어 코드와 복귀 포인터에 저장될 새로운 주소로 구성되어 있으며, 복귀 포인터에 저장될 새로운 주소는 다시 메모리의 스택 영역을 가리켜서 프로그램이 서브 루틴에서 반환될 때 해커가 작성한 명령어를 실행하게 된다.
버퍼 오버플로우 점검
점검 내용 | 사용자가 입력한 파라미터 값의 문자열 길이 제한 확인 |
점검 목적 | 웹 사이트에서 사용자가 입력한 파라미터 값의 문자열 길이 제한 여부를 점검하여 비정상적 오류 발생을 차단하기 위함 |
점검 대상 | 웹 애플리케이션 소스코드 |
1. 로그인 페이지에서 계정 정보 입력 시 대량의 문자열을 입력하여 에러 페이지나 오류가 발생하는지 점검

무작위의 문자열을 입력한 뒤 로그인을 시도해 보았다.

에러 페이지나 오류가 발생하지 않는다.
2. 로그인 후 정보변경 페이지에서 가입 정보 수정 시 대량의 문자열을 입력하여 에러 페이지나 오류가 발생하는지 점검

E-mail 항목에 대량의 문자열을 입력했다.

에러 페이지나 오류가 발생하지 않는다.
3. 검색어 입력 시 대량의 문자열을 입력하여 에러 페이지나 오류가 발생하는지 점검

게시글 검색어 입력 칸에 대량의 문자열을 입력해 보았다.

에러가 발생하지 않았으나 # 이후의 특수문자가 생략된 것을 확인할 수 있었다.
4. 게시글 작성 시 대량의 문자열을 입력하여 에러 페이지나 오류가 발생하는지 점검

게시글의 제목과 내용에 대량의 문자열을 입력하여 작성하였다.

에러 페이지나 오류가 발생하지 않았다.
5. URL 파라미터 값에 대량의 문자열 입력 시 에러 페이지나 오류가 발생하는지 점검

URL 파라미터 값에 대량의 문자열을 입력해 보았다.

에러 페이지나 오류가 발생하지 않고 기존 페이지가 유지되었다.
보안 설정 방법
- 웹 서버, 웹 애플리케이션 서버 버전을 안정성이 검증된 최신 버전으로 패치한다.
- 웹 애플리케이션에 전달되는 파라미터 값을 필요한 크기만큼만 받을 수 있도록 변경하고 입력 값 범위를 초과한 경우에도 에러 페이지를 반환하지 않도록 설정한다.
- 동적 메모리 할당을 위해 크기를 사용하는 경우 그 값이 음수가 아닌지 검사하여 버퍼 오버플로우를 예방하는 형태로 소스 코드 변경한다.
- 버퍼 오버플로우를 점검하는 웹 스캐닝 툴을 이용하여 주기적으로 점검한다.
코드 예제
다음의 예제는 외부의 입력(args[0], args[1])을 이용하여 동적으로 계산한 값을 배열의 크기 (size)를 결정하는데 사용되어, 외부 입력으로부터 계산된 값(size)이 오버플로우에 의해 음수값이 되면 배열의 크기가 음수가 되어 시스템 에 문제가 발생될 수 있는 코딩이다.
......
public static void main(String[] args)
{
int size = new Integer(args[0]).intValue();
size += new Integer(args[1]).intValue();
MyClass[] data = new MyClass[size];
......
동적 메모리 할당을 위해 크기를 사용하는 경우 그 값이 음수가 아닌지 검사하여 버퍼오버플로우를 예방하는 형태로 코딩하는 것이 바람직하다.
......
public static void main(String[] args)
{
int size = new Integer(args[0]).intValue();
size += new Integer(args[1]).intValue();
// 배열의 크기 값이 음수값이 아닌지 검사한다.
if (size < 0) return ;
MyClass[] data = new MyClass[size];
......
참고자료
주요정보통신기반시설 기술적 취약점 분석 평가 방법 상세가이드(2021)
웹서버 및 홈페이지 취약점점검 가이드(2014)
[해킹 기법] ② 버퍼 오버플로우(Buffer overflow)
https://www.ahnlab.com/kr/site/securityinfo/secunews/secuNewsView.do?seq=4462
[해킹 기법] ② 버퍼 오버플로우(Buffer overflow)
보안에 관심 있는 사람이라면 "버퍼 오버플로우"란 용어가 낯설지 않을 것이며, 그 중 적극적인 관리자라면 인터..
www.ahnlab.com