Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
OrganizerTransaction — CVE-2021-39749에 대한 PoC로, Android 12L Beta에서 임의의 Activity를 시작할 수 있게 해줍니다. | Kitploit
도구/GitHubGitHub/michalbednarski/organizertransaction
Android SecurityVulnerability AnalysisExploitationMobile App PentestingMobile Security
GitHubmichalbednarski/organizertransaction

OrganizerTransaction

CVE-2021-39749에 대한 PoC로, Android 12L Beta에서 임의의 Activity를 시작할 수 있게 해줍니다.

저장소 보기

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
3711724년 전Kitploit 검토 완료

이것은 CVE-2021-39749에 대한 PoC로, Android 12L Beta에서 다른 앱의 permission 및 exported 설정과 관계없이 해당 앱의 Activity를 시작할 수 있게 해줍니다.

Android 12L에서 TaskFragmentOrganizer 접근은 (의도적으로) 더 이상 MANAGE_ACTIVITY_TASKS 권한을 요구하지 않습니다

여기 제공된 앱을 사용하려면 Hidden API Checks를 비활성화해야 하며, adb shell settings put global hidden_api_policy 1을 통해 수행할 수 있습니다. 이는 보안 경계가 아니며 앱 기반 우회 방법이 알려져 있습니다

이 버그(및 원본 보고서에서 언급된 몇 가지 관련 문제)를 수정하는 커밋은 다음과 같습니다:

  1. startActivityInTaskFragment가 더 이상 Binder.getCallingUid()에 의존하지 않음
  2. ResolverActivity에 이제 relinquishTaskIdentity가 활성화됨
  3. (다른 Activity를 시작하는 데는 필요하지 않지만, 화면에서 위치를 이동하고 투명하게 만들고 탭-재킹이 가능하게 함) TaskFragment의 SurfaceControl이 더 이상 제공되지 않음
  4. (여기 코드에는 표시되지 않으며, 원본 보고서에서만 언급된 문제) ActivityRecord#appToken을 TaskFragmentOrganizer로 보낼지 여부를 결정하는 기준이 pid 대신 uid로 변경됨

android-12.1.0_r4를 체크아웃하고 처음 3개 커밋(또는 처음 2개)을 되돌릴 수 있습니다. (앱은 여전히 ShutdownActivity를 시작하여 기기를 종료할 수 있지만, "Zoom and set alpha" 체크박스는 작동하지 않습니다)

(목록의 첫 번째 커밋은 되돌리려고 하면 테스트에서 병합 충돌이 발생하지만, 무시해도 됩니다)

항상 시스템 uid를 반환하는 Binder.getCallingUid()

Binder.getCallingUid() 메서드는 현재 처리 중인 Binder 트랜잭션을 보낸 프로세스의 uid를 반환합니다. 해당 uid는 스레드-로컬 변수에 저장됩니다. 트랜잭션을 처리하는 코드는 Binder.clearCallingIdentity()를 호출하여 해당 변수를 자체 프로세스의 uid로 설정할 수 있으며, 이는 트랜잭션 처리 중 이후에 호출되는 메서드에 권한 검사가 Binder 트랜잭션 호출자가 아닌 자체(트랜잭션 처리 코드)에 대해 수행되어야 함을 나타냅니다.

때때로 Binder.clearCallingIdentity() 이후에 항상 호출되는 Binder.getCallingUid()가 있어 항상 자체 프로세스의 uid를 반환합니다. 때로는 의도적으로 발생합니다. 예를 들어 ActivityTaskManagerService#startDreamActivity에서 (비록 Process.myUid() 또는 Os.getuid()를 사용하는 다소 복잡한 방법이지만)

저는 스스로 (Soot-기반) 정적 분석 도구를 작성하여 Binder.clearCallingIdentity() 이후에만 발생할 수 있는 Binder.getCallingUid() 호출(및 기타 권한 검사)을 보고합니다. (Soot이 제공하는 Jimple/Shimple IR을 처리하는 사용자 정의 로직이 있지만, Soot로 이를 수행하는 더 나은 방법이 있을 수 있지만 현재는 이 방법을 사용하고 있습니다)

Android 12L Beta에서 해당 도구는 ActivityStartController#startActivityInTaskFragment에서 하나를 발견했습니다. (참고: Beta 릴리스는 오픈 소스가 아니므로 소스 코드를 사용할 수 없었지만, Shimple은 일반적으로 읽을 수 있으므로 Soot를 Java 디컴파일러로도 사용했습니다)

startActivityInTaskFragment 호출 방법

정적 분석 보고서의 일부로 Binder 호출이 시작되는 onTransact() 구현에서 startActivityInTaskFragment까지의 호출 계층 구조를 얻었습니다:

  1. IWindowOrganizerController의 aidl-생성 코드의 onTransact
  2. WindowOrganizerController#applyTransaction (CallerInfo 인수 없음)
  3. WindowOrganizerController#applyTransaction (CallerInfo 인수 포함)
  4. WindowOrganizerController#applyHierarchyOp
  5. ActivityStartController#startActivityInTaskFragment

applyTransaction에 대한 Binder 호출이 TaskFragmentOrganizer 클래스에 존재한다는 것을 발견했고, 모든 Binder 호출을 직접 수행하는 것보다 더 편리한 래퍼로 사용하기로 결정했습니다. (둘 다 공개 API가 아니므로 어차피 리플렉션을 사용해야 했습니다)

먼저, 메서드 "2."는 enforceTaskPermission을 호출하는데, Android 12.0에서는 signature-전용 MANAGE_ACTIVITY_TASKS 권한을 확인했으며 우리는 이를 얻을 수 없었지만, Android 12L에서는 규칙이 완화되어 특정 트랜잭션을 권한 없이 수행할 수 있습니다. startActivityInTaskFragment를 수행하는 데 필요한 작업 중 어느 것도 권한이 필요하지 않다는 것이 밝혀졌습니다. (트랜잭션에 TaskFragmentOrganizer가 연결된 경우)

따라서 우리는 HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT를 수행하려고 합니다. 이를 위해 우리의 TaskFragment가 mLaunchTaskFragments에 등록되어 있어야 합니다. 그렇지 않으면 "Not allowed to operate with invalid fragment token" 예외가 보고됩니다.

HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT를 통해 이러한 TaskFragment를 등록할 수 있으며, 이는 createTaskFragment()를 호출합니다.

(PoC 코드에서 이러한 트랜잭션은 SecondActivity에서 전송됩니다: HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT는 initOrganizerAndFragment()에 의해 전송되고 HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT는 startActivityInOrganizer에 의해 전송됩니다)

따라서 이를 통해 startActivityInTaskFragment를 호출할 수 있으며 여기서 시작된 Activity의 Intent는 시스템 uid에서 온 것으로 간주되지만, 그 자체로는 아무것도 할 수 없다는 것이 밝혀졌습니다: 시스템이 시작한 Activity는 URI 권한을 부여할 수 없으며 다른 앱의 Activity를 시작하려고 하면 canEmbedActivity 검사에 의해 차단됩니다.

canEmbedActivity 우회

canEmbedActivity를 다시 살펴보겠습니다: taskFragment.getTask().effectiveUid가 시스템의 uid이거나 시작된 앱의 uid와 일치하면 임베딩이 허용됩니다. effectiveUid가 시스템인 작업에 있어야 합니다.

도구 다운로드