Memory Tagging Extension (MTE)

HackTricks 지원

기본 정보

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

메모리 태깅 확장 작동 방식

MTE는 메모리를 작은 고정 크기 블록으로 나누어 각 블록에 태그를 할당하는 방식으로 작동합니다.

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

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

MTE 포인터 태그

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

따라서 최대 16가지 다른 태그 값을 허용합니다.

MTE 메모리 태그

16B의 물리적 메모리에 해당하는 메모리 태그가 있습니다.

메모리 태그는 전용 RAM 영역에 저장됩니다(일반적인 사용에는 접근할 수 없음). 16B 메모리 태그마다 4비트 태그를 사용하여 RAM의 3%까지 사용합니다.

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에는 잘못된 양성 결과가 없음).

참고 자료

Last updated