Off by one overflow
Last updated
Last updated
AWS 해킹 학습 및 실습:HackTricks Training AWS Red Team Expert (ARTE) GCP 해킹 학습 및 실습: HackTricks Training GCP Red Team Expert (GRTE)
1바이트 오버플로우에만 액세스할 수 있다면, 공격자는 다음 청크의 size
필드를 수정할 수 있습니다. 이를 통해 어떤 청크가 실제로 해제되는지를 조작할 수 있으며, 잠재적으로 다른 유효한 청크를 포함하는 청크를 생성할 수 있습니다. 이 취약점은 이중 해제 또는 중첩된 청크와 유사한 방식으로 악용될 수 있습니다.
오프 바이 원 취약점에는 두 가지 유형이 있습니다:
임의 바이트: 이 유형은 해당 바이트를 임의의 값으로 덮어쓸 수 있습니다.
널 바이트 (off-by-null): 이 유형은 해당 바이트를 0x00으로만 덮어쓸 수 있습니다.
이러한 취약점의 일반적인 예는 다음 코드에서 볼 수 있습니다. 여기서 strlen
및 strcpy
의 동작이 일관되지 않아 다음 청크의 시작 부분에 0x00 바이트를 설정할 수 있습니다.
이는 House of Einherjar로 악용될 수 있습니다.
Tcache를 사용하는 경우, 이는 이중 해제 상황으로 이어질 수 있습니다.
그 외의 확인 사항 중 하나로, 이제 청크가 해제될 때 이전 크기가 메타데이터의 청크에 구성된 크기와 비교되므로 2.28 버전부터 이 공격은 꽤 복잡해졌습니다.
Tcache 사용으로 이 공격은 더 이상 작동하지 않습니다.
더 큰 청크를 사용하여 남아있는 경우 오류가 발생합니다: malloc(): invalid next size (unsorted)
한 청크를 다른 청크 안에 포함되도록 만들어 두 번째 청크에 대한 쓰기 액세스를 가능하게하여 포함된 청크를 덮어쓸 수 있도록 함
사이즈 메타데이터 정보를 수정하기 위한 오프 바이 원 오버플로우
세 개의 청크 A
, B
, C
를 할당하고(크기 0x20), 상단 청크와 병합되지 않도록 다른 하나를 할당합니다.
C
를 해제합니다(0x20 Tcache 해제 목록에 삽입됨).
청크 A
를 사용하여 B
에 오버플로우합니다. 오프 바이 원을 악용하여 B
의 size
필드를 0x21에서 0x41로 수정합니다.
이제 B
에는 해제된 청크 C
가 포함됩니다.
B
를 해제하고 0x40 청크를 할당합니다(다시 여기에 배치됨).
여전히 해제된 C
인 fd
포인터를 수정할 수 있습니다(Tcache 독성)
메모리의 3개 청크(a, b, c)가 연이어 예약됩니다. 그런 다음 중간 청크가 해제됩니다. 첫 번째 청크에는 오프 바이 원 오버플로우 취약점이 있으며 공격자가 0x00을 사용하여 악용합니다(이전 바이트가 0x10이면 중간 청크가 실제보다 0x10 작다고 표시됩니다).
그런 다음 중간 해제된 청크(b)에 2개의 더 작은 청크가 할당됩니다. 그러나 b + b->size
가 c 청크를 업데이트하지 않는 이유는 가리키는 주소가 예상보다 작기 때문입니다.
그런 다음, b1과 c가 해제됩니다. 여전히 b1과 c를 가리키는 c - c->prev_size
가 하나의 청크로 통합됩니다. 그러나 b2는 여전히 b1과 c 사이에 있습니다.
마지막으로, 이 메모리 영역을 다시 요구하는 새로운 malloc이 수행되어 b2를 포함하게 됩니다. 이를 통해 새 malloc의 소유자가 b2의 내용을 제어할 수 있습니다.
이 이미지는 공격을 완벽하게 설명합니다:
strlen
이 다음 청크의 size
필드를 고려하기 때문에 오프 바이 원이 발생합니다.
Tcache가 사용되고 있으므로 일반적인 오프 바이 원 공격을 사용하여 Tcache 독성으로 임의 쓰기 원시를 얻을 수 있습니다.
오프 바이 원을 악용하여 힙에서 주소를 누출할 수 있습니다. 왜냐하면 문자열 끝의 0x00 바이트가 다음 필드에 의해 덮어씌워지기 때문입니다.
오프 바이 원 쓰기를 악용하여 포인터가 가짜 구조체와 가짜 포인터가 있는 다른 위치를 가리키도록 만들 수 있습니다. 그런 다음 이 구조체의 포인터를 따라가면 임의 쓰기를 얻을 수 있습니다.
libc 주소가 누출되는 이유는 힙이 mmap을 사용하여 확장될 때 mmap에 의해 할당된 메모리가 libc로부터 고정된 오프셋을 가지기 때문입니다.
마지막으로 임의 쓰기를 악용하여 __free_hook 주소에 원 가젯을 쓰기 위해 주소를 쓸 수 있습니다.
사용자 입력 라인을 읽는 getline
함수에 NULL 오프 바이 원 취약점이 있습니다. 이 함수는 콘텐츠의 "키"를 읽는 데 사용됩니다.
writeup에서 초기 5개의 청크가 생성됩니다:
청크1 (0x200)
청크2 (0x50)
청크5 (0x68)
청크3 (0x1f8)
청크4 (0xf0)
청크 방어 (0x400) 상단 청크와 병합을 피하기 위해
그런 다음 청크 1, 5 및 3이 해제됩니다. 따라서:
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]