중화사전망 - 자전 검색 - 버퍼 오버플로 공격의 기본 원리는 무엇입니까?
버퍼 오버플로 공격의 기본 원리는 무엇입니까?
1. 개념
버퍼 오버플로란 컴퓨터가 데이터 비트로 버퍼를 채울 때 버퍼 자체의 용량을 초과하는 오버플로된 데이터를 합법적인 데이터로 덮어쓴다는 의미입니다. 이상적으로 프로그램은 데이터 길이를 검사하고 버퍼 길이를 초과하는 문자는 입력할 수 없지만, 대부분의 프로그램은 데이터 길이가 항상 할당된 스토리지 공간과 일치하는 것으로 간주하여 버퍼 오버플로에 숨겨진 위험을 안고 있습니다. 운영 체제에서 사용하는 버퍼를 스택이라고도 합니다. 각 작업 중에 명령은 일시적으로 "스택" 에 저장됩니다.
2. 손해
현재의 네트워크 및 분산 시스템 보안 중 50% 이상이 버퍼 오버플로우에 널리 사용되고 있으며, 가장 유명한 예는 1988 에서 fingerd 취약점을 이용하는 웜입니다. 버퍼 오버플로에서 가장 위험한 것은 스택 오버플로입니다. 침입자가 스택 오버플로를 사용하여 함수가 반환될 때 반환 프로그램의 주소를 변경하여 임의의 주소로 이동할 수 있기 때문입니다. 한 가지 위험은 프로그램 충돌로 인해 서비스가 거부되는 것이고, 다른 하나는 악성 코드 (예: 하우징 가져오기 및 원하는 대로 수행) 를 점프하는 것입니다.
3. 버퍼 공격
1. 버퍼 오버플로 원리
길이를 초과하는 내용을 프로그램 버퍼에 기록하여 버퍼 오버플로를 통해 프로그램 스택을 파괴하고 프로그램이 다른 명령을 실행하여 공격 목적을 달성하도록 합니다. 버퍼 오버플로는 프로그램에서 사용자가 입력한 매개변수를 자세히 확인하지 않았기 때문입니다. 예를 들면 다음과 같습니다.
Voidfunction(char*str){
Charbuffer [16];
Strcpy (버퍼, str);
}
위의 Strcpy () 는 str 의 내용을 buffer 로 직접 복사합니다. 이렇게 하면 str 의 길이가 16 보다 크면 버퍼 오버플로가 발생하여 프로그램이 제대로 실행되지 않을 수 있습니다. Strcpy 와 같은 문제가 있는 표준 함수로는 strcat (), sprintf (), vsprintf (), gets (), scanf () 등이 있습니다.
물론, 버퍼를 임의로 채워 오버플로우시키는 것은 일반적으로 "Segmentationfault" 로 이어질 뿐 공격의 목적을 달성하지 못한다. 가장 일반적인 방법은 버퍼 오버플로를 만들어 프로그램에서 사용자 셸을 실행한 다음 셸을 통해 다른 명령을 실행하는 것입니다. 프로그램이 루트에 속하고 suid 권한이 있는 경우 공격자는 루트 권한을 가진 셸을 얻어 운영 체제를 자유롭게 조작할 수 있습니다.
버퍼 오버플로 공격은 버퍼 오버플로 취약점이 너무 일반적이고 구현하기 쉽기 때문에 일반적인 보안 공격 수단이되었습니다. 버퍼 오버플로우는 공격자가 원하는 모든 것, 즉 공격 코드를 이식하고 실행하기 때문에 원격 공격의 주요 수단이 되었습니다. 시드된 공격 코드는 버퍼 오버플로우 취약점이 있는 프로그램을 특정 권한으로 실행하여 공격받는 호스트의 제어권을 얻습니다.
1998 에서 링컨 연구소가 침입 탐지를 평가하는 데 사용하는 다섯 가지 원격 공격 중 두 가지는 버퍼 오버플로입니다. 1998 에서 CERT 의 13 개 권장 사항 중 9 개는 버퍼 오버플로와 관련이 있고 1999 에서는 최소 절반이 버퍼 오버플로와 관련이 있습니다. Bugtraq 설문 조사에서 응답자의 3 분의 2 는 버퍼 오버플로 취약점이 매우 심각한 보안 문제라고 생각했습니다.
버퍼 오버플로우 취약점과 공격은 여러 가지 형태가 있으며, 두 번째 부분에서 설명하고 분류할 것입니다. 이에 따라 방어 수단은 공격 방식에 따라 다르며, 이는 4 절에서 설명되며, 여기에는 각 공격 유형에 대한 효과적인 방어 수단이 포함되어 있습니다.
둘째, 버퍼 오버플로 취약점과 공격
버퍼 오버플로우 공격의 목적은 특정 권한을 가진 프로그램의 기능을 방해하여 공격자가 프로그램을 제어할 수 있도록 하는 것입니다. 프로그램에 충분한 권한이 있으면 전체 호스트가 제어됩니다. 일반적으로 공격자는 루트 프로그램을 공격하고' exec(sh)' 와 같은 실행 코드를 실행하여 루트 권한이 있는 셸을 얻습니다. 이 목표를 달성하기 위해서는 공격자가 다음 두 가지 목표를 달성해야 합니다.
1. 프로그램의 주소 공간에 적절한 코드를 배치합니다.
2. 적절한 초기화 레지스터와 메모리를 통해 프로그램이 침입자가 배정한 주소 공간으로 점프하도록 합니다.
이 두 가지 목표에 따라 버퍼 오버플로우 공격이 분류되었다. II. 1 섹션에서는 공격 코드가 공격 대상 프로그램의 주소 공간에 어떻게 배치되는지 설명합니다. 섹션 2.2 에서는 공격자가 프로그램의 버퍼를 오버플로우하고 실행을 공격 코드로 전송하는 방법에 대해 설명합니다 (이것이 바로 "오버플로우" 의 유래). 섹션 II.3 에서는 이전 섹션에서 설명한 코드 정렬 및 프로그램 실행 제어 기술을 통합합니다.
둘. 1 프로그램 주소 공간에 적절한 코드를 배치하는 방법
공격받는 프로그램의 주소 공간에 공격 코드를 정렬하는 두 가지 방법이 있습니다.
1, 이식 방법:
공격자는 공격당한 프로그램에 문자열을 입력하면 프로그램이 이 문자열을 버퍼에 넣습니다. 이 문자열에 포함된 데이터는 공격받는 하드웨어 플랫폼에서 실행할 수 있는 명령 시퀀스입니다. 여기서 공격자는 공격 프로그램의 버퍼를 사용하여 공격 코드를 저장합니다. 버퍼는 스택 (자동 변수), 힙 (동적으로 할당된 메모리 영역) 및 정적 데이터 영역 등 어느 곳에나 설정할 수 있습니다.
2, 기존 코드 사용:
때때로 공격자가 원하는 코드는 이미 공격받는 프로그램에 있으며 공격자가 해야 할 일은 코드에 매개 변수를 전달하는 것입니다. 예를 들어, 공격 코드는 "exec ("/bin/sh") "를 요구하고, libc 라이브러리의 코드는" exec(arg) "를 실행합니다. 여기서 arg 는 문자열에 대한 포인터 매개 변수를 만드는 경우 공격자는 들어오는 매개 변수 포인터를"/bin "으로 변경하기만 하면 됩니다
II.2 제어 프로그램을 공격 코드로 전송하는 방법
이러한 모든 방법은 프로그램 실행을 변경하여 공격 코드로 점프하도록 하는 것입니다. 가장 기본적인 것은 경계 검사나 다른 약점 없이 버퍼를 넘쳐서 프로그램의 정상적인 실행 순서를 방해하는 것이다. 오버플로우 버퍼를 통해 공격자는 인접한 프로그램 공간을 폭력적으로 다시 작성하여 시스템 검사를 직접 건너뛸 수 있습니다.
분류 기준은 공격자가 버퍼 오버플로를 찾는 프로그램 공간의 유형입니다. 원칙적으로 모든 공간이 될 수 있습니다. 사실, 많은 버퍼 오버플로는 폭력적인 방법으로 프로그램 포인터를 변경하려고 시도한다. 이러한 프로그램의 차이점은 프로그램 공간의 돌파구와 메모리 공간의 위치가 다르다는 것입니다. 1 및 ActivationRecords 의 세 가지 주요 유형이 있습니다.
함수 호출이 발생할 때마다 호출자는 함수가 끝날 때 반환된 주소가 포함된 활성 레코드를 스택에 남겨 둡니다. 공격자는 스택의 자동 변수를 오버플로우하여 반환 주소가 공격 코드를 가리키도록 합니다. 프로그램의 반환 주소를 변경하여 함수 호출이 끝나면 프로그램은 원래 주소가 아닌 공격자가 설정한 주소로 이동합니다. 스택 오버플로우 공격이라고 하는 이러한 버퍼 오버플로우는 현재 가장 일반적으로 사용되는 버퍼 오버플로우 공격입니다.
2. 함수 포인터:
함수 포인터는 모든 주소 공간을 찾는 데 사용할 수 있습니다. 예를 들어 "void(*foo) ()" 는 void 값을 반환하는 함수 포인터 변수 foo 를 선언합니다. 따라서 공격자는 임의의 공간의 함수 포인터 근처에서 오버플로우 버퍼를 찾은 다음 이 버퍼를 넘쳐서 함수 포인터를 변경하기만 하면 됩니다. 특정 시점에서 프로그램이 함수 포인터를 통해 함수를 호출하면 프로그램 프로세스가 공격자의 의도에 따라 구현됩니다. 공격의 한 예는 Linux 시스템의 superprobe 프로그램이다.
3.Longjmpbuffers:
C 언어에는 setjmp/longjmp 라는 간단한 검사/복구 시스템이 포함되어 있습니다. 체크포인트에' setjmp(buffer)' 를 설정하고' longjmp(buffer)' 로 체크포인트를 복구한다는 뜻이다. 그러나 공격자가 버퍼 공간으로 들어갈 수 있는 경우 "longjmp(buffer)" 는 실제로 공격자로 이동하는 코드입니다. 함수 포인터와 마찬가지로 longjmp 버퍼는 아무 곳이나 가리킬 수 있으므로 공격자가 해야 할 일은 오버플로우 버퍼를 찾는 것입니다. 전형적인 예는 Perl5.003 의 버퍼 오버플로우 취약점입니다. 공격자는 먼저 복구 버퍼 오버플로를 위한 longjmp 버퍼로 들어간 다음 복구 모드로 유도되어 Perl 인터프리터가 공격 코드로 점프할 수 있도록 합니다.
2.3 코드 이식 및 프로세스 제어 기술 종합 분석
가장 간단하고 가장 일반적인 버퍼 오버플로우 공격 유형은 문자열에 코드 이식과 활동 기록 기술을 결합한 것입니다. 공격자는 오버플로된 자동 변수를 찾은 다음 프로그램에 큰 문자열을 전달하여 버퍼 오버플로를 발생시키고 코드를 포함하는 동안 활성 레코드를 변경합니다. 이것은 리비가 지적한 공격의 본보기이다. C 는 습관적으로 사용자와 매개변수에 작은 버퍼만 열어 주기 때문에 이런 허점 공격은 흔히 볼 수 있다.
코드 이식 및 버퍼 오버플로는 한 동작에서 수행할 필요가 없습니다. 공격자는 오버플로할 수 없는 버퍼에 코드를 배치할 수 있습니다. 그런 다음 공격자는 다른 버퍼를 넘침으로써 프로그램의 포인터를 전송합니다. 이 방법은 일반적으로 오버플로우에 사용할 수 있는 버퍼가 충분히 크지 않은 경우 (모든 코드를 놓을 수 없는 경우) 를 해결하는 데 사용됩니다.
공격자가 외부에서 코드를 이식하는 대신 이미 상주하는 코드를 사용하려고 하면 일반적으로 코드를 인수로 호출해야 합니다. 예를 들어, libc 의 일부 코드 조각 (거의 모든 C 프로그램에 연결해야 함) 은 "exec(something)" 을 실행합니다. 여기서 something 은 매개변수입니다. 그런 다음 공격자는 버퍼 오버플로우를 사용하여 프로그램의 매개변수를 변경하고 다른 버퍼 오버플로우를 사용하여 프로그램 포인터가 libc 의 특정 조각을 가리키게 합니다.
셋째, 버퍼 오버플로 공격의 실험적 분석
5438 년 6 월 +2000 년 10 월, Cerberus 보안팀은 Microsoft IIS4/5 에서 버퍼 오버플로우 취약점을 발표했습니다. 이 취약점을 공격하면 웹 서버가 충돌하고 모든 코드를 실행할 수 있는 수퍼 권한을 얻을 수 있습니다. 현재 Microsoft 의 IIS4/5 는 주요 웹 서버 프로그램입니다. 따라서 버퍼 오버플로우 취약점은 웹 사이트의 보안에 큰 위협이 됩니다. 그 설명은 다음과 같습니다.
브라우저는 IIS 에 HTTP 요청을 하고 도메인 이름 (또는 IP 주소) 뒤에 "."가 있는 파일 이름을 추가합니다. Htr "을 접미사로 사용합니다. 따라서 IIS 는 클라이언트가 "을 (를) 요청했다고 생각합니다. Htr "파일 및. Htr "확장 파일은 ISAPI(InternetServiceAPI) 응용프로그램에 매핑됩니다. IIS 는 \ "\" 에 대한 모든 요청을 재설정합니다. Htr' 리소스를 ISM.DLL 프로그램에 연결하면 ISM.DLL 에서 이 파일을 열고 실행합니다.
브라우저가 제출한 요청에 포함된 파일 이름은 로컬 변수 버퍼에 저장됩니다. 길이가 길고 600 자를 초과하면 로컬 변수 버퍼 오버플로가 발생하여 반환 주소 공간을 덮어쓰게 되어 IIS 가 충돌합니다. 또한 1 과 같이 잘 설계된 코드를 2K 버퍼에 삽입하여 시스템 수퍼 권한으로 실행할 수 있습니다.
넷째, 버퍼 오버플로 공격 방지 방법
버퍼 오버플로우 공격은 대부분의 원격 네트워크 공격의 원인이며, 이를 통해 익명 인터넷 사용자는 호스트에 대한 일부 또는 전체 제어를 받을 수 있습니다. 버퍼 오버플로우 취약점을 효과적으로 제거할 수 있다면 보안 위협의 상당 부분을 완화할 수 있습니다.
현재 버퍼 오버플로의 공격과 영향으로부터 버퍼를 보호하는 네 가지 기본 방법이 있습니다. 4. 1 에서는 운영 체제가 버퍼를 실행할 수 없도록 하여 공격자가 공격 코드를 이식하는 것을 방지하는 방법에 대해 설명합니다. IV.2 에서는 올바른 코드를 강제로 작성하는 방법에 대해 설명합니다. 4.3 장에서는 컴파일러의 경계 검사를 사용하여 버퍼를 보호하는 방법에 대해 설명합니다. 이 방법은 버퍼 오버플로를 불가능하게 하여 버퍼 오버플로의 위협을 완전히 제거하지만 상대적으로 비용이 많이 듭니다. 4.4 에서는 프로그램 포인터가 고장나기 전에 무결성을 확인하는 간접적인 방법이 도입되었습니다. 이 방법으로 모든 버퍼 오버플로를 무효화할 수는 없지만 대부분의 버퍼 오버플로 공격을 방지할 수 있습니다. 그런 다음 IV.5 에서는 이러한 보호 방식의 호환성 및 성능 이점을 분석했습니다.
넷. 1 비실행 버퍼
공격받는 프로그램의 데이터 세그먼트의 주소 공간을 실행할 수 없게 함으로써 공격자는 공격받는 프로그램의 입력 버퍼를 이식하는 코드를 실행할 수 없습니다. 이 기술을 비 실행 버퍼 기술이라고합니다. 이전 Unix 시스템 설계에서는 코드 조각에서 프로그램 코드만 실행할 수 있었습니다. 그러나 최근 Unix 및 MSWindows 시스템에서는 성능과 기능을 향상시키기 위해 실행 코드가 데이터 세그먼트에 동적으로 배치되는 경우가 많습니다. 이것이 버퍼 오버플로의 근본 원인입니다. 프로그램 호환성을 유지하기 위해 모든 프로그램의 데이터 세그먼트를 실행할 수 없습니다.
그러나 스택 데이터 세그먼트는 프로그램 호환성을 보장하기 위해 실행할 수 없도록 설정할 수 있습니다. Linux 와 Solaris 모두 이 방면의 커널 패치를 발표했다. 스택에 코드를 저장하는 합법적인 프로그램이 거의 없기 때문에 이 방법은 호환성 문제를 거의 발생시키지 않습니다. 단, Linux 의 두 가지 특수한 경우를 제외하고는 실행 코드를 스택에 배치해야 합니다.
(1) 신호 전송:
Linux 는 프로세스 스택에 코드를 해제한 다음 인터럽트를 발생시켜 스택에서 코드를 실행함으로써 프로세스에 Unix 신호를 보냅니다. 실행 버퍼가 아닌 패치를 사용하면 신호를 보낼 때 버퍼를 실행할 수 있습니다.
(2) 온라인 재사용 2)GCC:
Gcc 가 온라인 재사용을 위해 실행 코드를 스택 영역에 두는 것을 발견했습니다. 그러나 이 기능을 꺼도 문제가 발생하지 않지만 일부 기능은 사용할 수 없는 것 같습니다.
비실행 스택 보호는 코드가 자동 변수에 포함된 버퍼 오버플로우 공격에 효과적으로 대응할 수 있지만 다른 형태의 공격에는 영향을 주지 않습니다. 데몬에 대한 포인터를 참조하여 이러한 보호를 무시할 수 있습니다. 다른 공격은 힙 또는 정적 데이터 세그먼트에 코드를 이식하여 보호를 우회할 수 있습니다.
IV.2 올바른 코드 작성
정확한 코드를 쓰는 것은 의미 있는 일이다. 특히 C 언어로 풍격이 자유롭고 오류가 발생하기 쉬운 프로그램을 쓰는 것은 성능을 추구하고 정확성을 무시하는 전통으로 인한 것이다. 사람들이 보안 프로그램을 작성하는 방법을 아는 데 오랜 시간이 걸렸지만 보안 취약점이 있는 절차가 나타났다. 따라서 경험이 없는 프로그래머가 안전하고 정확한 프로그램을 작성할 수 있도록 도구와 기술을 개발했습니다.
가장 쉬운 방법은 grep 를 사용하여 입력 매개변수의 길이를 확인하지 않는 strcpy 및 sprintf 호출과 같이 소스 코드에서 취약성이 발생하기 쉬운 라이브러리 호출을 검색하는 것입니다. 사실 모든 버전의 C 표준 라이브러리에 이런 문제가 있다.
또한 faultinjection 과 같은 고급 오류 감지 도구도 개발되었습니다. 이러한 도구의 목적은 인위적으로 버퍼 오버플로를 생성함으로써 코드의 보안 취약점을 발견하는 것입니다. 버퍼 오버플로의 존재를 감지할 수 있는 정적 분석 도구도 있습니다.
이러한 도구는 프로그래머가 보다 안전한 프로그램을 개발하는 데 도움이 되지만 C 언어의 특성으로 인해 모든 버퍼 오버플로우 취약점을 발견할 수는 없습니다. 따라서 디버깅 기술은 버퍼 오버플로의 가능성을 줄이는 데만 사용할 수 있으며, 그 존재를 완전히 막을 수는 없습니다.