Memory corruption stack

1,734 views

Published on

Published in: Education
1 Comment
1 Like
Statistics
Notes
No Downloads
Views
Total views
1,734
On SlideShare
0
From Embeds
0
Number of Embeds
19
Actions
Shares
0
Downloads
28
Comments
1
Likes
1
Embeds 0
No embeds

No notes for slide
  • ThisIsMyVeryExtremelySuperMagnifcantConnectionStringForMyDataSource
  • cdecl - Add esp, 0Ch : 스택 포인터가 원래 위치로 되돌려지게 보장 . 호출 전에 넣은 3 인자에 대한 정리 작업 . - 호출 함수가 스택 포인터를 조정하여 스택 무결성의 보장을 책임 stdcall - 인자는 동일한 방식 . 하지만 스택 포인터 정리하는 부분이 없음 . - 호출된 함수 자신이 스택포인터의 조정을 책임진다 .
  • Ret 0Ch : 지정된 수만큼 스택포인터를 조정하라는 의미
  • Memory corruption stack

    1. 1. Memory Corruption 김태우 ( http://codevania.tistory.com ) 데브루키 ( http://cafe.naver.com/devrookie.cafe )
    2. 2. INDEX <ul><li>개요 </li></ul><ul><li>메모리 손상 탐지 </li></ul><ul><li>스택 손상 </li></ul><ul><ul><li>스택 오버런 </li></ul></ul><ul><ul><li>비동기 동작과 스택 포인터 </li></ul></ul><ul><ul><li>호출 규약 불일치 </li></ul></ul><ul><li>회피 전략 </li></ul>
    3. 3. 개요 <ul><li>메모리 손상이 수정하기 어려운 이유 </li></ul><ul><ul><li>원인과 결과를 관련짓기 어렵다 </li></ul></ul><ul><ul><ul><li>손상의 원인과 현상이 너무나도 떨어져 있다 </li></ul></ul></ul><ul><ul><li>오류 재발을 일관성 있게 할 수 없다 </li></ul></ul><ul><ul><ul><li>비정상적인 조건에서 발생하는 증상 </li></ul></ul></ul>
    4. 4. 개요 <ul><li>메모리 손상은 언제 발생하는가 ? </li></ul><ul><ul><li>실행 스레드가… </li></ul></ul><ul><ul><ul><li>자신이 소유하지 않은 메모리 블록에 쓴다 </li></ul></ul></ul><ul><ul><ul><li>자신이 소유한 메모리 블록에 쓰지만 , 이 메모리 블록의 상태를 손상한다 </li></ul></ul></ul>
    5. 5. 개요 <ul><li>메모리 손상의 증상 </li></ul><ul><ul><li>크래쉬 </li></ul></ul><ul><ul><ul><li>최선의 시나리오 </li></ul></ul></ul><ul><ul><ul><li>메모리 손상의 출처가 어디인지를 나타내기 때문 </li></ul></ul></ul><ul><ul><li>넌크래쉬와 예측 불가능한 동작 </li></ul></ul><ul><ul><ul><li>최악의 시나리오 </li></ul></ul></ul><ul><ul><ul><li>사용되는 유효한 메모리 블록에 쓰기 </li></ul></ul></ul><ul><ul><ul><li>메모는 손상을 당했고 이후는 예측 불가능 </li></ul></ul></ul><ul><ul><ul><li>출처를 찾기란 매우 난해 </li></ul></ul></ul>
    6. 6. 개요 <ul><li>어떻게 해야 하나 ? </li></ul><ul><ul><li>즉시 통지 </li></ul></ul><ul><ul><ul><li>소유하지 않은 메모리에 쓸 때 즉시 통지를 받아야 함 </li></ul></ul></ul><ul><li>사후탐지 </li></ul><ul><ul><li>올바른 전략 </li></ul></ul><ul><ul><li>강력한 툴 셋 </li></ul></ul>
    7. 7. 개요 <ul><li>레지스터 </li></ul><ul><ul><li>EAX, EBX, ECX, EDX </li></ul></ul><ul><ul><ul><li>A: Accumulator register </li></ul></ul></ul><ul><ul><ul><li>B: Base register </li></ul></ul></ul><ul><ul><ul><li>C: Count register </li></ul></ul></ul><ul><ul><ul><li>D: Data register </li></ul></ul></ul><ul><ul><li>ESI, EDI </li></ul></ul><ul><ul><ul><li>S: Source (for memory operation) Register </li></ul></ul></ul><ul><ul><ul><li>D: Destination (for memory operation) Register </li></ul></ul></ul><ul><ul><li>EIP, ESP </li></ul></ul><ul><ul><ul><li>I: Instruction Pointer </li></ul></ul></ul><ul><ul><ul><li>S: Stack Pointer </li></ul></ul></ul>RAX EAX AX AL 64 32 16 8
    8. 8. 메모리 손상 탐지
    9. 9. 메모리 손상 탐지 <ul><li>State Analysis </li></ul><ul><ul><li>진짜로 메모리 손상으로 인한 것인지 확인 </li></ul></ul><ul><ul><li>크래쉬라면 </li></ul></ul><ul><ul><ul><li>유효한 코드 경로를 거쳐 문제에 도달 가능 </li></ul></ul></ul><ul><ul><li>넌크래쉬라면 </li></ul></ul><ul><ul><ul><li>메모리 상태를 비정상적으로 만드는 코드는 찾기 힘듬 </li></ul></ul></ul><ul><ul><ul><li>어딘가에서 메모리 손상이 발생했다고 보는 것이 유일한 그럴듯한 (-_-) 설명임 </li></ul></ul></ul>
    10. 10. 메모리 손상 탐지 <ul><li>Source Code Analysis </li></ul><ul><ul><li>메모리 손상 </li></ul></ul><ul><ul><ul><li>스레드가 소유하지 않은 메모리 위치에 쓸 때 발생 </li></ul></ul></ul><ul><ul><ul><li>즉 , 쓰여지는 데이터는 이를 쓰는 스레드에게만 의미가 있음 </li></ul></ul></ul><ul><ul><ul><li>이 데이터를 분석하고 이해 </li></ul></ul></ul><ul><ul><ul><li>가능한 의혹들의 범위를 축소 </li></ul></ul></ul>
    11. 11. 메모리 손상 탐지 <ul><li>Use Memory Corruption Detection Tool </li></ul><ul><ul><li>Declaim </li></ul></ul><ul><ul><ul><li>메모리 손상을 잡아내는 것을 보장하지는 못함 </li></ul></ul></ul><ul><ul><ul><li>메모리 손상 시나리오를 잡는 데 도움을 줌 </li></ul></ul></ul><ul><ul><li>Tool </li></ul></ul><ul><ul><ul><li>컴파일러 </li></ul></ul></ul><ul><ul><ul><ul><li>스택 검증 코드 삽입 가능 </li></ul></ul></ul></ul><ul><ul><ul><li>어플리케이션 베리파이어 </li></ul></ul></ul><ul><ul><ul><ul><li>힙 기반의 메모리 손상의 경우 최선의 툴 </li></ul></ul></ul></ul>
    12. 12. 메모리 손상 탐지 <ul><li>Instrument Source Code </li></ul><ul><ul><li>가능성에 대한 이론 수립 </li></ul></ul><ul><ul><ul><li>지금까지 모은 모든 정보를 이용 </li></ul></ul></ul><ul><ul><li>이론이 옳고 그름을 증명해야함 </li></ul></ul>
    13. 13. 메모리 손상 탐지 <ul><li>Define Avoidance Strategy </li></ul><ul><ul><li>향후의 회피 전략을 정의 </li></ul></ul><ul><ul><ul><li>가장 중요함 </li></ul></ul></ul><ul><ul><ul><li>툴을 이용 </li></ul></ul></ul><ul><ul><ul><ul><li>코드가 잠재적인 메모리 손상을 최소화하기 위한 명시적인 조치를 취하도록 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>일반적인 메모리 손상을 잡아내도록 </li></ul></ul></ul></ul>
    14. 14. 메모리 손상 탐지
    15. 15. 메모리 손상 탐지
    16. 16. 메모리 손상 탐지
    17. 17. 스택 손상 <ul><li>스택 </li></ul><ul><ul><li>단순한 데이터 구조체 </li></ul></ul><ul><ul><li>동작은 항상 최상단에서 일어남 </li></ul></ul><ul><ul><li>LIFO 구조 </li></ul></ul><ul><ul><ul><li>Last In First Out </li></ul></ul></ul><ul><li>코드와 연관해서… </li></ul><ul><ul><li>실행중인 스레드에 할당된 메모리 블록 </li></ul></ul><ul><ul><li>목적 : 함수 호출 체인을 추적하는 것 </li></ul></ul>
    18. 18. 예제 . StackDesc
    19. 19. 예제 . StackDesc
    20. 20. 예제 . StackDesc
    21. 21. 예제 . StackDesc <ul><li>함수의 도입부 </li></ul><ul><ul><li>ebp </li></ul></ul><ul><ul><ul><li>주어진 프레임의 베이스 포인터를 포함 </li></ul></ul></ul><ul><ul><ul><li>각 프레임마다 유지되어야 함 </li></ul></ul></ul><ul><ul><ul><ul><li>새 프레임의 생성 ( 호출명령 ) 전에 스택에 저장됨 </li></ul></ul></ul></ul><ul><ul><li>esp  ebp </li></ul></ul><ul><ul><ul><li>새로운 스택의 시작을 만들기 위해 </li></ul></ul></ul>
    22. 22. 예제 . StackDesc
    23. 23. 예제 . StackDesc
    24. 24. 예제 . StackDesc
    25. 25. 예제 . StackDesc
    26. 26. 예제 . StackDesc
    27. 27. 예제 . StackDesc <ul><li>8? </li></ul><ul><ul><li>Printf 함수 복귀시 esp 는 호출 준비 작업으로 스택에 저장됐던 마지막 인자를 가리키게 설정 </li></ul></ul><ul><ul><li>호출 이전의 상태로 스택 복구를 보장하기 위해 8 바이트 (2*4= 두 인자의 크기 ) </li></ul></ul>
    28. 28. 스택손상 <ul><li>스택 오버런 </li></ul><ul><li>비동기 동작과 스택 포인터 </li></ul><ul><li>호출 규약 불일치 </li></ul>
    29. 29. 스택 오버런 <ul><li>스택 오버런 </li></ul><ul><ul><li>예약된 자신의 호출 스택 일부분을 덮어쓰는 경우 </li></ul></ul><ul><ul><ul><li>복귀 주소 </li></ul></ul></ul><ul><ul><ul><li>전체 프레임 </li></ul></ul></ul><ul><ul><ul><li>스택을 완전히 소진 </li></ul></ul></ul><ul><ul><li>결과 </li></ul></ul><ul><ul><ul><li>크래시 </li></ul></ul></ul><ul><ul><ul><li>예측 불가능한 행위 </li></ul></ul></ul><ul><ul><ul><li>심각한 보안 결함 </li></ul></ul></ul><ul><ul><ul><ul><li>공격자가 컴퓨터의 완전한 제어를 획득하게 해줄 수 있음 </li></ul></ul></ul></ul>
    30. 30. 스택 오버런
    31. 31. 스택 오버런
    32. 32. 스택 오버런
    33. 33. 스택 오버런
    34. 34. 스택 오버런 <ul><li>해결책 </li></ul><ul><ul><li>지역 변수를 위해 할당된 크기 이상을 변수에 복사하지 않게 보장 </li></ul></ul><ul><ul><ul><li>연결 스트링이 크기 제한이 없는 가변 길이 </li></ul></ul></ul><ul><ul><ul><ul><li>스택에 메모리를 할당하는 것이 잘못되었음 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>컴파일 시점에 스트링의 크기를 알아야함 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>이럴 때는 힙에서 버퍼를 할당 </li></ul></ul></ul></ul><ul><ul><ul><li>연결 스트링이 실제로 30 문자로 제한 ( 아이디 / 비번 등 ) </li></ul></ul></ul><ul><ul><ul><ul><li>경계를 넘지 않게 보장 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>스트링의 크기를 지정하게 돼있는 스트링 복사 함수를 사용 </li></ul></ul></ul></ul>
    35. 35. 스택 오버런 <ul><li>도움을 줄만한 툴 </li></ul><ul><ul><li>Visual Studio 코드분석 </li></ul></ul><ul><ul><ul><li>컴파일 타임에 에러를 탐지 </li></ul></ul></ul><ul><ul><ul><li>Team Suit 만 ; </li></ul></ul></ul><ul><ul><li>PREfast </li></ul></ul><ul><ul><ul><li>http://www.microsoft.com/whdc/DevTools/tools/PREfast.mspx </li></ul></ul></ul><ul><ul><ul><li>http://bwahn.tistory.com/tag/PREfast </li></ul></ul></ul>
    36. 36. 비동기 동작과 스택 포인터 <ul><li>지역 변수의 수명에 대한 잘못된 가정 </li></ul><ul><ul><li>매우 흔한 프로그래밍 실수 중의 한 가지 </li></ul></ul><ul><ul><li>표준 호출 규약의 경우 </li></ul></ul><ul><ul><ul><li>함수의 종결부 코드 실행시 </li></ul></ul></ul><ul><ul><ul><li>스택 포인터는 이전 프레임으로 리셋되고 </li></ul></ul></ul><ul><ul><ul><li>모든 지역 변수는 유효하지 않다고 간주됨 </li></ul></ul></ul>
    37. 37. 비동기 동작과 스택 포인터 <ul><li>에러가 안 나서 디버깅을 할 수가 =_=;; </li></ul>
    38. 38. 호출 규약 불일치 <ul><li>호출 규약 </li></ul><ul><ul><li>함수 호출자와 피호출 함수 간의 단지 규약일 뿐 </li></ul></ul><ul><ul><li>규약간의 주 차이점 </li></ul></ul><ul><ul><ul><li>인자가 호출 함수로 전달되는 방식 </li></ul></ul></ul><ul><ul><ul><li>스택에서 이 인자가 정리되는 방식 </li></ul></ul></ul>
    39. 39. 호출 규약 불일치
    40. 40. 호출 규약 불일치
    41. 41. 호출 규약 불일치 <ul><li>stdcall 이 더 좋잖아 ? cdecl 은 언제 사용 ? </li></ul><ul><ul><li>가변인자리스트를 지원 </li></ul></ul><ul><ul><li>stdcall 은 callee 가 전달된 인자의 수를 알 수 없음 </li></ul></ul>
    42. 42. 호출 규약 불일치
    43. 43. 호출 규약 불일치
    44. 44. 호출 규약 불일치 <ul><li>미완 </li></ul>
    45. 45. 회피 전략 <ul><li>/GS </li></ul><ul><ul><li>C/C++  코드생성  버퍼보안검사 </li></ul></ul><ul><ul><li>리턴 주소가 덮어 써졌는지 보안 검사 코드 추가 </li></ul></ul><ul><ul><li>바이러스 작성이 어려워짐 </li></ul></ul><ul><ul><li>하지만 단순한 안전장치로만 생각 . 완벽한 보호는 불가능 . </li></ul></ul>
    46. 46. 회피 전략 <ul><li>/RTC (Run Time Checks) </li></ul><ul><ul><li>C/C++  코드생성  작은 형식 검사 (/RTCc) </li></ul></ul><ul><ul><ul><li>RTCc ( 데이터 손실 보호 ) </li></ul></ul></ul><ul><ul><ul><ul><li>작은 데이터형식 변환 시 손실 검사 : </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>모든 지역 변수를 0xCC 로 초기화 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>스택 프레임 검사가 로컬 변수 언더런 / 오버런을 감지 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>스택 충돌에 대해서 스택 포인터 검증 </li></ul></ul></ul></ul></ul><ul><ul><li>C/C++  코드생성  기본 런타임 검사 (/RTCu) </li></ul></ul><ul><ul><ul><li>RTCu ( 초기화되지 않은 변수 보호 ) </li></ul></ul></ul><ul><ul><ul><ul><li>초기화 되지 않은 변수가 접근될 때마다 에러 표시 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>변수 초기화를 하지 않는 것은 흔한 실수인데 이를 방지 </li></ul></ul></ul></ul><ul><ul><li>RTC 옵션은 디버그 빌드에만 영향이 있음 </li></ul></ul>
    47. 47. 회피 전략 <ul><li>툴 </li></ul><ul><ul><li>Rational’s Purify </li></ul></ul><ul><ul><li>NuMega’s BoundsChecker </li></ul></ul>
    48. 48. Summary <ul><li>스택 손상 </li></ul><ul><ul><li>심각한 불안정성 문제를 유발 </li></ul></ul><ul><ul><li>무작위적인 크래시 </li></ul></ul><ul><ul><li>사용자의 컴퓨터를 손상 </li></ul></ul><ul><ul><li>심각한 보안 취약점 제기 </li></ul></ul><ul><li>자세 </li></ul><ul><ul><li>개발자는 스택 무결성 유지 </li></ul></ul><ul><ul><li>소프트웨어의 성공을 위해 회피 기법을 채택 </li></ul></ul>

    ×