티스토리 뷰

3.10 Combining Control and Data in Machine-Level Programs

어떻게 기계 수준의 코드가 프로그램의 제어 측면을 구현하는 지와 어떻게 자료 구조로 구현되는지 구별하여 보았다.

데이터와 제어가 서로 상호작용하는 방법을 알아보자

 

3.10.1 Understanding Pointers

 

포인터는 C언어에서 중심적인 특징이다.

자료 구조에 있는 요소에 대한 참조를 생성하는 통합된 방법을 제공한다.

 

다음은 포인터의 중요한 원칙과 기계 코드로 매핑하는 것이다.

 

- 모든 포인터는 연관된 타입이 있다 : 포인터가 어떤 오브젝트를 가리키는지 가리킨다.

- 모든 포인터는 값이 있다 : 값은 지정된 타입의 어떤 오브젝트의 주소이다. NULL 값은 어떠한 곳도 가리키지 않는 것을 뜻한다.

- 포인터는 & 연산자와 함께 만들어진다 : 이 연산자는 lvalue로 되어있는 어떠한 C 표현식에 적용된다.

- 포인터는 * 연산자로 디퍼런스된다 : 포인터와 연관된 타입을 가진 값이 결과이다.

- 배열과 포인터는 연관되어 있다

- 포인터의 타입을 다른 타입으로 캐스팅할 수 있지만 값은 안바뀐다

- 포인터는 함수에 포인트할 수 있다

 

3.10.2 Life in the Real World: Using the GDB Debugger

 

3.10.3 Out-of-Bounds Memory References and Buffer Overflow

C는 메모리 참조에 대한 범위 체크를 수행하지 않고 지역 변수는 저장된 레지스터 값과 복귀 주소와 같은 상태 정보와 스택에 저장된다.

이러한 조합은 심각한 프로그램 에러를 일으키고, 스택에 저장되어 있는 상태들은 범위 밖에 요소들을 작성하는 것에 의해 손상된다.

프로그램이 레지스터를 다시 시작하거나 ret 명령어를 이렇게 손상된 상태로 작성하면, 심각하게 잘못된다.

 

이렇게 상태가 손상된 것의 소스를 버퍼 오버플로우(buffer overflow)라고 부른다

 

버퍼 오버플로우의 잘못된 사용은 우리가 원치 않는 함수를 수행하려는 프로그램이 된다는 것이다.

컴퓨터 네트워크에서 시스템 보안을 공격하는 가장 흔한 방법 중 하나이다.

 

일반적으로 프로그램에는 익스플로잇 코드(exploit code)라고하는 일부 실행 코드의 바이트 인코딩과 익스플로잇 코드에 대한 포인터로 반환 주소를 덮어 쓰는 추가 바이트가 포함 된 문자열이 제공됩니다.

ret 명령어를 실행하면 그 익스플로잇 코드로 jump한다.

 

익스플로잇 코드는 시스템 호출을 사용하여 쉘 프로그램을 시작하여 공격자에게 다양한 운영 체제의 함수를 제공한다.

익스플로잇 코드는 권한 없는 공격을 수행한다.

 

3.10.4 Thwarting Buffer Overflow Attacks

 

버퍼 오버플로우는 많이 퍼져있고 컴퓨터 시스템에 많은 문제를 일으키기 때문에 모던 컴파일러와 운영체제는 이러한 공격을 더 어렵게 만들고 공격자가 버퍼 오버플로우 공격을 통해 시스템의 제어를 가지는 방법을 제한한 메카니즘을 구현하였다.

 

Stack Randomization

익스플로잇 코드를 시스템에 넣으려면, 공격자는 코드와 포인터를 공격 문자열의 부분 코드에 주입해야 한다.

이 포인터를 생성하는 것은 문자열이 위치할 스택 주소를 알아야 한다.

프로그램의 스택 주소는 매우 예측하기 쉽다.

 

스택 랜덤화 개념은 한 프로그램이 실행하는 스택의 위치를 다른 곳으로 바꾸는 것이다.

이는 프로그램 시작하는 스택의 0부터 n바이트 사이에 무작위 공간을 할당하여 구현한다.

 

스택 랜덤화는 리눅스(Linux) 시스템에서 표준이 되었다. ASLR(Address Layout Randomization)이라는 기술의하나이다.

ASLR은 프로그램, 라이브러리 코드, 스택, 전역변수, 힙 데이터를 포함한 프로그램들을 메모리의 각각 다른 부분에 로드한다.

 

끈질긴 공격자는 브루트-포스(Brute-force)로 랜덤화를 극복할 수 있다.

 

Stack Corruption Detection

스택이 손상받으면 감지할 수 있게 해주는 것이다.

프로그램은 악영향을 받기 전에 쓰기가 발생하면 프로그램은 감지를 시도할 수 있다.

 

GCC는 스택 보호기라는 메카니즘을 생성된 코드에 만들어버퍼 침입을 감지한다.

지역 버퍼와 나머지 스택 상태 사이에 카나리아(canary) 값을 저장한다.

카나리아 값은 보호 값(guard value)으로 불려지며, 프로그램이 실행할 때마다 무작위로 생성되며 공격자가 결정하기 쉽지 않다.

 

Limiting Executable Code Reigons

시스템에 실행 가능한 코드를 삽입하려는 공격자의 능력을 제거하는 것이다.

실행 가능한 코드를 가진 메모리 지역을 제한하는 것이다.

 

3.10.5 Supporting Variable-Size Stack Frames -- 다시

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함