* 주의 : 나는 영어를 잘 하지 못한다. 이걸 번역한것은 뇌에서 고등학교 수준의 영어로 번역해낸 것이다. 더욱 자세한 내용을 볼려면 원문을 읽어라.
안드로이드는 보안 검사 및 수행에 역할을 하는 서로 상호작용하는 매커니즘으로 이루져 있다.
이러한 매커니즘들은 수행할 대상(app/user), 객체(other apps, files,devices) , 수행할 작업(read, write, delete 등) 과 정보를 교환 합니다.
대부분 실행 할 때는 멀쩡하지만 가끔씩 벌어진 틈새로 정보가 흘러나가 공격할 기회를 주기도 한다.
Understanding Android System Architecture(안드로이드 아키택처 이해하기)
일반적으로 안드로이드 아키텍처는 때때로 Linux의 자바로 묘사 되었지만 그건 잘못되었다.
안드로이드 아키텍처는 정확히 "어플리케이션, 프레임워크, 달빅(Dalvik)가상머신, 사용자 공간의 Native Code, 리눅스 커널" 로 구성 되어있다.
개발자들은 안드로이드 어플리케이션을 통해 low-level을 변경할 필요 없이 기기의 기능을 확장하고 개선 할 수 있다.
또한 안드로이드 프레임워크는 개발자들에게 안드로이드 기기가 제공하는 모든 기능에 접근할수 있는 API를 제공 한다.
여기에는 개발자가 UI(사용자 인터페이스) 요소 관리, 공유 데이터 저장소 엑세스, 애플리케이션 구성 요소 간 메시지 전달과 같은 일반적인 작업을 수행할 수 있도록 하는 구성 요소가 포함 된다.
안드로이드 어플리케이션과 안드로이드 프레임 워크는 모두 자바 프로그래밍 언어로 개발 되었으며 Dalvik VM에서 실행 된다. Dalvik vm 은 Dalvik Executable(DEX) 바이트 코드 형식을 해석하는 레지스터 기반 VM이다. 따라서 Dalvick V은 여러 네이티브 코드 라이브러리에서 제공하는 기능에 의존하게 된다.
※ 여기서 네이티브 코드 라이브러리에서 제공하는 기능에 의존하게 된다는 것은 아마 Android NDK 때문일 것이다. Android NDK 는 C나 C++ 같은 네이티브 코드를 안드로이드 앱에 삽입 할 수 있게 하는 도구 집합이다.
사용자 공간 네이티브 코드 구성 요소에는 시스템 서비스, 네트워킹 서스, bionic_libc, WebKit, OpenSSL과 같은 라이브러리가 포함 된다.
이러한 서비스 및 라이브러리는 커널 수준 서비스 및 드라이버와 통신 하지만 일부는 manage code에 대한 low-level 부분의 작동을 용이 하게 한다.
안드로이드는 리눅스 커널을 기본으로 한다. 안드로이드는 커널 소스 트리에 수많은 추가와 변경을 했으며, 그들 중 일부는 자체적인 보안상의 영향을 미친다.
이에 대해선 3장,10장,12장에서 더 보도록 하자.
커널 수준 드라이버는 또한 카메라 엑세스, wi-fi 및 기타 네트워크 장치 엑세스 특히 프로세스간 통신(IPC)를 구현하는 바인더 드라이버가 있다.
IPC에 관한 내용은 훗날 더 자세히 나온다.
Understanding Security Boundaries and Enforcement
보안 경계(신뢰 경계)는 신뢰 수준이 양쪽에서 서로 다른 시스템의 특정 위치를 말한다.
이에 대한 예시로는 커널 공간과 사용자 공간의 경계가 있다.
커널 공간의 코드는 하드웨어의 low-level 수준의 작업을 수행하고 모든 가상 및 물리적 메모리에 엑세스 할 수 있도록 신뢰된다.
하지만 사용자 공간 코드는 중앙 처리 장치(CPU)에 의해 시행되는 경계로 인해 모든 메모리에 엑세스 할 수 없다.
안드로이드 운영 체제는 두개의 분리된, 하지만 협력적인 권한 모델을 사용한다.
low-level에서 Linux 사용자 기반 보호를 활용 하여 Users와 groups 둘로 나눠 각각 따로 권한을 적용 한다.
이 권한 모델은 Linux에서 상속 되며 파일 시스템 항목 및 기타 Android 관련 리소스에 대한 엑세스를 강제 적용 한다.
이것을 일반적으로 Android SandBox라고 불린다.
안드로이드 런타임은 Dalvik VM과 안드로이드 프레임 워크에 의해 두 번째 모델(groups)을 시행한다.
사용자가 어플리케이션을 설치 할때 노출 되는 이 모델은 안드로이드 어플리케이션의 기능을 제한하는 앱 권한을 정의한다.
두 번째 모델의 일부 권한은 실제로 기본 운영 체제(os)의 특정 사용자, 그룹 및 기능에 직접 매핑 된다.
Android’s Sandbox
안드로이드는 유닉스 계열의 프로세스 격리와 최소한의 권한 원칙을 따른다.
특히 별도의 사용자로 실행 되는 프로세스는 신호를 전송하거나 서로의 메모리 공간에 엑세스 하는등의 서로 간섭할 수 없다.
안드로이드 샌드박스의 대부분은 표준 리눅스 프로세스 격리, 대부분의 프로세스에 대한 고유 사용자 ID(UID) 및 파일 시스템 권한 제한과 같은 몇 가지 핵심 개념을 볼 수 있다. 하지만 리눅스의 UID/GID (GroupID)패러다임을 공유할 뿐 사용자 및 그룹 자격증명 암호나 그룹 파일등은 가지고 있지 않다.
대신 안드로이드는 안드로이드 ID(AID)로 알려진 고유 식별자를 정의 한다.
초기 AID 매핑에는 시스템 사용자/그룹과 같은 권한 있는 시스템의 중요한 사용자를 위한 정적 항목이 포함 되어 있습니다. 또한 안드로이드는 앱 UID를 provisioning을 하기 위해 AID의 범위를 예약 합니다.
안드로이드 4.1 버전 이후 여러 사용자 프로필과 격리된 프로세스 사용자(예 : 크롬 추가 샌드박스)를 위한 추가 AID 범위를 추가 했다.
AOSP 트리에서 "symstem/core/include/private/android_filesystem_config.h"에서 AID에 대한 정의를 내렸고 이는 간단하게 편집하면 이렇다.
안드로이드는 AID 외에도 추가 그룹을 사용 하여 프로세스가 공유 또는 보호 리소스에 엑세스 할 수 있도록 합니다.
예를 들어 sdcard_rw 그룹의 멤버십은 마운트 옵션이 읽기/쓰기가 가능한 그룹으로 제한 하기 때문에 프로세스를 허용 한다. 이것은 많은 리눅스 배포판에서 보조 그룹이 사용 되는 방식과 비슷하다.
모든 AID 항목이 UID와 GID 에 모두 매핑 되지만 UID를 사용하여 시스템에 사용자를 나타낼 필요는 없습니다.
예를 들어 AID_SDCARD_RW는 sdcard_rw에 매핑되지만 시스템의 UID가 아닌 보조 그룹으로만 사용됩니다.
파일 시스템 접근을 강화하는 것 외에도 AID_NET 그룹이 사용자가 AF_INET/AF_INET6 소켓을 열 수 있도록 하는 것 처럼 보조 그룹을 사용하여 프로세스에 추가 권한을 부여 할 수 있습니다.
경우에 따라서는 "Linux capability"의 형태로도 권한이 제공 될 수 있습니다.
예를 들어 AID_INET_ADMIN그룹은 CAP_NET_ADMIN의 Capability를 부여하여 사용자가 네트워크 인터페이스 및 라우팅 테이블 구성을 설정할 수 있도록 허용합니다.
다른 네트워크 관련 그룹인 "paranoid Networking"섹션에 대해서는 나중에 언급이 됩니다.
안드로이드 4.3 이상에는 리눅스 기능의 사용을 늘립니다. 예를 들어 /system/bin/run-as 바이너리를 UID루트로 설정하는 것에서 Linux 기능을 사용하여 권한 있는 리소스에 엑세스 하는 것으로 변경 했습니다. 여기서 이 기능을 통해 packages.list 파일에 쉽게 접근 할 수 있습니다.
Linux capability에 관한 내용들은 리눅스 커널의 Documentation/security/credentials에서 확인할 수 있습니다.
응용 프로그램이 실행 되면 UID, GID 및 보조 그룹이 새로 생성된 프로세스에 할당됩니다. 고유한 UID와 GID로 실행 되면 운영 체제가 커널에서 하위 수준의 제한을 적용하고 런타임에 앱 간 상호 작용을 제어할 수 있습니다. 이것이 안드로이드 샌드박스의 핵심입니다.
아래 그림은 HTC one V 에서 ps 명령어를 입력한 모습 입니다.
맨 왼쪽에서 2번째에 위치한 UID들이 각 APP마다 고유한 것을 확인 할 수 있다.
또한 응용 프로그램은 응용 프로그램 패키지의 특수 지시문을 통해 UID를 공유 할 수 있습니다.
이는 "Major Application Components" 섹션에서 자세히 설명한다.
내부적으로 프로세스에 대해 표시되는 UID/GID는 실제로 이러한 값을 설정하고 가져오는데 사용되는
'POSIX'기능 중 getpwuid( )과 같은 안드로이드 특정 구현에 의해 제공된다.
getpwuid : 유저 IP로 사용자 정보를 구합니다. 사용자 정보는 pwd.h 에 정의된 struct passwd에 따릅니다.
getwuid는 안드로이드 전용 기능인형제처럼 getpwuid는 안드로이드 전용 기능인 approd_id_to_passwd를 차례로 호출한다.
그런 다음 해당 AID의 정보로 Unix password 구조체를 채웁니다.
android_id_to_passwd 함수는 다음을 수행하기 위해 indo_iinfo_to_passwd를 호출한다.
휴 힘들다
'안드로이드에 관하여 > 안드로이드 공부' 카테고리의 다른 글
JEB2 or JEB3가 안될때 (0) | 2021.03.20 |
---|---|
Android Hacker's Handbook 2장 -2- (0) | 2021.01.25 |
Where is my arm ? (0) | 2021.01.17 |
Android Hackers Handbook 1장 (0) | 2021.01.16 |
APK 보호기법 (0) | 2021.01.06 |