현재 위치 - 중국오락넷 - 공연예술정보 - 버퍼 오버플로 공격의 기본 원리는 무엇입니까?

버퍼 오버플로 공격의 기본 원리는 무엇입니까?

버퍼 오버플로는 다양한 운영 체제와 응용 프로그램 소프트웨어에 널리 존재하는 매우 일반적이고 위험한 취약점입니다. 버퍼 오버플로 공격은 프로그램 오류, 시스템 충돌, 재시작 및 기타 결과를 초래할 수 있습니다. 더욱 심각한 점은 승인되지 않은 명령을 실행하고 심지어 시스템 권한을 획득하는 데 사용될 수 있으며 다양한 불법적인 작업을 수행할 수 있다는 것입니다. 버퍼 오버플로 공격에는 많은 영어 이름이 있습니다. 버퍼 오버플로, 버퍼 오버런, 스택 분쇄, 스택 폐기, 스택 낙서, 스택 조작, 메모리 누수, 오버런 나사 등 모두 동일한 공격 방법을 나타냅니다. 최초의 버퍼 오버플로 공격인 모리스 웜은 10년 전에 발생하여 전 세계 6,000개 이상의 네트워크 서버를 마비시켰습니다.

1. 개념

버퍼 오버플로는 컴퓨터가 버퍼 자체의 용량을 초과하는 데이터 비트로 버퍼를 채우는 경우, 이상적으로는 오버플로된 데이터가 합법적인 데이터를 덮어쓰는 현상을 의미합니다. 프로그램은 데이터 길이를 확인하고 버퍼 길이를 초과하는 문자의 입력을 허용하지 않지만 대부분의 프로그램은 데이터 길이가 항상 할당된 저장 공간과 일치한다고 가정하므로 운영 체제는 버퍼 오버플로에 대한 숨겨진 위험을 만듭니다. 사용되는 버퍼는 "스택"이라고도 합니다. 각 작업 프로세스 사이에 명령이 일시적으로 "스택"에 저장되며 "스택"에서 버퍼 오버플로가 발생할 수 있습니다.

2. 위험

현재 네트워크 및 분산 시스템 보안에서 널리 악용되는 것 중 50% 이상이 가장 유명한 예는 1988년의 Fingerd 사용입니다. 벌레. 버퍼 오버플로 중에서 가장 위험한 것은 스택 오버플로입니다. 침입자는 함수가 반환될 때 반환 프로그램의 주소를 변경하기 위해 스택 오버플로를 사용할 수 있으며, 이로 인해 프로그램이 어떤 주소로든 점프할 수 있게 됩니다. 서비스 거부를 유발하고, 다른 하나는 쉘을 얻는 등 악성 코드를 점프하여 실행한 다음 원하는 대로 수행하는 것입니다.

3. 버퍼 공격

1. 버퍼 오버플로의 원리

프로그램의 버퍼 길이를 초과하는 내용을 작성하여 버퍼를 오버플로시켜 파괴합니다. 프로그램의 스택을 파괴하고 프로그램이 공격 목적을 달성하기 위해 다른 명령을 실행하도록 합니다. 버퍼 오버플로의 원인은 사용자가 입력한 매개변수를 프로그램에서 주의 깊게 확인하지 않기 때문입니다. 예를 들어, 다음 프로그램은:

void function(char *str) {

char buffer[16]

strcpy(buffer,str) < /p>

}

위의 strcpy()는 str의 내용을 버퍼에 직접 복사합니다. 이런 식으로 str의 길이가 16보다 크면 버퍼가 오버플로되고 프로그램이 잘못 실행됩니다. strcpy와 같은 문제가 있는 표준 함수로는 strcat(), sprintf(), vsprintf(), gets(), scanf() 등이 있습니다.

물론, 버퍼를 무작위로 채워서 오버플로를 일으키는 것은 일반적으로 "세그먼트 오류"만 유발할 뿐 공격의 목적을 달성할 수 없습니다. 가장 일반적인 방법은 버퍼 오버플로를 생성하여 프로그램이 사용자 셸을 실행하도록 한 다음 셸을 통해 다른 명령을 실행하는 것입니다. 프로그램이 루트에 속하고 suid 권한이 있는 경우 공격자는 루트 권한이 있는 셸을 획득하고 시스템에서 모든 작업을 수행할 수 있습니다.

버퍼 오버플로 공격이 일반적인 보안 공격 방법이 된 이유는 버퍼 오버플로 취약점이 너무 흔하고 구현하기 쉽기 때문입니다. 게다가 버퍼 오버플로가 원격 공격의 주요 수단이 된 이유는 버퍼 오버플로 취약점이 공격자에게 공격 코드 이식과 실행 등 원하는 모든 것을 제공하기 때문이다. 이식된 공격코드는 버퍼오버플로우 취약점이 있는 프로그램을 특정 권한으로 실행시켜 공격받은 호스트에 대한 제어권을 획득한다.

1998년 링컨 연구소가 침입 탐지를 평가하기 위해 사용한 5건의 원격 공격 중 2건은 버퍼 오버플로였습니다. 1998년에는 CERT의 13개 권장 사항 중 9개가 버퍼 오버플로와 관련이 있었습니다. 1999년에는 권장 사항 중 최소한 절반이 버퍼 오버플로와 관련이 있었습니다. Bugtraq의 설문 조사에서 응답자의 2/3는 버퍼 오버플로 취약점이 심각한 보안 문제라고 생각했습니다.

버퍼 오버플로 취약점과 공격은 다양한 형태로 나타나며 섹션 2에서 설명하고 분류합니다. 이에 따라 방어 방법도 공격 방법에 따라 달라지는데, 이에 대해서는 각 공격 유형에 대한 효과적인 방어 방법을 포함하는 4장에서 설명합니다.

2. 버퍼 오버플로 취약점 및 공격

버퍼 오버플로 공격의 목적은 특정 권한으로 실행되는 프로그램의 기능을 방해하여 공격자가 프로그램을 제어할 수 있도록 하는 것입니다. 프로그램에 충분한 권한이 있으면 전체 호스트가 제어됩니다. 일반적으로 공격자는 루트 프로그램을 공격한 후 "exec(sh)"와 유사한 실행 코드를 실행하여 루트 권한이 있는 셸을 획득합니다. 이 목표를 달성하기 위해 공격자는 다음 두 가지 목표를 달성해야 합니다.

1. 프로그램의 주소 공간에 적절한 코드를 배열합니다.

2. 적절한 초기화 레지스터와 메모리를 통해 프로그램이 실행을 위해 침입자가 마련한 주소 공간으로 점프하도록 합니다.

버퍼 오버플로 공격은 이 두 가지 목표에 따라 분류됩니다. 2.1절에서는 공격 코드가 공격 대상 프로그램의 주소 공간에 어떻게 배치되는지 설명합니다. 2.2절에서는 공격자가 어떻게 프로그램의 버퍼를 오버플로하고 실행을 공격 코드로 전달할 수 있는지 소개합니다(이것이 "오버플로"의 유래입니다). 2.3절에서는 앞선 두 절에서 논의한 프로그램 실행 흐름을 제어하기 위한 코드 배열과 기법을 종합한다.

2.1 프로그램의 주소 공간에 적절한 코드를 배열하는 방법

공격받는 프로그램의 주소 공간에 공격 코드를 배열하는 방법에는 두 가지가 있습니다.

1. 이식 방법:

공격자는 공격받는 프로그램에 문자열을 입력하고, 프로그램은 해당 문자열을 버퍼에 넣습니다. 이 문자열에 포함된 데이터는 공격받은 하드웨어 플랫폼에서 실행할 수 있는 일련의 명령입니다. 여기서 공격자는 공격받은 프로그램의 버퍼를 이용해 공격코드를 저장한다. 버퍼는 스택(자동 변수), 힙(힙, 동적으로 할당된 메모리 영역), 정적 데이터 영역 등 어디에나 위치할 수 있습니다.

2. 기존 코드 활용:

때로는 공격자가 원하는 코드가 이미 공격당하는 프로그램에 있고, 공격자가 해야 할 일은 일부 매개변수를 코드에 전달하는 것뿐입니다. . 예를 들어, 공격 코드는 "exec("/bin/sh")"의 실행을 요구하고, libc 라이브러리의 코드는 "exec(arg)"를 실행합니다. 여기서 arg는 문자열을 가리키는 포인터 매개변수이고, 공격자는 전달된 매개변수 포인터를 "/bin/sh"를 가리키도록 리디렉션하기만 하면 됩니다.

2.2 제어 프로그램을 공격 코드로 전달하는 방법

이들 방법은 모두 프로그램의 실행 흐름을 변경하여 공격 코드로 점프하도록 하려고 합니다. 가장 기본적인 것은 경계 검사나 다른 약점 없이 버퍼를 오버플로하여 프로그램의 정상적인 실행 순서를 방해하는 것입니다. 버퍼 오버플로를 통해 공격자는 무차별 대입으로 인접한 프로그램 공간을 덮어쓰고 시스템 검사를 직접 건너뛸 수 있습니다.

분류 기준은 공격자가 버퍼 오버플로를 위해 악용하려는 프로그램 공간 유형입니다. 원칙적으로 어떤 공간이라도 될 수 있습니다. 실제로 많은 버퍼 오버플로는 무차별 대입 방법을 사용하여 프로그램 포인터를 변경하려고 합니다. 이러한 유형의 프로그램의 차이점은 프로그램 공간의 획기적인 발전과 메모리 공간의 위치 지정이 다르다는 것입니다. 주로 세 가지 유형이 있습니다. 1. 활성화 레코드:

함수 호출이 발생할 때마다 호출자는 함수 주소가 끝날 때 반환되는 정보가 포함된 활동 레코드를 스택에 남깁니다. 공격자는 반환 주소가 공격 코드를 가리키도록 스택의 자동 변수를 오버플로합니다. 프로그램의 반환 주소를 변경하여 함수 호출이 끝나면 프로그램은 원래 주소가 아닌 공격자가 설정한 주소로 점프합니다.

이러한 종류의 버퍼 오버플로를 스택 오버플로 공격(Stack Smashing Attack)이라고 하며, 현재 가장 일반적으로 사용되는 버퍼 오버플로 공격 방법이다.

2. 함수 포인터:

함수 포인터는 모든 주소 공간을 찾는 데 사용할 수 있습니다. 예를 들어, "void (* foo)()"는 반환 값이 void인 함수 포인터 변수 foo를 선언합니다. 따라서 공격자는 어떤 공간에서든 함수 포인터 근처에서 오버플로할 수 있는 버퍼를 찾은 다음 이 버퍼를 오버플로하여 함수 포인터를 변경하기만 하면 됩니다. 어느 순간 프로그램이 함수 포인터를 통해 함수를 호출하게 되면 공격자가 의도한 대로 프로그램의 흐름이 구현된다. 공격 사례 중 하나는 Linux 시스템의 superprobe 프로그램입니다.

3. Longjmp 버퍼:

C 언어에는 setjmp/longjmp라는 간단한 확인/복구 시스템이 포함되어 있습니다. 이는 체크포인트에 "setjmp(buffer)"를 설정하고 "longjmp(buffer)"를 사용하여 체크포인트를 복원하는 것을 의미합니다. 그러나 공격자가 버퍼 공간에 들어갈 수 있으면 "longjmp(buffer)"는 실제로 공격자의 코드로 점프합니다. 함수 포인터와 마찬가지로 longjmp 버퍼는 어디든 가리킬 수 있으므로 공격자가 해야 할 일은 오버플로할 버퍼를 찾는 것뿐입니다. 일반적인 예는 Perl 5.003의 버퍼 오버플로 취약점입니다. 공격자는 먼저 버퍼 오버플로를 복구하는 데 사용되는 longjmp 버퍼에 들어간 다음 복구 모드로 들어가도록 유도하여 Perl 해석기가 공격 코드로 점프하게 합니다.

2.3 코드 이식 및 프로세스 제어 기술 종합 분석

버퍼 오버플로 공격의 가장 간단하고 가장 일반적인 유형은 코드 이식과 활동을 문자열 녹음 기술에 결합하는 것입니다. 공격자는 오버플로될 수 있는 자동 변수를 찾아 큰 문자열을 프로그램에 전달하여 버퍼 오버플로를 유발하고 활동 기록을 변경하는 동시에 코드를 이식합니다. 이는 레비가 지적한 공격에 대한 템플릿이다. C는 전통적으로 사용자와 매개변수에 대해 작은 버퍼만 할당하기 때문에 이러한 취약점 공격 사례는 매우 흔합니다.

코드 삽입과 버퍼 오버플로가 반드시 한 번의 작업으로 완료될 필요는 없습니다. 공격자는 오버플로될 수 없는 버퍼인 버퍼 내부에 코드를 배치할 수 있습니다. 그런 다음 공격자는 다른 버퍼를 오버플로하여 프로그램 포인터를 전송합니다. 이 방법은 일반적으로 오버플로에 사용할 수 있는 버퍼가 충분히 크지 않은(모든 코드를 담을 수 없는) 상황을 해결하는 데 사용됩니다.

공격자가 외부에서 코드를 이식하는 대신 이미 상주하는 코드를 사용하려고 시도하는 경우 일반적으로 해당 코드를 매개 변수로 호출해야 합니다. 예를 들어 libc(거의 모든 C 프로그램을 연결해야 하는)의 일부 코드 세그먼트는 "exec(something)"을 실행합니다. 여기서 something은 매개변수입니다. 그런 다음 공격자는 버퍼 오버플로를 사용하여 프로그램 매개변수를 변경한 다음 또 다른 버퍼 오버플로를 사용하여 프로그램 포인터가 libc의 특정 코드 세그먼트를 가리키도록 했습니다.

3. 버퍼 오버플로 공격에 대한 실험적 분석

2000년 1월 Cerberus 보안 팀은 Microsoft IIS 4/5의 버퍼 오버플로 취약점을 공개했습니다. 이 취약점을 공격하면 웹 서버가 중단될 수 있으며 심지어 임의 코드를 실행할 수 있는 최고 권한을 얻을 수도 있습니다. 현재 Microsoft의 IIS 4/5는 주류 웹 서버 프로그램이므로 이 버퍼 오버플로 취약점은 웹 사이트 보안에 큰 위협이 됩니다.

IIS에 대한 브라우저는 HTTP를 만듭니다. 요청 시, 도메인 이름(또는 IP 주소) 뒤에 파일 이름을 추가하고 파일 이름 뒤에 ".htr"이 붙습니다. 따라서 IIS는 클라이언트가 ".htr" 파일을 요청하고 있으며 ".htr" 확장 파일이 ISAPI(인터넷 서비스 API) 응용 프로그램에 매핑되어 있다고 생각합니다. IIS는 ".htr" 리소스에 대한 모든 요청을 ISM으로 재설정합니다. DLL 프로그램 , ISM.DLL이 이 파일을 열고 실행합니다.

브라우저가 제출한 요청에 포함된 파일 이름은 로컬 변수 버퍼에 저장됩니다. 길이가 600자를 초과하면 로컬 변수 버퍼가 오버플로되어 반환 주소를 덮어쓰게 됩니다. 공간이 부족해 IIS 충돌이 발생합니다. 또한 그림 1과 같이 잘 설계된 코드를 2K 버퍼에 이식함으로써 시스템 최고 권한으로 실행할 수 있습니다.

4. 버퍼 오버플로 공격을 방지하는 방법

버퍼 오버플로 공격은 원격 네트워크 공격의 대부분을 차지하며, 이러한 종류의 공격은 익명의 인터넷 사용자에게 제어권을 얻을 수 있는 기회를 제공할 수 있습니다. 호스트의 일부 또는 전부. 버퍼 오버플로 취약점을 효과적으로 제거할 수 있다면 보안 위협의 상당 부분을 완화할 수 있습니다.

현재 버퍼 오버플로 공격 및 영향으로부터 버퍼를 보호하는 기본 방법에는 네 가지가 있습니다. 섹션 4.1에서는 공격자가 공격 코드를 심는 것을 방지하기 위해 운영 체제를 통해 버퍼를 실행 불가능하게 만드는 방법을 소개했습니다. 올바른 코드를 강제로 작성하는 방법은 4.2절에 소개되어 있습니다. 섹션 4.3에서는 버퍼 보호를 달성하기 위해 컴파일러 경계 검사 사용을 소개했습니다. 이 방법은 버퍼 오버플로를 불가능하게 하여 버퍼 오버플로의 위협을 완전히 제거하지만 비용이 상대적으로 높습니다. 4.4절에서는 간접적인 방법을 소개합니다. 이 방법은 프로그램 포인터가 유효하지 않게 되기 전에 무결성 검사를 수행합니다. 이 방법으로 모든 버퍼 오버플로를 물리칠 수는 없지만 대부분의 버퍼 오버플로 공격을 방지할 수 있습니다. 그런 다음 IV.5에서는 이 보호 방법의 호환성 및 성능 이점을 분석합니다.

IV.1 실행 불가능한 버퍼

공격받은 프로그램의 데이터 세그먼트 주소 공간을 실행 불가능하게 함으로써 공격자가 공격받은 프로그램의 입력 버퍼를 실행하는 것이 불가능하다. 프로그램의 코드 영역에서 이 기술을 실행 불가능 버퍼 기술이라고 합니다. 초기 Unix 시스템 설계에서는 프로그램 코드만 코드 세그먼트에서 실행되도록 허용되었습니다. 그러나 최근 Unix 및 MS Windows 시스템에서는 더 나은 성능과 기능을 달성하기 위해 데이터 세그먼트에 실행 가능한 코드를 동적으로 배치하는 경우가 많으며, 이는 버퍼 오버플로의 원인이기도 합니다. 프로그램 호환성을 유지하기 위해 모든 프로그램의 데이터 세그먼트를 실행 불가능하게 만드는 것은 불가능합니다.

그러나 스택 데이터 세그먼트는 실행 불가능하도록 설정하여 프로그램 호환성을 보장할 수 있습니다. Linux와 Solaris 모두 이와 관련하여 커널 패치를 출시했습니다. 합법적인 프로그램이 스택에 코드를 저장하는 경우가 거의 없기 때문에 이 접근 방식은 실행 가능한 코드를 스택에 배치해야 하는 Linux의 두 가지 특별한 경우를 제외하고는 호환성 문제를 거의 일으키지 않습니다.

(1) 신호 전달:

Linux는 코드를 프로세스 스택에 공개한 다음 인터럽트를 트리거하여 스택의 코드를 실행함으로써 프로세스에 Unix 신호를 보냅니다. 실행 불가능한 버퍼용 패치를 사용하면 신호를 보낼 때 버퍼를 실행할 수 있습니다.

(2) GCC의 온라인 재사용:

연구에 따르면 gcc는 온라인 재사용을 위해 스택 영역에 실행 코드를 배치하는 것으로 나타났습니다. 하지만 이 기능을 꺼도 아무런 문제가 발생하지 않고, 일부 기능만 사용할 수 없는 것 같습니다.

비실행 스택 보호는 자동 변수에 코드를 삽입하는 버퍼 오버플로 공격을 효과적으로 처리할 수 있지만 다른 형태의 공격에는 영향을 미치지 않습니다. 상주 프로그램에 대한 포인터를 참조하여 이 보호를 우회할 수 있습니다. 다른 공격은 힙 또는 정적 데이터 세그먼트에 코드를 삽입하여 보호를 우회할 수 있습니다.

IV.2 올바른 코드 작성

올바른 코드를 작성하는 것은 매우 의미 있는 작업입니다. 특히 C 언어와 같이 자유 스타일이고 오류가 발생하기 쉬운 프로그램을 작성하는 것은 이러한 스타일 때문입니다. 정확성을 무시하고 성과를 추구하는 것입니다. 사람들이 안전한 프로그램을 작성하는 방법을 알기까지는 오랜 시간이 걸렸지만 보안에 취약한 프로그램은 여전히 ​​등장했습니다. 따라서 경험이 부족한 프로그래머가 안전하고 올바른 프로그램을 작성할 수 있도록 도구와 기술이 개발되었습니다.

가장 쉬운 방법은 grep을 사용하여 strcpy 및 sprintf 호출과 같이 소스 코드에서 취약한 라이브러리 호출을 검색하는 것입니다. 실제로 C 표준 라이브러리의 모든 버전에는 이러한 문제가 있습니다.

또한 사람들은 오류 주입과 같은 고급 오류 검사 도구도 개발했습니다. 이러한 도구의 목적은 일부 버퍼 오버플로를 인위적으로 무작위로 생성하여 코드의 보안 취약점을 찾는 것입니다. 버퍼 오버플로의 존재를 감지하는 데 사용되는 정적 분석 도구도 있습니다.

이러한 도구는 프로그래머가 보다 안전한 프로그램을 개발하는 데 도움이 되지만 C 언어의 특성상 모든 버퍼 오버플로 취약점을 찾아내는 것은 불가능합니다. 따라서 디버깅 기술은 버퍼 오버플로 가능성을 줄이는 데에만 사용할 수 있지만 버퍼 오버플로의 존재를 완전히 제거할 수는 없습니다.

copyright 2024중국오락넷