스킬캠퍼스
10강 · 메모리 취약점
강의

오늘 끝나면

메모리 취약점

  • 메모리 취약점의 핵심 문제를 한 문장으로 설명한다
  • 오른쪽 실습에서 메모리이 어떻게 움직이는지 관찰한다
  • 다음 강의와 이어지는 한계를 말할 수 있다

실습 미션

버퍼 오버플로우 — 스택을 넘어 쓰면 이 문장이 실제로 무슨 뜻인지 실습에서 한 번 손으로 확인한다.

성공 조건

  • 실습의 기본값을 먼저 관찰
  • 입력값이나 모드를 한 번 이상 바꿔 결과 비교
  • 왜 결과가 바뀌었는지 한 문장으로 설명

화이트해킹 · 10

메모리
취약점

입력이 그릇 크기를 넘으면 옆 메모리로 흘러넘침.
그 옆에 함수의 반환주소가 있음.
거길 덮으면 실행 흐름이 통째로 넘어감.

P.01화이트해킹 · 10

스택 — 함수가 쓰는 메모장

함수가 돌 때 자기 변수들을 임시로 쌓아두는 칸이 있음. 그게 스택임.

입력을 담는 그릇(버퍼)도 여기 잡힘.
그런데 버퍼 바로 위에 함수가 끝나고 돌아갈 자리, 반환주소가 같이 얹혀 있음.

반환주소는 “이 함수 끝나면 여기로 가”라고 적힌 쪽지임.
함수가 끝나면 CPU는 묻지도 따지지도 않고 그 쪽지대로 점프함.
버퍼와 반환주소가 한 메모장에 붙어 있다는 게 이 강의 모든 위험의 출발점임.

버퍼 위에 반환주소가 얹혀 있음
한 함수의 스택 — 위가 높은 주소
반환주소끝나면 여기로 점프
저장변수함수의 임시 값
버퍼[7]입력 마지막 칸
버퍼[…]입력이 채우는 곳
버퍼[0]입력 첫 칸
버퍼 바로 위에 반환주소가 붙어 있음 — 여기가 약점
P.02화이트해킹 · 10

크기를 안 재면 흘러넘침

버퍼는 크기가 정해져 있음. 8칸이면 8글자까지임.

그런데 C/C++의 옛 함수들은 입력 길이를 안 잼.
strcpy·gets는 들어온 만큼 그냥 복사함 / 그릇이 넘쳐도 멈추질 않음.

8칸짜리 그릇에 12글자를 부으면 4글자가 밖으로 샘.
새는 글자는 사라지는 게 아니라 바로 옆 칸을 덮어씀.
옆 칸엔 다른 변수가, 더 위엔 반환주소가 있음 / 입력이 길수록 더 깊이 침범함.

8칸 그릇에 12글자를 부으면
8칸 그릇 · 12글자 입력
들어온 글자 — 8칸을 넘는 4글자가 샘
ABCDEFGHIJKL
버퍼 안 8칸넘쳐서 옆 칸 덮음
길이를 안 재는 함수는 8에서 안 멈춤
P.03화이트해킹 · 10

넘치면 반환주소를 덮는다

오른쪽에서 직접 넘쳐 봄. 입력 길이 슬라이더를 올리면 글자가 버퍼부터 위로 차오름.

8칸을 넘는 순간 옆 변수를 침범함.
더 올리면 반환주소 칸까지 빨갛게 덮임.

반환주소가 덮이면 함수가 끝날 때 공격자가 심어둔 주소로 점프함.
그럼 공격자가 짠 코드로 실행 흐름이 넘어감 / 이게 제어 흐름 탈취임.
“경계검사 켜짐” 버튼을 누르면 8칸까지만 받고 잘라냄 — 넘쳐도 반환주소가 멀쩡함.

슬라이더로 직접 넘쳐 보기
스택 시각화 · 입력이 버퍼를 넘치는 순간
입력 — 글자 수5 / 버퍼 8
스택 — 입력은 버퍼부터 위로 차오름
반환주소·비어 있음
반환주소·비어 있음
저장변수·비어 있음
저장변수·비어 있음
버퍼[7]·비어 있음
버퍼[6]·비어 있음
버퍼[5]·비어 있음
버퍼[4]입력
버퍼[3]입력
버퍼[2]입력
버퍼[1]입력
버퍼[0]입력

버퍼 8칸 · 저장변수 2칸 · 반환주소 2

판정 — 함수가 끝나면 어디로 점프하나
정상버퍼 안에 들어맞음

입력이 버퍼 안에 들어맞음. 인접 메모리가 안 건드려짐.

P.04화이트해킹 · 10

왜 C/C++에서 흔한가

파이썬·자바스크립트에선 이게 안 터짐. C/C++에서만 단골임. 이유가 있음.

C/C++는 속도를 위해 안전장치를 뺐음.
배열에 몇 칸이 있는지 실행 중에 안 따짐 / 9번째 칸에 써도 언어가 안 말림.

대신 그 책임을 전부 개발자에게 넘김.
파이썬은 범위를 넘으면 바로 오류를 내고 멈춤 / C는 조용히 옆 메모리를 망가뜨림.
이 “조용함” 때문에 버그가 숨고, 그 틈을 공격자가 노림.

언어가 경계를 안 챙겨줌
경계검사를 누가 해주나
언어자동 경계검사
C / C++안 함조용히 옆 칸 덮음
PythonIndexError로 멈춤
JavaScript범위 밖이면 undefined
Rust컴파일·실행 중 차단
C는 속도를 위해 검사를 뺌 → 책임이 개발자에게 넘어옴
P.05화이트해킹 · 10

방어 — 경계를 재고 멈춰라

방어의 핵심은 한 줄임. 쓰기 전에 크기를 재고, 넘치면 멈추는 것.

길이를 안 재는 함수를 안 씀.
strcpy 대신 길이를 받는 strncpy·snprintf / gets 대신 fgets를 씀.
입력을 받을 땐 항상 버퍼 크기와 비교하는 경계검사를 넣음.

컴파일러·OS도 거듦 — 스택에 몰래 심은 표식(카나리)이 깨졌는지 보고, 주소를 매번 섞음.
가장 확실한 건 경계를 언어가 챙겨주는 Rust·Go 같은 도구로 옮기는 것.
뚫는 법을 배우는 이유는 결국 이 경계를 어디에 둘지 알기 위해서임.

Q. 버퍼 오버플로우가 위험한 이유는? (속도가 느려져서 · 반환주소를 덮어 실행 흐름을 가로채서 · 화면이 깨져서 · 디스크가 차서)정답은 반환주소를 덮어 실행 흐름을 가로챌 수 있어서임.
버퍼를 넘친 입력이 옆에 붙은 반환주소까지 덮으면, 함수가 끝날 때 공격자가 심은 주소로 점프함.
그럼 공격자 코드로 제어가 넘어감 / 단순한 데이터 손상이 아니라 기기 장악으로 이어짐.
그래서 방어는 항상 경계검사 — 쓰기 전에 크기를 재고 넘치면 멈추는 것임.
위험한 함수 → 안전한 함수
위험한 함수 → 안전한 함수
strcpystrncpy / snprintf

길이를 받아 자름

getsfgets

최대 크기를 넘김

sprintfsnprintf

버퍼 크기로 제한

받침막 — 카나리 · 주소 무작위화 · Rust/Go

3줄 요약

  1. 1버퍼 오버플로우 — 스택을 넘어 쓰면
  2. 2메모리 취약점은 기초·정찰 → 웹 취약점 → 시스템 침투 → 네트워크·IoT → 레드팀·AI 흐름 안의 한 칸이다.
  3. 3개념을 외우는 것보다 입력을 바꾸면 무엇이 달라지는지 보는 것이 우선이다.

완료 전 점검

복습 카드

메모리

버퍼 오버플로우 — 스택을 넘어 쓰면

취약점

공격에 악용될 수 있는 시스템의 약점

익스플로잇

취약점을 실제로 이용하는 코드나 기법