[보안/기술]삼성 KNOX (삼성녹스) 란? -- 삼성 KNOX 원리[커널] -2- + RKP 취약점 정리
안녕하세요. 학생개발자입니다.
-번역 컨텐츠-
어제는 삼성전자의 하드웨어 기반 보안 솔루션 Samsumg Knox의
HW수준 보안 계층을 설명하였는데요.
아직 [보안/기술]삼성 KNOX(삼성 녹스) 란? -- 삼성 KNOX 원리 -1-편을 보지 않으셨던 분들 은
아래 링크를 통해 읽고 오시는 걸 추천드립니다.
Trusted Boot
Knox Verified Boot (KVB)
Real-time Kernel Protection (RKP)
구글 프로젝트 제로의 삼성KNOX RKP 취약점 보고서
구글 프로젝트 제로 에서 발표한 취약점을 간단히 설명하자면
삼성의 실시간 커널 보호(RKP)를 Bypass하는 취약점입니다.
위 이미지는 RKP의 아키텍쳐의 구성입니다.
EL1은 Android의 Linux 커널을 나타내며 EL2 ( "HYP"모드라고도 함)는 RKP 하이퍼 바이저를 나타냅니다.
하이퍼 바이저는 "를 사용하여 커널에서 수행되는 주요 작업을 제어 할 수 있습니다.
H ypervisor C onfiguration R egister"(HCR). 이 레지스터는 EL2가 EL1에서 실행되는 코드와 상호 작용할 수 있도록
가상화 기능을 제어합니다.
예를 들어, HCR의 특정 비트를 설정하면 하이퍼 바이저가 일반적으로 EL1에서 처리하는 특정 작업을
트래핑하여 하이퍼 바이저가 요청 된 작업을 허용할지 여부를 선택할 수 있습니다
하이퍼 바이저는 "스테이지 2 변환"이라고하는 추가 메모리 변환 계층을 구현할 수 있습니다.운영 체제의 변환 테이블이 가상 주소 (VA)와 실제 주소 (PA) 사이를매핑하는 정규 모델을 사용하는 대신 변환 프로세스가 두 개로 나뉩니다.주어진 VA를 중간 물리적 주소 (IPA)에 매핑하기 위해 EL1 변환 테이블이 사용됩니다.이를 "1 단계 변환"이라고합니다.이 과정에서 액세스 권한 (AP) 비트,execute never (XN) 및 privileged execute never (PXN)을 비롯하여 액세스 제어를
translation 하는데 적용됩니다.
그런 다음 결과 IPA는 "2 단계 변환"을 수행하여 PA로 변환됩니다.
이 매핑은 EL2에 액세스 할 수있는 변환 테이블을 사용하여 수행되며
EL1에서 실행되는 코드에는 액세스 할 수 없습니다.
이 2 단계 변환 방식을 사용하면 하이퍼 바이저는 EL1에서 비밀로 유지해야하는
중요한 데이터가 포함될 수있는 물리적 메모리의 특정 키 영역에 대한 액세스를 방지 할 수 있습니다.
Layout Randomisation (KASLR)이 도입되었습니다.
이 보안 기능은 장치가 부팅 될 때마다 생성되는 임의의 "오프셋"을 도입하여 커널의 기본 주소가 변경됩니다.
일반적으로 커널은 커널의 VAS에서 고정 된 가상 주소에 해당하는 고정 된 물리적 주소에로드됩니다.
KASLR을 도입함으로써 코드를 포함한 모든 커널의 메모리가
이 무작위 오프셋에 의해 이동됩니다.
리눅스 커널은 그러한 포인터가 사용자 영역으로 유출되는 것을 막기위한 메커니즘을 포함하고습니다.
하나의 그러한 완화는 포인터의 값이 커널에 의해 쓰여질 때마다
특수 형식 지정자 "% pK"를 사용하여 인쇄되도록함으로써 완화됩니다.
그런 다음 kptr_restrict 의 값에 따라 커널이 인쇄 된 포인터 를 익명화 할 수 있습니다.
대부분의 안드로이드 장치에서 kptr_restrict 가 올바르게 구성되어 실제로 "% pK"포인터의 익명화 가 보장됩니다.
커널 코드 (init / main.c)를 자세히 살펴보면 Exynos 장치 (Qualcomm 기반 장치와 반대)에서
RKP가 EL1 커널에 의해 부트 스트랩된다는 것을 알 수 있습니다.
즉, EL2에서 직접 EL2를 부팅하는 대신 EL1이 먼저 부팅 된 다음
EL2를 부트 스트랩하기 위해 일부 작업 만 수행합니다.
이 부트 스트래핑은 EL 커널의 코드 세그먼트에 RKP 코드가 포함 된
전체 바이너리를 포함시킴으로써 이루어집니다.
그런 다음 커널이 부팅되면 RKP 바이너리를 사전 정의 된 물리적 범위로 복사하고 RKP를
부트 스트랩하고 초기화하기 위해 TrustZone으로 전환합니다.
RKP 바이너리를 커널의 텍스트 세그먼트에 내장하면 EL1에서 실행 가능한 메모리 범위의 일부가됩니다.
아래 코드는 구글 프로젝트 제로 팀이 EL1에서 RKP 바이너리의 가젯을 사용하여
스테이지 1 변환 테이블의 위치를 읽고 작은 테이블을 만든 다음 테이블의 내용을 덤프하고 파싱한 결과물입니다.
[256] L1 table [PXNTable: 0, APTable: 0]
[ 0] 0x080000000-0x080200000 [PXN: 0, UXN: 1, AP: 0]
[ 1] 0x080200000-0x080400000 [PXN: 0, UXN: 1, AP: 0]
[ 2] 0x080400000-0x080600000 [PXN: 0, UXN: 1, AP: 0]
[ 3] 0x080600000-0x080800000 [PXN: 0, UXN: 1, AP: 0]
[ 4] 0x080800000-0x080a00000 [PXN: 0, UXN: 1, AP: 0]
[ 5] 0x080a00000-0x080c00000 [PXN: 0, UXN: 1, AP: 0]
[ 6] 0x080c00000-0x080e00000 [PXN: 0, UXN: 1, AP: 0]
[ 7] 0x080e00000-0x081000000 [PXN: 0, UXN: 1, AP: 0]
[ 8] 0x081000000-0x081200000 [PXN: 0, UXN: 1, AP: 0]
[ 9] 0x081200000-0x081400000 [PXN: 0, UXN: 1, AP: 0]
[ 10] 0x081400000-0x081600000 [PXN: 1, UXN: 1, AP: 0]
...
위에서 볼 수 있듯이 전체 물리적 메모리 범위 [ 0x80000000, 0x81400000]는 1MB 범위의 메모리를
변환하는 첫 번째 수준 "섹션"설명자를 사용하여 1 단계 변환 테이블에 매핑됩니다.
예상대로이 범위는 UXN 및 PXN이 아닌 것으로 표시되므로 EL1은 이러한 범위에서
메모리를 실행할 수 있지만 EL0에서는 그렇게 할 수 없습니다.
그러나 훨씬 더 놀랍게도 전체 범위에는 액세스 권한 (AP) 비트 값 "00"이 표시됩니다.
따라서 이 메모리 범위가 EL1에서 읽고 쓸 수 있다는 것입니다.
이 모든 것을 종합하면 [ 0x80000000, 0x81400000] 의 전체 물리적 범위가
1 단계 변환 테이블에서 RWX로 매핑 됩니다.
하지만 커널의 코드를 수정할 수 있다는 것을 의미하지는 않습니다.
이러한 메모리 범위는 공격자가 쓰기 권한을 얻지 못하도록 2 단계 번역에서 제한 될 수 있습니다.
커널 측에서는이 명령이 RKP에 커널에 속한 많은 메모리 범위를 제공한다는 것을 알 수 있습니다.
void handle_rkp_init(...) {
...
void* kern_text_phys_start = rkp_get_pa(text);
void* kern_text_phys_end = rkp_get_pa(etext);
rkp_debug_log("DEFERRED INIT START", 0, 0, 0);
if (etext & 0x1FFFFF)
rkp_debug_log("Kernel range is not aligned", 0, 0, 0);
if (!rkp_s2_range_change_permission(kern_text_phys_start, kern_text_phys_end, 128, 1, 1))
rkp_debug_log("Failed to make Kernel range RO", 0, 0, 0);
...
}
출처: 구글 프로젝트 제로
위 코드에 포함된 함수 호출은 주어진 PA 메모리 범위에 대한
스테이지 2 액세스 권한을 수정하기 위해 사용됩니다.
이러한 인수를 사용하여 함수를 호출하면 지정된 메모리 범위가
2 단계 변환에서 읽기 전용으로 표시됩니다.
즉, EL1 커널을 부팅하자마자 RKP는 실제로 커널의 코드 범위에 대한 쓰기 액세스를 잠급니다.
앞에서 살펴본 주소 범위는 RWX가 1 단계 및 2 단계 변환 테이블로 표시된 것과 동일하며
커널의 텍스트 세그먼트보다 훨씬 큽니다.
이것은 부분적으로, KASLR 슬라이드가 결정된 후 커널이 그 영역의 어딘가에 배치되도록하기위한 것입니다.
우리가 보았 듯이 그러나 KASLR 슬라이드를 선택한 후,
RKP는 단지 즉, 커널의 텍스트를 포함하는 영역 만 - "_text"에서 "_etext"까지
이르기까지의 범위를 보호 후 KASLR 슬라이드를 적용합니다.
이러한 취약점은 삼성전자의 트러스트 부트 기능을 무력화 시킬수 있습니다.
현재 해당 취약점은 해결된 상태입니다.
RKP가 중요한 이유
커널 보호는 장치 보안 및 엔터프라이즈 데이터 보호의 핵심입니다.
공격자가 소프트웨어 취약점을 발견하면 종종 권한을 상승시키고 OS의 핵심 인 커널을 손상시킵니다.
손상된 커널은 중요한 데이터를 유출하고 영향을받는 장치를 원격으로 모니터링하고 제어 할 수 있습니다.
시큐어 부트 나 하드웨어 기반 키 스토어와 같은 다른 보편적 인 보호는
커널 자체가 런타임에 제어되는 경우 거의 가치가 없습니다.
장치가 부팅되어 중요한 내용을 해독 한 후에는 커널 손상으로 인해 기업의 데이터 무결성에
직접 영향을주는 데이터 유출이 발생할 수 있습니다.
RKP 설계 및 구조
RKP는 커널을 격리하여 TCB (Trusted Computing Base)를 축소하고 커널을 손상시키지 않도록 설계되었습니다.
커널 코드 - RKP는 커널 코드 및 논리 수정을 방지합니다.커널 데이터 - RKP는 중요한 커널 데이터 구조의 수정을 방지합니다.커널 제어 흐름 - RKP는 ROP (Return-Oriented Programming) 및JOP (Jump-Oriented Programming) 공격을 방지합니다.이 공격은 기존 커널 논리를 다시 사용하여 커널의 코드에서 악용 할 수 있습니다.
Periodic Kernel Measurement (PKM)
오늘은 Samsung RKP 리얼 타임 커널 프로텍션과 RKP취약점을 정리해 보았습니다.
내일은 루팅 탐지와 OS와 소프트웨어 단계 KNOX 보안 플랫폼 원리를 설명하겠습니다.
학생개발자의 IT Story에 방문해주셔서 감사합니다.
본 포스팅의 내용을 무단 전재하거나 복제 하지 마십시오.학생개발자의 IT Story 의 컨텐츠의 저작권은 학생개발자에게 있습니다.euiseoad03@gmail.comcschauiseo1234@naver.comcopyright(c)학생개발자 2019
-본문 이미지 출처-
삼성 Knox 웹 사이트 : https://www.samsungknox.com