2015. 11. 1. 07:43ㆍSecurity ★ Development/Paper
<SCanDroid: Automated Security Certification of Android Application>
이번엔 안드로이드 어플리케이션의 보안에 대해 자동적으로 판단하는 SCanDroid라는 툴에 대한 것입니다. 'Security Certifier for anDroid'의 줄임말입니다. 보통 안드로이드 어플리케이션에서 악성코드 여부를 판단할 때 권한을 우선적으로 보게됩니다. 툴들도 많이 있구요. 그 이상으로(코드나 동작수준에서) 어느정도의 분석을 하는지가 주요 관심영역이 될 것 같습니다.
기본적으로 SCanDroid도 manifests의 권한을 확인합니다. 그리고 권한에 맞게 데이터가 흐르는지 정적으로 체크합니다.
안드로이드에서는 권한을 통해 다른 어플리케이션의 데이터에 접근하는 것을 제어합니다. 이는 악성 어플리케이션을 제한하는데 어느정도 도움이 되지만 완벽한 해답은 될 수 없습니다. SCanDroid는 특히 다른 어플리케이션에 의해 허용된 권한에 기반하여 특정 권한을 실행하는 것이 안전한지에 대한 결정을 할 수 있습니다.
앞부분에서는 안드로이드에 대한 소개가 이루어집니다. Activity, Service, BroadcastReceiver, ContentProvider부터 말이죠. 주소는 컴포넌트사이에서 제어흐름이 어떻게 되는지 영향을 주고 권한은 주소를 기반으로 이런 흐름을 제어할 수 있습니다. 그렇기 때문에 논문에서 소개할 분석은 Uris와 Intents를 매우 정확히 추적할 필요가 있다고 합니다.
Uri가 이동될 수 있는 몇가지 루트를 예를 들어 보여주고 있습니다.
1. Intra-component flows
UriA의 값이 UriB에 쓰여지는 부분을 보시면됩니다. 만약 UriA의 값이 private이고 UriB의 값이 public일 때 UriB에 접근할 권한이 있다고 하면 Uri값의 이동에 따라 UriB의 접근권한으로 UriA에 접근할 수 있습니다.
또한 UriA에 쓸 수 있는 권한으로 UriB에 데이터를 쓰게됩니다.
2. Inter component flows
다른 Activity에서 Uri에 violation이 발생하는 코드입니다.
3. Flows through dynamic components
Service를 통해 Uri violation이 발생하는 코드입니다.
4. Flows through dynamically registered broadcast receiver
BroadcastReceiver를 통해 Uri violation이 발생하는 코드입니다.
앞으로의 목적은 Uris 사이에서 이런 모든 흐름을 추적하는 것이 되겠습니다.
Syntax and informal semantics
이후 슈도코드에서 쓰일 문법들입니다.
- activity(LAUNCH, PERM, 람다x.t, 람다x.t')는 권한 LAUNCH를 권한 PERM과 함께 강요되는 어떤 액태비티를 의미합니다. 람다x.t와 람다x.t'에 의해 onCreate와 onActivityResult이 모델링됩니다. 람다x.t는 activity를 실행하는데 쓰이고 람다x.t'는 이 activity에 실행된 다른 activity가 이 액티비티에게 리턴해주는 값입니다.
- listener(SEND, PERM, 람다x.t)는 권한 LAUNCH를 권한 PERM과 함께 강요되는 어떤 리스너를 의미합니다. 리스너로 보내지는 λx.t에 의해 리스너 메소드가 모델링됩니다.
- store(READ, WRITE, v)는 권한 READ와 WRITE로 실행되며 값 v를 컨텐츠 프로바이더에게 저장하는 것을 의미합니다.
- begin(n, v)는 activity(LAUNCH, PERM, 람다x.t, 람다x.t')와 매칭이 되고 권한은 LAUNCH이며 스택에 윈도우가 올라가고 프로그램t가 권한 PERM, v와 바운드된 x와 실행된다는 것과 맵핑됩니다.
- end(v)는 현재 윈도우를 스택에서 꺼내고 컨트롤을 이전 액티비티에게 돌려줍니다.
- listen(SEND, n, λx.t)는 PERM이 현재 컨텍스트의 권한이라는 전제하에 listener(SEND, PERM, λx.t)를 의미합니다.
- send(LISTEN, n ,v)는 n이 listener(SEND, PERM, λx.t)와 맵핑되는 것을 체크합니다. 여기서 현재 컨텍스트 권한은 SEND이고 LISTEN을 포함하고 있습니다. 프로그램 t는 권한 PERM, v와 바운드된 x와 실행됩니다.
- query(n)은 n이 store(READ, WRITE, v)와 맵핑되었는지 체크합니다. 이때 컨텍스트의 권한은 READ입니다.
- update(n, v)는 n이 store(READ, WRITE, v')와 맵핑되었는지 체크하고 이때의 컨텍스트 권한은 WRITE입니다.
- let x=t in t'는 t를 체크하며 그 후 결과와 바운드되는 x로 t'를 체크합니다. 여기서 x는 지역변수입니다.
- ㄱt는 t를 실행시키는 스레드를 시작합니다. 백그라운드에서 서비스와의 연결을 가능하게 합니다.
- t+t'는 t나 t'를 체크합니다. t나 t'는 유저인터페이스의 비결정적인 상호작용을 가능하게 합니다.
위 표현은 Inter-component flow를 표현한 것입니다. 여기서 두 액티비티는 권한 T에 의해 실행되도록 되어있습니다.
이는 dynamic receiver 표현입니다. 위의 문법에 맞춰 읽으면 실제 코드와 유사한 흐름이라는 것을 알 수 있습니다.
이 외에도 다른 약속어들이 있고 아래는 그 약속어로 Inter-component flow를 표현한 것입니다.
Implementation
구현에는 WALA가 쓰였습니다. WALA는 자바 코드 분석을 위한 오픈 소스 라이브러리의 모음입니다. WALA는 유연한 포인터 분석 프레임워크를 구현하며 지역 변수 필드 다른 객체들에 대한 포인터의 분석 기능이 있습니다.
Elements of analysis
클래스와 어플리케이션의 매니피스트가 인풋으로 들어가고 어플리케이션의 데이터 흐름에 의해 유도된 것 이상의 권한이 아웃풋이 됩니다.
실제 코드 수준의 예제와 분석 결과, 과정은 없고 분석 과정에서의 필요 요소들에 대해서만 설명이 되어있습니다.
- Bytecode loader
주어진 어플리케이션 클래스와 API들에 대해서 호출 그래프를 분석하고 생성합니다. 여기서는 축소된 호출 그래프, 메소드간의 메소드간의 그래프, 포인터 분석결과를 얻을 수 있습니다.
- String/data analysis
string은 코드 여기저기에 쓰이기 때문에 데이터 흐름 추적은 코드에서 다양한 string 값의 정확한 근사치를 요구합니다. bytecode에서 string은 보통 StringBuilder 객체를 사용해서 조작됩니다. 그렇기 때문에 포인터 분석을 통해 StringBuilder 객체를 유심히 살펴보고 string의 접두어를 근사화합니다. 이 정보는 string을 쓰는 Uris와 같은 데이터 구조에 전파됩니다. Uri의 string 접미사를 완벽히 복원할 수는 없어도 manifest에서 기본 Uri에 대한 권한을 찾아내기에는 충분합니다. 이 단계의 아웃풋은 Uri와 string에 대한 키와 문자열의 맵입니다.
- Inflow filter
데이터는 메소드를 통해서 어플리케이션을 흘러갑니다. 메소드를 각각의 소스로 다루는데 WALA에서는 유일한 태그와 맵핑한 키로 나타납니다. 이런 키들은 inter-component flow를 해결하기 위한 정보를 포함하고 있습니다.
inflow filter의 아웃풋은 태그와 소스를 식별하는 인스턴스 키의 맵입니다. 이 맵은 flow analysis에서 사용됩니다.
- Flow analysis
구현단계에서는 WALA의 RHS solver를 사용합니다. 다른 분석들과 달리 본 분석은 동시에 흐름 식별자들에 대한 몇개의 태그들의 흐름을 추적할 필요가 있습니다.
- outflow filter
어떤 데이터가 어플리케이션 외부로 나가는지 식별합니다. 이를 sinks라고 하는데 이 단계에서의 분석은 어플리케이션의 모든 sinks들을 어플리케이션 내부에서 모든 end-to-end, intra-component 흐름을 끌어내기 위한 흐름 분석의 결과와 연결시킵니다. 아웃풋은 inflow tag들과 outflow 태그들의 맵입니다.
- Manifest loader
핵심 안드로이드 어플리케이션과 연관된 manifest를 불러옵니다. 본 분석에서 요구하는 manifests의 몇 가지 특성은 Uris와 권한 사이의 링크, Uris와 Uris를 다루는 ContentProviders 사이의 링크, 각각의 어플리케이션이 설치시 요구하는 권한의 모음을 포함합니다. 모든 이런 정보들은 checker로 넘어갑니다.
- Checker
본 분석은 Uris의 대략적인 접두어를 회복시키기 위해 문자열 분석에 의존합니다. 그리고 이런 접두어들과 관련이 있다고 알려진 권한을 위해 manifest loader의 결과를 봅니다.
흐름 분석에서 탐지된 모든 흐름들이 실행시 허용되는 것은 아닙니다. 특히 inter-component flow는 각각 접근하기 위해 충분한 권한을 가진 연관된 컴포넌트를 필요로 합니다.
Limitations and future exxtensions
본 분석의 현재 제한점은 Java 소스코드와 사용가능한 어플리케이션의 컴파일된 JVML 바이트코드를 필요로 한다는 것입니다. 본 분석이 offline certification을 위한 합리적인 모델인 반면 안드로이드 디바이스에 대한 packaged 어플리케이션엔 즉시 적용할 수 없습니다.
Related work
비슷한 툴로 TAJ라는 것이 있습니다. 웹 어플리케이션을 확인하기 위해 고안되었는데 SCanDroid는 다중 흐름을 체크한다는 면이 다릅니다. 또 SCanDroid는 모듈화 되었고 안드로이드 어플리케이션 프래임워크 코드보다 어플리케이션의 추상적인 구문에 의존합니다. 이것이 SCanDroid를 TAJ보다 더 가볍게 만들어줍니다.
데이터 흐름 분석의 자동화 없이 유저에 의한 판단의 정확성은 제한됩니다. 오래전에 안드로이드 어플리케이션 보안과 관련하여 공부했을 때도 대표적으로 제일 먼저 확인해야할 것들이 설치 시 권한이었습니다. 최근에 뉴스에서 정확히 이와같은 내용의 기사를 보도하는 것을 봤습니다. 가장 기본적이면서도 효과적이라는 말이 되겠죠. 그 다음이 코드의 내용을 정적 혹은 동적분석 하는 것이었는데 자동화 도구만으로 검사를 하고 넘어가기에는 불안전 할 것 같습니다. 코드 분석 자동화 도구를 쓰더라도 전체적인 위험성을 빠르게 훑을 뿐 분석가가 어플리케이션의 행동을 직접 살펴보는 것은 빠질 수 없습니다.
'Security ★ Development > Paper' 카테고리의 다른 글
Improving Host Security with System Call Policies (0) | 2015.11.27 |
---|---|
How Secure is TextSecure? (0) | 2015.11.27 |
A Proxy-Based Data Security Solution in Mobile Cloud (0) | 2015.11.07 |
Payments Security (0) | 2015.09.25 |
Guess Who's Texting You? Evaluating the Security of Smartphone Messaging Applications (0) | 2015.08.29 |