메모리 태깅 확장 (MTE)

Reading time: 4 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원하기

기본 정보

**메모리 태깅 확장 (MTE)**는 버퍼 오버플로우 및 사용 후 해제 취약점과 같은 메모리 관련 오류를 감지하고 방지하여 소프트웨어의 신뢰성과 보안을 향상시키기 위해 설계되었습니다. MTE는 ARM 아키텍처의 일부로, 각 메모리 할당에 작은 태그를 부착하고 해당 메모리를 참조하는 각 포인터에 해당 태그를 부여하는 메커니즘을 제공합니다. 이 접근 방식은 런타임에서 불법 메모리 접근을 감지할 수 있게 하여, 임의 코드를 실행하기 위한 이러한 취약점의 악용 위험을 크게 줄입니다.

메모리 태깅 확장이 작동하는 방식

MTE는 메모리를 작고 고정 크기의 블록으로 나누고, 각 블록에 태그를 할당하여 작동합니다. 태그는 일반적으로 몇 비트 크기입니다.

포인터가 해당 메모리를 가리키도록 생성되면, 동일한 태그를 부여받습니다. 이 태그는 메모리 포인터의 사용되지 않는 비트에 저장되어, 포인터를 해당 메모리 블록에 연결합니다.

https://www.youtube.com/watch?v=UwMt0e_dC_Q

프로그램이 포인터를 통해 메모리에 접근할 때, MTE 하드웨어는 포인터의 태그가 메모리 블록의 태그와 일치하는지 확인합니다. 태그가 일치하지 않으면, 이는 불법 메모리 접근을 나타냅니다.

MTE 포인터 태그

포인터 내부의 태그는 상위 바이트의 4비트에 저장됩니다:

https://www.youtube.com/watch?v=UwMt0e_dC_Q

따라서, 최대 16개의 서로 다른 태그 값을 허용합니다.

MTE 메모리 태그

모든 16B의 물리적 메모리는 해당하는 메모리 태그를 가집니다.

메모리 태그는 전용 RAM 영역에 저장됩니다 (일반 사용을 위해 접근할 수 없음). 16B 메모리 태그마다 4비트 태그를 가지며, 최대 3%의 RAM을 차지합니다.

ARM은 전용 RAM 메모리에서 이러한 태그를 조작하기 위해 다음 명령어를 도입합니다:

STG [<Xn/SP>], #<simm>    Store Allocation (memory) Tag
LDG <Xt>, [<Xn/SP>]       Load Allocatoin (memory) Tag
IRG <Xd/SP>, <Xn/SP>      Insert Random [pointer] Tag
...

모드 확인

동기

CPU는 명령어 실행 중 태그를 확인하며, 불일치가 발견되면 예외를 발생시킵니다.
이것은 가장 느리지만 가장 안전합니다.

비동기

CPU는 비동기적으로 태그를 확인하며, 불일치가 발견되면 시스템 레지스터 중 하나에 예외 비트를 설정합니다. 이전 방법보다 빠르지만 불일치를 일으킨 정확한 명령어를 지적할 수 없으며, 즉시 예외를 발생시키지 않아 공격자가 공격을 완료할 시간을 제공합니다.

혼합

???

구현 및 탐지 예시

하드웨어 태그 기반 KASAN, MTE 기반 KASAN 또는 커널 내 MTE라고 불립니다.
커널 할당자(예: kmalloc)는 이 모듈을 호출하여 사용할 태그를 준비하고(무작위로) 커널 공간에 할당된 메모리와 반환된 포인터에 연결합니다.

요청된 크기에 대해 충분한 메모리 그라뉼(각 16B)만 표시합니다. 따라서 요청된 크기가 35이고 60B의 슬랩이 제공되면, 이 태그로 첫 16*3 = 48B를 표시하고 나머지는 **유효하지 않은 태그(0xE)**로 표시됩니다.

태그 0xF모든 포인터와 일치합니다. 이 포인터가 있는 메모리는 어떤 태그도 사용하여 메모리에 접근할 수 있습니다(불일치 없음). 이로 인해 공격된 메모리에서 이 태그가 사용되고 있다면 MET가 공격을 탐지하지 못할 수 있습니다.

따라서 0xE와 0xF가 예약되어 있기 때문에 태그를 생성하는 데 사용할 수 있는 14개의 값만 있습니다. 이는 태그를 재사용할 확률을 1/17로 약 **7%**로 만듭니다.

커널이 유효하지 않은 태그 그라뉼에 접근하면 불일치탐지됩니다. 다른 메모리 위치에 접근할 경우, 메모리에 다른 태그(또는 유효하지 않은 태그)가 있으면 불일치가 탐지됩니다. 공격자가 운이 좋고 메모리가 동일한 태그를 사용하고 있다면 탐지되지 않습니다. 확률은 약 7%입니다.

또 다른 버그는 할당된 메모리의 마지막 그라뉼에서 발생합니다. 애플리케이션이 35B를 요청하면 32에서 48까지의 그라뉼이 제공됩니다. 따라서 36에서 47까지의 바이트가 동일한 태그를 사용하지만 요청되지 않았습니다. 공격자가 이 추가 바이트에 접근하면 탐지되지 않습니다.

**kfree()**가 실행되면 메모리는 유효하지 않은 메모리 태그로 다시 태그가 지정되므로 사용 후 해제에서 메모리에 다시 접근할 때 불일치가 탐지됩니다.

그러나 사용 후 해제에서 동일한 청크가 이전과 동일한 태그로 다시 할당되면, 공격자는 이 접근을 사용할 수 있으며 이는 탐지되지 않습니다(약 7% 확률).

게다가 **slabpage_alloc**만 태그가 지정된 메모리를 사용하지만, 앞으로는 vmalloc, stackglobals에서도 사용될 것입니다(비디오 시점에서 이들은 여전히 악용될 수 있습니다).

불일치가 탐지되면 커널은 추가적인 악용과 공격 재시도를 방지하기 위해 패닉 상태에 빠집니다(MTE는 잘못된 긍정이 없습니다).

참고 문헌

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원하기