
저번포스트에 서 함수가 시스템 단위에서 어떻게 다뤄지는지 살펴봤고, 그 때 스택을 사용해서 값을 저장하는 것을 확인했는데요.
스택이 너무 자라서 힙영역과 충돌하게 되면 메모리가 덮어씌워져서 스택오버플로우가 일어나는데요.
내용은 완전히 다르지만 스택 영역에서 일어날 수 있는 문제 중 하나인 버퍼 오버플로우에 대해서 알아보겠습니다.
C는 배열에 접근할 때 경계를 검사해주지 않는다.
이게 무슨 말이냐면, 배열이 예를 들어 char buf[8] 이렇게 선언되어 있다고 하면,
8바이트까지만 써야 되는데 그 이상 써도 아무 경고 없이 진행된다는 거다. 너무 쿨하게 아무 말도 안 해줌. 그리고 이게 바로 버퍼 오버플로우라는 악명 높은 취약점으로 이어진다.
이 C코드를 한번 봐볼까요
void echo() {
char buf[8];
gets(buf);
puts(buf);
}
char 형의 buf 라는 배열이 [8] 까지만 선언되었는데.
이건 총 8바이트 크기의 배열이라는 뜻이다.
근데 gets 는 입력을 받을 때, 크기 제한이 없다. 그냥 줄 끝날 때 까지 다 읽어버린다.
그런데 buf 는 8바이트 크기의 배열.
Q: 총 8바이트인데 이거 넘어서 입력하면 어케댐?
A: 스택에 있던 다른 데이터들 덮어씌워버려용 ^^~
그냥 에렌 땅울림에 마레인들 지워지는거마냥 지워짐
심지어 이게 return Address 까지 갈 수도 있어서
return Address 가 바뀌고 함수가 끝나면 return Address 로 ret 해서 가야되는데
그냥 갑자기 엉뚱한 곳으로 점프한다.
이걸 악용하면 내가 입력한 문자열로 프로그램 흐름을 조작할 수 있다. ㄷㄷ
이걸 그냥 단순한 버그라고 보면 안 된다. 버퍼 오버플로우는 시스템 해킹의 핵심이다. 예전 유명한 사례 중에는 1988년 모리스 웜(Morris Worm) 사건이 있는데, 이것도 버퍼 오버플로우 이용해서 퍼졌다.
공격자는 입력 문자열에 쉘코드(shellcode)를 넣고, 리턴 주소를 그 쉘코드 위치로 덮어씌워서 원하는 코드 실행시킨다. 이거 완전 해킹이다.
뭐 너무 유명한 오류라 방어 방법이 많이 나와있다.
fgets(buf,sizeof(buf),stdin) 이런 식으로 써야 안전함strcpy() 대신 strncpy() 사용정리
C는 배열 범위 벗어나도 말 안 해줌
gets()는 무조건 오버플로우 나니까 쓰지 마
보안 생각하면서 코딩하자
오늘도.. cs 지식이 하나 늘어간다.

형 진짜 미친거같아