memory corruption stack

48
Memory Corruption 김김김 (http://codevania.tistory.com ) 김김김김 (http://cafe.naver.com/devrookie.cafe )

Upload: taewoo-kim

Post on 21-Jun-2015

1.405 views

Category:

Education


3 download

TRANSCRIPT

Page 1: Memory corruption stack

Memory Corruption

김태우 (http://codevania.tistory.com)

데브루키 (http://cafe.naver.com/devrookie.cafe)

Page 2: Memory corruption stack

INDEX

• 개요• 메모리 손상 탐지• 스택 손상–스택 오버런–비동기 동작과 스택 포인터–호출 규약 불일치

• 회피 전략

Page 3: Memory corruption stack

개요

• 메모리 손상이 수정하기 어려운 이유

–원인과 결과를 관련짓기 어렵다•손상의 원인과 현상이 너무나도 떨어져 있다

–오류 재발을 일관성 있게 할 수 없다•비정상적인 조건에서 발생하는 증상

Page 4: Memory corruption stack

개요

• 메모리 손상은 언제 발생하는가 ?–실행 스레드가…

•자신이 소유하지 않은 메모리 블록에 쓴다•자신이 소유한 메모리 블록에 쓰지만 ,

이 메모리 블록의 상태를 손상한다

Page 5: Memory corruption stack

개요

• 메모리 손상의 증상

–크래쉬•최선의 시나리오•메모리 손상의 출처가 어디인지를 나타내기 때문

–넌크래쉬와 예측 불가능한 동작•최악의 시나리오•사용되는 유효한 메모리 블록에 쓰기•메모는 손상을 당했고 이후는 예측 불가능•출처를 찾기란 매우 난해

Page 6: Memory corruption stack

개요

• 어떻게 해야 하나 ?–즉시 통지

•소유하지 않은 메모리에 쓸 때 즉시 통지를 받아야 함

• 사후탐지–올바른 전략–강력한 툴 셋

Page 7: Memory corruption stack

개요

• 레지스터– EAX, EBX, ECX, EDX

• A: Accumulator register• B: Base register• C: Count register• D: Data register

– ESI, EDI• S: Source (for memory operation) Register• D: Destination (for memory operation) Register

– EIP, ESP• I: Instruction Pointer• S: Stack Pointer

8 16 32 64

AL AX EAX RAX

Page 8: Memory corruption stack

메모리 손상 탐지

Page 9: Memory corruption stack

메모리 손상 탐지

• State Analysis–진짜로 메모리 손상으로 인한 것인지 확인–크래쉬라면

•유효한 코드 경로를 거쳐 문제에 도달 가능

–넌크래쉬라면•메모리 상태를 비정상적으로 만드는 코드는 찾기 힘듬•어딘가에서 메모리 손상이 발생했다고 보는 것이

유일한 그럴듯한 (-_-) 설명임

Page 10: Memory corruption stack

메모리 손상 탐지

• Source Code Analysis–메모리 손상

•스레드가 소유하지 않은 메모리 위치에 쓸 때 발생•즉 , 쓰여지는 데이터는

이를 쓰는 스레드에게만 의미가 있음•이 데이터를 분석하고 이해•가능한 의혹들의 범위를 축소

Page 11: Memory corruption stack

메모리 손상 탐지

• Use Memory Corruption Detection Tool– Declaim

•메모리 손상을 잡아내는 것을 보장하지는 못함•메모리 손상 시나리오를 잡는 데 도움을 줌

– Tool•컴파일러

– 스택 검증 코드 삽입 가능

•어플리케이션 베리파이어– 힙 기반의 메모리 손상의 경우 최선의 툴

Page 12: Memory corruption stack

메모리 손상 탐지

• Instrument Source Code–가능성에 대한 이론 수립

•지금까지 모은 모든 정보를 이용

–이론이 옳고 그름을 증명해야함

Page 13: Memory corruption stack

메모리 손상 탐지

• Define Avoidance Strategy–향후의 회피 전략을 정의

•가장 중요함•툴을 이용

– 코드가 잠재적인 메모리 손상을 최소화하기 위한 명시적인 조치를 취하도록

– 일반적인 메모리 손상을 잡아내도록

Page 14: Memory corruption stack

메모리 손상 탐지

Page 15: Memory corruption stack

메모리 손상 탐지

Page 16: Memory corruption stack

메모리 손상 탐지

Page 17: Memory corruption stack

스택 손상

• 스택–단순한 데이터 구조체–동작은 항상 최상단에서 일어남– LIFO 구조

• Last In First Out

• 코드와 연관해서…–실행중인 스레드에 할당된 메모리 블록–목적 : 함수 호출 체인을 추적하는 것

Page 18: Memory corruption stack

예제 . StackDesc

Page 19: Memory corruption stack

예제 . StackDesc

Page 20: Memory corruption stack

예제 . StackDesc

Page 21: Memory corruption stack

예제 . StackDesc

• 함수의 도입부– ebp

•주어진 프레임의 베이스 포인터를 포함•각 프레임마다 유지되어야 함

– 새 프레임의 생성 ( 호출명령 ) 전에 스택에 저장됨

– esp ebp •새로운 스택의 시작을 만들기 위해

Page 22: Memory corruption stack

예제 . StackDesc

Page 23: Memory corruption stack

예제 . StackDesc

Page 24: Memory corruption stack

예제 . StackDesc

Page 25: Memory corruption stack

예제 . StackDesc

Page 26: Memory corruption stack

예제 . StackDesc

Page 27: Memory corruption stack

예제 . StackDesc

• 8?– Printf 함수 복귀시 esp 는 호출 준비 작업으로

스택에 저장됐던 마지막 인자를 가리키게 설정– 호출 이전의 상태로 스택 복구를 보장하기 위해

8 바이트 (2*4= 두 인자의 크기 )

Page 28: Memory corruption stack

스택손상

• 스택 오버런• 비동기 동작과 스택 포인터• 호출 규약 불일치

Page 29: Memory corruption stack

스택 오버런

• 스택 오버런–예약된 자신의 호출 스택 일부분을 덮어쓰는 경우

•복귀 주소•전체 프레임•스택을 완전히 소진

–결과•크래시•예측 불가능한 행위•심각한 보안 결함

– 공격자가 컴퓨터의 완전한 제어를 획득하게 해줄 수 있음

Page 30: Memory corruption stack

스택 오버런

Page 31: Memory corruption stack

스택 오버런

Page 32: Memory corruption stack

스택 오버런

Page 33: Memory corruption stack

스택 오버런

Page 34: Memory corruption stack

스택 오버런

• 해결책–지역 변수를 위해 할당된 크기 이상을 변수에 복사하지 않게 보장•연결 스트링이 크기 제한이 없는 가변 길이

– 스택에 메모리를 할당하는 것이 잘못되었음– 컴파일 시점에 스트링의 크기를 알아야함– 이럴 때는 힙에서 버퍼를 할당

•연결 스트링이 실제로 30문자로 제한 ( 아이디 / 비번 등 )– 경계를 넘지 않게 보장– 스트링의 크기를 지정하게 돼있는 스트링 복사 함수를 사용

Page 35: Memory corruption stack

스택 오버런

• 도움을 줄만한 툴– Visual Studio 코드분석

•컴파일 타임에 에러를 탐지• Team Suit 만 ;

– PREfast•http://www.microsoft.com/whdc/DevTools/tools/PREfast

.mspx•http://bwahn.tistory.com/tag/PREfast

Page 36: Memory corruption stack

비동기 동작과 스택 포인터

• 지역 변수의 수명에 대한 잘못된 가정–매우 흔한 프로그래밍 실수 중의 한 가지–표준 호출 규약의 경우

•함수의 종결부 코드 실행시•스택 포인터는 이전 프레임으로 리셋되고•모든 지역 변수는 유효하지 않다고 간주됨

Page 37: Memory corruption stack

비동기 동작과 스택 포인터

• 에러가 안 나서 디버깅을 할 수가 =_=;;

Page 38: Memory corruption stack

호출 규약 불일치

• 호출 규약–함수 호출자와 피호출 함수 간의 단지 규약일 뿐–규약간의 주 차이점

•인자가 호출 함수로 전달되는 방식•스택에서 이 인자가 정리되는 방식

Page 39: Memory corruption stack

호출 규약 불일치

Page 40: Memory corruption stack

호출 규약 불일치

Page 41: Memory corruption stack

호출 규약 불일치

• stdcall 이 더 좋잖아 ? cdecl 은 언제 사용 ?–가변인자리스트를 지원– stdcall 은 callee 가 전달된 인자의 수를 알 수 없음

Page 42: Memory corruption stack

호출 규약 불일치

Page 43: Memory corruption stack

호출 규약 불일치

Page 44: Memory corruption stack

호출 규약 불일치

• 미완

Page 45: Memory corruption stack

회피 전략

• /GS– C/C++ 코드생성 버퍼보안검사–리턴 주소가 덮어 써졌는지 보안 검사 코드 추가–바이러스 작성이 어려워짐–하지만 단순한 안전장치로만 생각 . 완벽한 보호는

불가능 .

Page 46: Memory corruption stack

회피 전략

• /RTC (Run Time Checks)– C/C++ 코드생성 작은 형식 검사 (/RTCc)

•RTCc ( 데이터 손실 보호 )– 작은 데이터형식 변환 시 손실 검사 :

» 모든 지역 변수를 0xCC 로 초기화» 스택 프레임 검사가 로컬 변수 언더런 / 오버런을 감지» 스택 충돌에 대해서 스택 포인터 검증

– C/C++ 코드생성 기본 런타임 검사 (/RTCu)•RTCu (초기화되지 않은 변수 보호 )

– 초기화 되지 않은 변수가 접근될 때마다 에러 표시– 변수 초기화를 하지 않는 것은 흔한 실수인데 이를 방지

– RTC 옵션은 디버그 빌드에만 영향이 있음

Page 47: Memory corruption stack

회피 전략

• 툴– Rational’s Purify– NuMega’s BoundsChecker

Page 48: Memory corruption stack

Summary

• 스택 손상–심각한 불안정성 문제를 유발–무작위적인 크래시–사용자의 컴퓨터를 손상–심각한 보안 취약점 제기

• 자세–개발자는 스택 무결성 유지–소프트웨어의 성공을 위해 회피 기법을 채택