[안드로이드 모의해킹] Zygote와 Zygisk

 

안드로이드 취약점진단에서 루팅 탐지 우회와 관련있는 매지스크 모듈인 Zygisk의 동작 원리에 대해 정리한다.

Zygote 프로세스 개요

 

안드로이드 앱은 자바 코드로 작성되어 있고 가상머신인 안드로이드 런타임(ART)에서 동작한다. 앱이 실행될 따마다 가상머신을 초기화하고 자원을 할당하는 작업은 실행을 느리게 하는 원인이 된다. Zygote(자이고트) 프로세스는 앱이 실행되기 이전에 실행된 가상 머신의 코드 및 메모리 정보를 공유함으로써 실행시간을 단축한다.

 

 

리눅스의 fork() 시스템 콜의 동작 원리와 비슷하다. 자식 프로세스 'A'를 생성할 때 부모 프로세스의 메모리 구성 정보 및 공유 라이브러리에 대한 링크 정보를 공유한다. 부모 프로세스에는 이미 이러한 정보들을 가지고 있으므로 링크 정보만 매핑하면 되므로 라이브러리에 빠른 접근 및 실행이 가능하다.

 

fork() 시스템 콜을 호출하여 자식 프로세스인 Zygote 프로세스를 생성한다. 부모 프로세스인 Zygote 프로세스의 코드 영역과 링크 정보를 공유한다. 새로운 앱이 실행될 때마다 가상 머신 환경만 제공하면 되는 것이다.

 

 

안드로이드 부팅과 Zygote 프로세스

 

Zygote 프로세스는 부팅 단계에 실행되기 때문에 부팅 과정을 살펴본다. 안드로이드는 다음의 순서에 따라 부팅된다.

 

① BootROM 부트로더의 첫 번째 단계를 내부 RAM에 로드
② 부트로더: 메모리를 초기화하고 보안을 확인하여 커널을 로드
③ 커널: 인터럽트 컨트롤러, 메모리 보호, 캐시 및 예약을 설정하고 사용자 공간 프로세스를 실행
④ init 프로세스: init.rc 스크립트를 파싱하고, 파일 시스템을 마운트하며, zygote 및 시스템 프로세스를 시작한다.
⑤ Zygote : 안드로이드 객체의 자바 런타임 및 init 메모리를 설정
⑥ 시스템: 시스템의 첫 번째 자바 구성요소로, 핵심 안드로이드 서비스를 시작

 

Zygote 프로세스만 살펴보면 init.rc에 등록된 다음의 명령에 따라 init 프로세스에서 실행된다. 다음은 AOSP 11의 init.zygote32.rc 스크립트이다.

 

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    socket usap_pool_primary stream 660 root system
    onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks
    critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

 

zygote는 자바로 작성되어 있기 때문에 ART VM환경에서 ZygoteInit 클래스를 로딩하고 실행한다.

 

Zygote와 Zygisk

 

Magisk 프레임워크에서 지원하는 모듈인 Zygisk는 앞서 다룬 동작 원리를 이용하여 루팅 탐지 우회 로직을 한다. Zygote에 커스텀 코드를 주입하여 앱 프로세스의 동작을 조작한다. 주로 시스템 레벨에서 수정이 필요한 경우에 사용되며, 루팅을 했을 때 발생하는 시스템 레벨에서의 변화를 원복한 것처럼 조작한다. 또한 zygisk는 zygote 프로세스에서 실행 중인 앱 프로세스의 흐름을 분기시키거나 특정 함수의 호출을 숨김으로써 루팅 탐지를 우회한다.

 

APK 파일을 실행하는 것은 앱 아이콘을 클릭하여 실행하는 것부터 시스템 서버(System Server)에서 액티비티 매니저(Activity Manager)를 통해 컨텍스트(Context)를 생성하고 해당 액티비티(Activity)를 실행될 수 있는 가상 머신 환경을 Zygote를 통해 fork 후 구성하는 것이다. 앱의 코드는 이때부터 실행되는 것이기 때문에 루팅 탐지 로직 또한 이 단계 이후에 실행된다.

 

References

 

https://source.android.com/docs/devices/automotive/power/boot_time?hl=ko

반응형