자기 메모리의 영역을 넘어 다른 영역까지 넘어가는 현상을 말한다.
오버 플로우가 어떻게 발생하는지 쉽게 확인하기 위해 다음과 같은 프로그램을 만들었다.

소스코드 #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { char bottom[8]; char top[8]; strcpy(top,"top"); strcpy(bottom,"bottom"); printf("top= %s\n",top); printf("bottom= %s\n",bottom); strcpy(top,argv[1]); puts("\n==after=="); printf("after top= %s\n",top); printf("after bottom= %s\n",bottom); } |
소스코드 설명부분 - 씨언어에서 //는 주석을 뜻합니다.
#include <stdio.h>
//화면 입출력을 위한 라인 -
// #include 는 특정함수가 저장되어 있는 파일을
// 로딩하기 위한 명령으로 < >사이에 함수가 정의되어 있는 파일명을 넣으면됨
// stdio는 standard input output의 약자로 화면 입출력을 위한 함수가 들어 있음
#include <string.h>
//문자열 함수 strcpy를 사용하기 위한 라인
int main(int argc, char *argv[])
//씨언어의 시작을 알리는 라인
{
char bottom[8];
//8바이트의 문자를 저장할수 있는 bottom이라는 공간설정
char top[8];
//8바이트의 문자를 저장할수있는 top이라는 공간설정
strcpy(top,"top");
//top공간에 top이라는 문자열을 저장
strcpy(bottom,"bottom");
//bottom공간에 bottom이라는 문자열을 저장
printf("top= %s\n",top);
//top공간에 있는 내용을 화면에 출력
printf("bottom= %s\n",bottom); /
/bottom 공간의 내용을 화면에 출력
strcpy(top,argv[1]);
//프로그램 시작시 새로받은 값을 top이라는 공간에 새로 저장하는 부분
// argv[1]이라는 것은, 프로그램 실행시 프로그램에 넘겨 주는 값으로
// a라는 프로그램에 1000을 넘겨주고 싶을때 명령창에 a 1000이라고 입력하면 된다.
// 그러면 a는 1000을 받아서 프로그램 내부의 정해진 변수로 저장시킨다 여기서는 top로 저장
puts("\n==after==");
//after이라는 글자를 화면에 출력
printf("after top= %s\n",top);
//새로 입력 받은 top공간의 값을 화면에 출력
printf("after bottom= %s\n",bottom);
//bottom이라는 공간의 내용을 화면에 출력
} // 종료를 알리는 라인
위의 소스를 보면 처음에 top과 bottom 이라는 문자열 변수(=변경되는 값을 저장하는 공간)에
각각 top과 bottom이라는 값을 넣고 =>처음 나오는 strcpy부분 2개
프로그램 시작 시 인자값을 받아 그 값으로 top의 내용을 변경시키는 간단한 프로그램이다 -> strcpy(top,argv[1]) 부분
프로그램 시작시 값을 전달받는 법!!
=> 소스코드의 strcpy(top,argv[1]) 부분
argv[1]이라는 것은 프로그램 실행시 프로그램에 값을 넘겨 주는 인자이다
a라는 프로그램에 1000을 넘겨주고 싶을때 명령창에 a 1000이라고 입력하면 된다.
그러면 a는 1000을 받아서 프로그램 내부의 정해진 변수로 저장시킨다, 여기서는 인자값이 top로 저장된다
위 프로그램은 top과 bottom의 값을 두번 출력하는데
처음 출력시는 최초의 top과 bottom값, 두번째는 프로그램 시작시 전달받은 값을 top에 저장한후의 top과 bottom을 출력한다.
이때 8자 이상의 글자를 입력하여 top 메모리영역을 넘치게 하면
top영역을 넘어 bottom의 영역까지 침범하게 되어 bottom의 값이 변경 되는 것을 확인할수 있다.
(7자 이하까지는 top영역을 넘지 않아 기존의 bottom값은 유지됨)
참고로 문자열 변수는 저장하고 싶은 글자수보다 한글자 많은 공간을 할당해야 한다.
이유는 널바이트라고 끝을 알리는 문자가 들어가기 때문이다
여기서는 7글자까지 저장시키기 위해 8바이트를 할당했다.(소스코드의 char top[8]부분)
<정상 메모리상태>
=> ■ 갯수가 top영역안에 있는 상태
메모리상 top영역 ↓ bottom영역↓
■□□□□□□□ □□□□□□□□
■■■□□□□□ □□□□□□□□
■■■■■■■□ □□□□□□□□
<오버플로우상태>
=> top영역을 넘어가는 ■ 을 넣으면 bottom영역으로 넘어가버려 bottom값이 바뀜
메모리상 top영역 ↓ bottom영역↓
■■■■■■■■ ■□□□□□□□
직접 실행해 보면 결과는 다음과 같다.
큰녹색 테두리가 인자를 넣어 실행한 명령어부분인데, 정상실행을 한번하고 두번은 오버플로우를 시켜 실행해봤다.
이때,
정상실행이라함은 인자를 top의 저장범위인 7자이하를 넣는것이고 , 오버플로우는 8자이상 입력하는 것을 말한다.

정상실행 부분
메모리상 top영역 ↓ bottom영역↓
■■■■■■■■ □□□□□□□□
top변수에 7글자를 넣으면 오버 플로우가 안생기고 bottom값 변동없음(7자 까지 정상적으로 저장가능, 널문자 포함 총8자)
after top=1234567
after bottom=bottom
첫번째 overflow발생부분이라고 표시된 부분
8글자를 넣으면 top에 8글자가 저장되고 널 값이 bottom영역으로 침범한다(after bottom이 빈공간인부분)
메모리상 top영역 ↓ bottom영역↓
■■■■■■■■ ■□□□□□□□ (널값은 공백이라 아무것도 안나오지만 널값이 bottom으로 넘어간 상태)
두번째 overflow발생부분이라고 표시된 부분
9글자를 넣어보면 마지막 글자가 bottom영역으로 들어 간다(after bottom이 9인 부분)
메모리상 top영역 ↓ bottom영역↓
■■■■■■■■ ■■□□□□□□ (9와 널값이 넘어가서 9는 보이고 공백으로 보이는 부분이 널값인 상태)
이처럼 자기 영역을 넘어 다른 영역을 침범하는 것을 오버플로우라고 한다.
참고로
8바이트를 할당했으니까 당연히 9바이트면 오버 플로우가 발생한다고 생각하겠지만,
운영체제와 컴파일러에 따라 최적의 성능을 내기 위한 메모리를 할당하기 때문에
복귀주소를 수정하여 해킹을 하려면
실제 디버깅을 통해서 메모리에 얼마나 할당되었는지 확인해야 할 것이다. ㅎ
첫댓글 소스 코드가 안 보입니다. 이미지 말고 실제 텍스트 형태로 본문에 올려주세요. 소스 코드가 안 보이니깐 남은 설명도 이해하기 힘듭니다.
에공 어느정도 지식있고 잘보여도 ㅠ헷갈리는 내용인데 괜히올렸나요ㅠ. 관련 예제를 접하기 어려울것 같아서 만들어본건데 새로만들어야겠네요
스택 버퍼 오버플로우 예제 배경 등이 안 좋아 코드 내용이 잘 안 보인다는 말씀입니다. 그냥 흰 바탕에 검은 글씨로 나오도록 올려주세요. 괜히 색 입힌다고 올리면 오히려 가독성만 떨어지는 경우가 많아요. 얼마 전 SSL 취약점 발견으로 시끌벅적했으니깐 실기와 관련해서도 충분히 다룰 수 있을 듯 싶어요. 본질은 물론 버퍼 오버플로우겠죠? ^^
네^ 배경이야긴줄 압니다 .사실 이게 오버플로우 기본개념을 어느정도 알면 실제예제를 보고 싶어 하는데 그걸 마땅히 볼때가 없을것 같아서 올렸어요, 그런거라 노파심에 이해 안되시면 개념만 아시라고 쓴거구요 ㅠ, 더 쉬운걸로 만들려고 했는데 일단 소스를 새로 타이핑해서 한줄한줄 주석을 달아 놨습니다 . 괜히 이런걸 올려서 죄송^아 참고로 소스색깔은 제가 입힌게 아니라 리눅스에서 코딩하면 저절로 색깔이 입혀진답니다. 이눔에 리눅스 ㅋ^ 열공하세요