2011-09-05 3 views
10

이 두 유형의 공격의 정확한 차이점을 이해하고 싶습니다. 읽은 내용 :차이점 - 버퍼 오버플로 및 libc 공격으로 돌아 가기

버퍼 오버플로 : 스택의 ret 주소를 악성 코드가 삽입 된 코드의 다른 섹션을 가리 키도록 덮어 씁니다. 그래서 효과적으로 - 실제로 공격을 수행하기 위해 프로그램의 소스 코드를 수정해야합니다.

로 돌아 가기 Libc-로 돌아 가기 소스 코드를 수정하는 대신 C 라이브러리에서 제공하는 런타임 함수 호출이 사용됩니다 (예 : 셸 열기). 여기서 함수 호출에 사용 된 매개 변수는 스택의 ret 부분 이후에 끝나는 덮어 쓰기 버퍼에도 전달됩니다.

위 내용이 정확한 설명입니까?

그리고 또 다른 관련 질문 - 원래 프로그램의 소스 코드를 실제로 수정하지 않고도 버퍼 오버 플로우 공격이 가능합니까? 아마도 새 프로그램을 작성하여 메모리의 특정 섹션 (원래 프로그램의 손상된 스택에있는 새 재시도 주소)을 수정할 수있는 경우 일 것입니다. 그렇다면 커널에서 프로세스간에 제공되는 메모리 보호로 인해 이것이 가능하지 않을 수도 있습니다.

답변

12

기존의 버퍼 오버 플로우 익스플로잇에서 오버플로되는 스택 버퍼는 실행할 머신 코드 (일반적으로 쉘 프로세스를 호출했기 때문에 쉘 코드라고 함)와 새 리턴 주소로 채워져 있습니다. 새로운 반환 주소는 오버플로 된 스택 버퍼 자체를 가리 키도록 제작됩니다. 분명히, 공격 된 프로세스에서 스택 버퍼의 주소를 알고 추측해야합니다.

그 당시에는 프로세스의 메모리 레이아웃이 일반적으로 매우 결정적이었습니다. 스택 버퍼의 위치는 일반적으로 공격자가 상당히 잘 예측할 수있었습니다 (특히 공격 대상 소프트웨어의 버전을 정확히 알고있는 경우). 어떤 추측이 있었을 때의 성공 가능성을 높이기 위해, "NOP sled"또는 "NOP slide"라고 불리는 유용한 실행을 수행하지 못한 많은 양의 실행 가능한 기계 코드가 활성 쉘 코드 앞에 놓이는 경우가있었습니다. 여기서 "NOP" "No Operation"을 수행하는 기계어 명령어의 일반적인 이름입니다. NOP 썰매의 어떤 지점으로 돌아 가면 원하는 효과를 얻을 수 있습니다.

반면에 "return-to-libc"악용은 도용 된 프로세스가 쉘 코드로 직접 돌아 가지 않습니다. 대신, 프로세스가 하나씩 라이브러리 함수 체인의 시작으로 리턴됩니다. 이러한 라이브러리 함수는 공격자가 원하는 작업을 직접 수행 할 수 있지만 일반적으로 공격자의 쉘 코드를 간접적으로 실행하는 데 사용됩니다.

0

실제로는 버퍼 오버 플로우 공격에서 ret 포인터를 무시하면서 악성 코드를 삽입합니다. 결론적으로 언급 된 두 공격의 차이를 볼 수는 없으므로이를 위해 아무 것도 수정할 필요가 없습니다. 예를 들어

:

char* str[5];
cin << str;

이것은 사용자가 덮어 쓰게됩니다 다음 스택에 문자열을보다 큰 5 개 문자, 모두를 삽입하는 경우, exploided 할 수있는 코드입니다. 그리고 ret-ptr이 스택에서 "더 낮습니다"라는 사실 때문에, 당신이 거리를 올바르게 얻었 으면 그것을 오버라이드 할 수 있습니다. 재정의 할 때의 의도는 ret-ptr이 호출되고 "점프"가 실행되는 즉시 실행되는 악의적 인 (어셈블러) 코드를 삽입 한 입력의 시작 부분을 가리 키도록하려는 것입니다.

4

ret 주소를 덮어 쓰는 부분은 두 공격간에 공유됩니다. 위의 답에서 알 수 있듯이, 이전에 작성한 어셈블리 코드로 돌아갔다. 이 어셈블리 코드는 루트 사용자 쉘을 생성합니다.

공격을하지 않으면 소스 코드를 '덮어 씁니다'. 어셈블리 관점에서 볼 때, 소스 코드는 .text 세그먼트에 있고 항상 (또는 적어도 내가 아는 모든 시간 동안) 쓰기 금지되어있다. 이전에 메모리 세그먼트에 어셈블 한 코드를 작성한 다음이 코드로 건너 뛰었습니다. 코드는 가장 일반적으로 '스택 세그먼트'또는 그 근처에 위치하며, 오버플로하도록 선택하면 오버플로하여 ret 주소 (예 :)에서 트래픽을 리디렉션합니다. 다른 공격 장소에는 이전에 작성하여 쉘 코드로 채운 환경 변수가 포함됩니다. 또는 힙, 또는 함수 포인터, 또는 PLT. 이렇게 삽입 된 코드는 일반적으로 system() 호출을 사용하여 원하는 것을 실행합니다. 그러나이를 위해 메모리 영역에서 '실행할'수 있어야합니다 (또는 사용하려는 재배치 엔트리를 쓰기 가능으로 선언해야합니다).

두 공격의 차이점은 일단 메모리가 대부분 실행 불가능하게되면 공격 유형 a (스택 오버플로)가 상당히 망가질 수 있다는 것입니다. 그런 다음이 유형의 공격을 우회하려는 시도가 작성되면 공유 라이브러리 함수에 직접 액세스합니다. 즉, 더 이상 스택 세그먼트 또는 다른 곳에 코드를 작성하여 실행하지 않아도됩니다. 그러나 나는 libc 유형의 공격이 현재까지 크게 영향을 받았다고 믿는다; 나는 세부 사항을 유용하게 가지고 있지 않다; 어쩌면 내가 틀렸어.

이러한 공격이 요즘 어떻게 저지되고 있는지, 또는 몇 가지 핵심 아이디어에 대해 알고 싶다면 Google의 '2011 년에 스매쉬 스택'(또는 2010)을 시작하십시오.

+0

무슨 뜻인지 설명해 주시겠습니까? 메모리를 실행 가능 (또는 비 실행 가능)로 설정하십시오. 그리고 다른 의심 (내 원래 질문의 일부)은 - 나는 C 코드가 메인 메모리의 모든 부분에 액세스하지 못할 것이라고 믿는다. 악의적 인 어셈블리 코드가 메모리에 저장되는 위치는 어떻게 확인됩니까? 대부분의 메모리 영역을 생각하기 때문에 거기에 돌아 왔을 때 세분화 오류가 표시됩니다. – Hari

+0

삽입하는 익스플로잇 코드의 핵심은 일반적으로 패밀리 스타일 기능을 사용하고 exec()입니다. 즉, 적절한 매개 변수를 입력하면 루트 사용자로/bin/sh 쉘을 생성 할 수 있습니다. 이것은 프로그램을 실행하고 * 더 이상 할 수 없습니다. 다양한 보안 조치가 있지만이 내용은 예를 들어 – gnometorule

+0

http://en.wikipedia.org/wiki/NX_bit에 설명되어 있습니다. – gnometorule

4

나는 버퍼 오버 플로우이이 개발 기술이다과 libc 프로그래밍 오류 및 수익의 클래스입니다 말할 것입니다. 개념을 함께 사용하지 않는 것이 가장 좋습니다.

예를 들어, 당신은 버퍼 오버 플로우 취약점을 악용 할을과 libc 수익을 사용할 수 있습니다. 또는 과 같은 다른 기술을 사용할 수 있습니다. 또는 쉘 코드로 돌아 가기. 반대로 을 libc으로 반환하여 형식 문자열과 같은 다른 버그를 악용 할 수도 있습니다.