Stack Canaries

htARTE (HackTricks AWS Red Team Expert)를 통해 AWS 해킹을 처음부터 전문가까지 배우세요 htARTE (HackTricks AWS Red Team Expert)!

HackTricks를 지원하는 다른 방법:

StackGuard와 StackShield

StackGuardEIP (Extended Instruction Pointer) 앞에 특별한 값을 삽입하는데, 이를 카나리라고 하며, 버퍼 오버플로우로부터 보호하기 위해 0x000aff0d (null, newline, EOF, carriage return을 나타냄)를 특별히 삽입합니다. 그러나 recv(), memcpy(), read(), bcopy()와 같은 함수들은 취약하며, **EBP (Base Pointer)**를 보호하지 않습니다.

StackShield는 **전역 반환 스택(Global Return Stack)**을 유지함으로써 StackGuard보다 더 정교한 방식을 취합니다. 이 스택은 모든 반환 주소 (EIPs)를 저장하며, 오버플로우가 발생해도 피해를 입히지 않도록 하기 위해 저장된 반환 주소와 실제 반환 주소를 비교하여 오버플로우 발생을 감지합니다. 또한 StackShield는 반환 주소를 경계 값과 비교하여 EIP가 예상 데이터 공간 외부를 가리키는지 여부를 감지할 수 있습니다. 그러나 이 보호 기능은 Return-to-libc, ROP (Return-Oriented Programming), 또는 ret2ret과 같은 기술을 통해 우회될 수 있으며, 이는 StackShield가 로컬 변수를 보호하지 않음을 의미합니다.

스택 스매시 프로텍터 (ProPolice) -fstack-protector:

이 메커니즘은 EBP 앞에 카나리를 배치하고, 로컬 변수를 재배치하여 버퍼가 다른 변수를 덮어쓰지 못하도록 높은 메모리 주소에 버퍼를 배치합니다. 또한 스택 위에 전달된 인수를 안전하게 복사하고 이 복사본을 인수로 사용합니다. 그러나 8개 미만의 요소를 가진 배열이나 사용자 구조체 내의 버퍼를 보호하지 않습니다.

카나리/dev/urandom에서 파생된 무작위 숫자이거나 기본 값인 0xff0a0000입니다. 이는 **TLS (Thread Local Storage)**에 저장되어 스레드 간에 공유 메모리 공간을 가지고 있어 스레드별 전역 또는 정적 변수를 가질 수 있습니다. 이러한 변수들은 초기에 부모 프로세스에서 복사되며, 자식 프로세스는 부모나 형제에 영향을 미치지 않고 데이터를 변경할 수 있습니다. 그러나 새로운 카나리를 생성하지 않고 fork()를 사용하면 모든 프로세스(부모 및 자식)가 동일한 카나리를 공유하므로 취약해집니다. i386 아키텍처에서 카나리는 gs:0x14에, x86_64에서는 fs:0x28에 저장됩니다.

이 로컬 보호는 공격에 취약한 버퍼를 가진 함수를 식별하고, 이러한 함수의 시작 부분에 카나리를 배치하고 무결성을 확인하기 위해 함수 끝에 코드를 삽입합니다.

웹 서버가 fork()를 사용하면 카나리를 한 바이트씩 추측하는 브루트 포스 공격을 활성화할 수 있습니다. 그러나 fork()execve()를 사용하면 메모리 공간이 덮어쓰여 공격이 무효화됩니다. vfork()는 쓰기를 시도할 때까지 중복 없이 자식 프로세스가 실행되도록 하며, 쓰기를 시도하면 중복이 생성되어 프로세스 생성 및 메모리 처리에 대한 다른 접근 방식을 제공합니다.

길이

x64 바이너리에서 카나리 쿠키는 0x8 바이트 큐워드입니다. 첫 일곱 바이트는 무작위이며, 마지막 바이트는 널 바이트입니다.

x86 바이너리에서 카나리 쿠키는 0x4 바이트 dword입니다. 첫 세 바이트는 무작위이며, 마지막 바이트는 널 바이트입니다.

두 카나리의 가장 낮은 유효 바이트는 널 바이트이며, 낮은 주소에서 스택으로부터 올 것이므로 문자열을 읽는 함수는 그것을 읽기 전에 중지합니다.

우회

카나리를 유출하고 그 값을 덮어쓰기(예: 버퍼 오버플로우)합니다.

  • 자식 프로세스에서 카나리가 생성된 경우 한 번에 한 바이트씩 브루트 포스할 수 있습니다:

pageBF Forked & Threaded Stack Canaries
  • 이진 파일에서 카나리를 인쇄할 수 있는 경우:

pagePrint Stack Canary
  • 스택에 저장된 포인터 덮어쓰기

스택이 스택 오버플로우에 취약하면 덮어쓸 수 있는 문자열 또는 함수 주소가 포함될 수 있으며, 스택 카나리에 도달하지 않고도 취약점을 악용할 수 있습니다. 확인:

pagePointer Redirecting
  • 마스터 및 스레드 카나리 수정

카나리로 보호된 스레드 함수에서 발생하는 버퍼 오버플로우를 사용하여 스레드의 마스터 카나리를 수정할 수 있습니다. 결과적으로, 수정된 두 카나리를 사용하여 검사하는 데 사용되는 두 카나리가 동일하므로(수정되었음에도 불구하고) 보호가 무용지물이 됩니다.

또한, 카나리로 보호된 스레드 함수에서 발생하는 버퍼 오버플로우를 사용하여 TLS에 저장된 마스터 카나리를 수정할 수 있습니다. 이는 스레드의 스택에서 bof를 통해 TLS가 저장된 메모리 위치에 도달할 수 있기 때문입니다. 결과적으로, 수정된 두 카나리를 사용하여 검사하는 데 사용되는 두 카나리가 동일하므로(수정되었음에도 불구하고) 보호가 무용지물이 됩니다. 이 공격은 다음 writeup에서 수행됩니다: http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads

또한 https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015의 발표를 확인하십시오. 이 발표에서는 보통 TLS가 **mmap**에 의해 저장되며, 스레드스택이 생성될 때도 이와 같이 mmap에 의해 생성된다고 언급합니다. 이는 이전 writeup에서 보여진 것처럼 오버플로우를 허용할 수 있습니다.

  • __stack_chk_fail의 GOT 항목 수정

이진 파일이 Partial RELRO를 가지고 있다면, 임의 쓰기를 사용하여 __stack_chk_fail의 GOT 항목을 수정하여 카나리가 수정되어도 프로그램을 차단하지 않는 더미 함수로 만들 수 있습니다.

이 공격은 다음 writeup에서 수행됩니다: https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/

참고 자료

htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 AWS 해킹을 마스터하세요 htARTE (HackTricks AWS Red Team Expert)!

HackTricks를 지원하는 다른 방법:

Last updated