SVE-2021-20636 / CVE-2021-25388
1) APP info
* APP: Knox Core (com.samsung.android.knox.containercore) * REWARD: $1720 * DESCRIPTION: Installation of arbitrary apps * Occur: Knox Core > DualDARInitService
2) Knox core (com.samsung.android.knox.containercore)
- Knox core는 안드로이드 업무용 프로필, 시큐어폴더, 컨테이너 락 그리고 취약점이 발생하는 DualDar 등 암호로 보호된 작업 컨테이너 공간을 생성하는 기능을 가지며 Knox Core를 사용하면 하드웨어에서 앱 수준까지 여러 계층 보호 가능.
3) DualDAR?

- 취약점이 발생하는 지점인 DualDAR은 Dual Data-at-Rest Encryption의 약자로 컨테이너 데이터 암호화를 계층적으로 제공하는 기능을 가지고 있으며 각 계층은 서로 다른 암호 모듈, 키, 암호를 사용함.
- DualDAR은 Android 파일 기반 암호화(FBE) 아키텍처를 활용하며, 앱에서 사용할 수 있는 공간은 DE(Device Encryption)와 CE(Credential Encryption)로 나누어져 있음. 단, DualDAR Workspace 내에서는 이 공간이 DualDAR로 이중 암호화되고, 앱 입장에서는 CE처럼 동작함.
- FBE(File Based Encryption)은 많은 앱에 적합하지만 NSA(National Security Agency)의 기밀 데이터에 대한 더 높은 수준을 위해 데이터를 이중 암호화하는 DualDAR이 적합함.
- Samsung Knox DualDAR 솔루션은 다른 암호화 및 다른 키 생성으로 두 가지 개별 계층(Inner Encryption Layer, Outer Encryption Layer)을 제공하여 이중으로 암호화 함.
- Android 9.0(삼성 FBE 지원 장치)에서는 일반적으로 모든 데이터가 CE 저장소에 저장되지만, DualDAR Workspace 내에서는 모든 데이터가 DualDAR로 이중 암호화되고, Knox 프레임워크는 앱이 DualDAR 보호를 받지 않는 공간에 데이터를 쓰는 것을 방지함.
- DualDAR 솔루션의 API는 다양한데 취약점은 DualDARInitService에서 발생.
- (참고: https://docs.samsungknox.com/dev/knox-sdk/dual-dar-architecture.htm)
4) 취약점 설명
< AndroidManifest.xml >
- 취약점은 KnoxCore에 정의되어 있는 DualDARInitService에서 발생 하게되는데 xml 파일을 보면 DualDARIgnitService가 exported=”true” 이므로 외부에서 접근이 가능한 서비스이다.
< DualDARInitService onStartCommand >
- 해당 서비스를 호출하면 onStartCommand에 의해 proceedPrerequisiteForDualDARWithWPCOD 함수를 호출함. (onStartCommand는 service가 onCreate으로 서비스가 정의된 후 바로 실행)
- UserHandle.myUserID 값이 0이여야하고 DualDARServiceEventFlag 값이 500 이여야 함.
- 해당 함수는 디바이스의 개인 데이터와 작업 데이터를 분리하는 WPCOD(Work Profile on Compay-Owned Devices) 즉, 회사 소유 장치의 작업 프로필에 대해 설정하는 기능을 가진 함수이다. 요 함수에서 취약점이 발생하게 됨.
< proceedPrerequisiteForDualDARWithWPCOD >
- 취약점이 발생하는 부분은 최종적으로 installPackageTask 함수를 호출하여 임의의 앱을 설치 함.
- installPackageTask로 가기 위한 분기문들은 외부에서 받아온 intent 파라미터로 우회가 가능함(서비스가 외부에 오픈되어 있기 때문에 변조하여 전송이 가능).
- 우선 bundleExtra 변수에 인텐트에 전달된
DUAL_DAR_PARAMS에 해당하는 번들 데이터를 저장함. - 번들 데이터 중 dualdar-config-client-location 파라미터를 통해 설치할 앱의 URI를 받아 string2 변수에 저장함.
- str 변수에는 getExternalFilesDir 함수와
/client_downloaded_knox_app.apk문자열로 앱이 설치될 경로를 저장함./storage/sdcard0/Android/data/package/files/client_downloaded_knox_app.apk
- string2에 URI 문자열과 str에 대한 apk 문자열을 rcp라는 시스템 서비스를 호출한 뒤 그 서비스의 copyFile 함수에 파라미터로 넘김. rcp 시스템 서비스의 copyFile에 대한 구현체 부분을 자세히 보지는 못했지만 단순 파일에 대한 복사로 추정.
- 결과적으로 dualdar-config-client-location에 저장된 파일 데이터는
/sdcard/Android/data/com.samsung.android.knox.containercore/files/client_download_knox_app.apk에 저장됨. - 후에 installPacakgeTask 메소드에 str(client._download_knox_app.apk) 파라미터를 넘김.
< installPackageTask >

- proceedPrerequisiteForDualDARWithWPCOD 함수의 str을 installPackageTask에선 str2로 변수명이 바뀜(주의). > str2가 client._download_knox_app.apk
- str은 처음에 보내준 번들 파일의 조작 가능한 임의 데이터(패키지명)
- apk를 설치까지는 완료했고, apk를 디바이스에 설치하기 위해서 packageInstaller 객체 선언과 str2에 대한 파일 객체 생성.
getPackageInstaller: 장치에 응용 프로그램을 설치, 업그레이드 및 제거할 수 있는 기능을 제공하는 인터페이스를 반환( silent install시 주로 사용 )
- packageInstaller를 통해 세션을 만들고 openWrite 메소드 호출.
OutputStream openWrite = openSession.openWrite(file.getName(), 0L, -1L);
- copyStream 메소드를 호출해 openWrite로 써진 데이터를 str2 객체에 복사
- 패키지 설치는 OpenSessionCommit을 통해 최종적으로 설치함.
5) Payload

- File(getApplicationInfo().dataDir, “app.apk”)를 통해
/data/user/0/com.example.mytestapplication/app.apk와 같은 경로에 파일 객체를 생성. 미리 Asset폴더에 올려 놓은 공격자의 앱을 file객체에 복사하는 payload를 구성함.
Ref.
https://blog.oversecured.com/