사자자리
Android Static Taint Analysis 기법과 발전 방향 본문
2022 CodeEngn Conference 18
Android Static Taint Analysis 기법과 발전 방향
https://www.youtube.com/watch?v=tSmgW62lYb4
Android Static Taint Analysis
Android app을 자동화 분석하는 하나의 기법
- 분석해야 할 app의 수가 점차 증가하고 있다. 정상적인 app은 변종이 없지만, 악성 app은 기존 코드의 일부만을 바꾸는 기법을 통해 자동 생성이 가능해서, 정상적인 app보다 악성 app이 더 많이 생겨나고 있다.
- 그러나 분석가의 시간은 한정적이므로 자동화 탐지가 필요하다.
Static Taint Analysis 기법의 한계
- Android app에 적용하기 어려움 → Flowdroid 이용
Flowdroid
- app 전체의 코드 구조를 모델링하고, 가능한 모든 데이터의 흐름을 파악한다.
- 10분 내외의 시간에 1개의 app 분석이 가능하다.
Taint Analysis
- 신뢰할 수 없는(untrustworthy) 데이터의 프로그램 내부 흐름을 분석하는 기법
- 목적: 개인정보를 유출하는 악성 앱 탐지
Taint | taint: 오염, 감염, 얼룩 → 추적의 대상 tainted 데이터로부터 영향을 받은 데이터들은 tainted된다. |
Source | taint 데이터가 생성되는 위치. 분석가가 추적하고자 하는 데이터의 생성 지점. ex) 사용자의 개인정보를 반환하는 함수 |
Sink | taint 데이터가 도착하는 위치 ex) 사용자의 데이터를 외부로 유출할 수 있는 함수 |
Dynamic Taint Analysis | Static Taint Analysis | |
수행 방법 | user input, event를 자동으로 발생시키고 로그 데이터나 함수 실행 등을 추적한다. 즉, 동작이 일어날 때마다 관찰한다. | 소스 코드 혹은 컴파일된 코드를 input으로 받아서, 코드를 실행하지 않고 taint analysis를 수행한다. 코드 구조, 문법, 순서, 의미를 고려하여 taint가 전달되는 과정을 분석한다. |
정확성 | 실제 실행 환경과 거의 유사 → 높다 | 실제 실행 환경을 알 수 없음 → 낮다 (특히 False Positive가 높음) |
코드 실행 환경 구축 | 어렵다 | 쉽다 |
시간 | 오래 걸린다 | 적게 걸린다 |
코드 커버리지 | 낮다 | 높다 |
결과적으로는 (Dynamic 기법의 단점) > (Static 기법의 단점) 이어서 Android app에서는 Static 기법이 더 많이 사용된다.
*코드 커버리지(Code Coverage)
- 소프트웨어의 테스트를 논할 때 얼마나 테스트가 충분한가를 나타내는 지표 중 하나
- 가능한 모든 분기나 흐름을 커버할수록 높다.
*거짓 양성(False Positive)
- 음성(negative)을 양성(positive)으로 잘못 판정하는 오류
- 실제로는 유해하지 않지만 유해하다고 결과가 나오는 것
Static Taint Analysis의 Challenges
① Dalvik bytecode에 대한 분석의 어려움
- stack 기반, OP code 많음, 깔끔한 처리가 어려운 부분 많음
② Main entrypoint가 없음
- app은 각 component들이 각 lifecycle을 따라 맞물리며 동작한다.
- main entrypoint를 만들어야 한다.
③ Java reflection, Implicit flow, ICC(Inter-component communication) 등의 처리가 어려움
Flowdroid를 통해 알아보는 Static Taint Analysis
Consideration 1 - Android Specific Features
① Android framework modeling
- Android framework 모델링: 어떤 함수가 데이터를 어떻게 처리하는지 보기 쉽게 정리하는 것
- Conservative approach: 어떤 함수의 parameter 중 1개라도 tainted 되었다면, 나머지 parameter와 return value를 모두 tainted 되었다고 간주하는 것
② Component lifecycle
- Android app은 4가지 컴포넌트로 구성: Activity, Service, Broadcast Receiver, Content Provider
- 각 컴포넌트는 생성, 시작, 재개, 정지, 중지, 종료의 lifecycle을 가진다.
- main entrypoint가 없다. lifecycle을 분석해야 실행 흐름을 파악할 수 있다.
- 이벤트에 따른 callback 함수를 분석해야 한다. callback 함수는 언제 일어날지 모르는데, 이것을 파악해야 한다.
③ ICC(Inter-component communication)
- 컴포넌트는 다른 컴포넌트와 소통할 때 Intent를 이용한다.
Explicit Intent | 어떤 컴포넌트와 소통할지 명시해주는 것 |
Implicit Intent | 소통할 컴포넌트를 Android System이 찾아주도록 요청하는 것 |
④ Native Code
- C/C++로 컴파일된 라이브러리를 Android에서 사용할 수 있는데, Java는 C/C++ 라이브러리를 전혀 해석할 수 없다.
- ①과 마찬가지로 Native Function 모델링과 Conservative approach를 한다.
Consideration 2 - Sensitivities
① Flow Sensitivity
- 실행 흐름, 즉 명령어의 순서를 고려해야 한다.
② Object Sensitivity
- 객체 지정, 함수의 흐름, 객체 내부의 함수 호출 등을 하나하나 고려해야 한다.
Consideration 3 - Implicit Flow
- taint가 실행 흐름에 간접적으로 영향을 주어 결과값을 다르게 만드는 것
- taint의 직접적인 영향이 없으므로 taint 전파가 아닌 것이 아니라, implicit flow라고 부르는 간접적인 전파이다.
Consideration 4 - Java-specific features
- 분석을 까다롭게 만드는, Java에서 지원하는 기능들
Reflection | 객체를 직접 호출하지 않고, Java에서 제공하는 Reflection 기능을 이용해 호출하는 것 중요한 데이터를 비밀스럽게 호출하거나 숨기거나, private 함수나 변수를 변경한 다음에 호출을 하는 등 특이한 흐름들을 만들어낼 수 있다. |
Exception | 상황에 따라 예외처리가 달라지기 때문에 처리하기 까다롭다. |
위의 considerations를 모두 고려해서 만든 것이 Flowdroid이다.
Flowdroid
소개
- 2014년에 발표된 Android app Static Taint Analysis 도구
- 현재 존재하는 Static Analysis 도구 중 뛰어난 성능을 보유
- 현재까지 업데이트되고 있는 도구. 다른 도구들은 업데이트가 중단되어 최신 app을 진단하기에 무리가 있다.
구동 방법
Soot
- Java bytecode를 Jimple로 변환하고, callgraph를 생성한다.
- Jimple: Java bytecode를 분석하기 깔끔한 형태로 표현한 것
IFDS framework (Interprocedural, Finite, Distributive, Subset problems)
- 생성된 callgraph를 기반으로 data-flow analysis를 poly-time 내에 풀어낼 수 있도록 하는 알고리즘
- 정확성을 살짝 희생하고, 유한한 시간 내에 해결한다.
IFDS Solver
- 생성된 callgraph를 이용해서 그래프를 만들어가며 데이터 흐름을 분석한다.
- IFDS 형식으로 만들어진 알고리즘을 단순히 풀어내는 역할
- 즉, IFDS만으로는 taint analysis를 할 수 없다.
FlowDroid Core
- taint analysis를 할 수 있도록 만들어준다.
- 소스 코드를 분석해서 IFDS Solver가 풀 수 있는 문제를 만드는 역할
- taint와 taint source가 무엇인지, taint가 언제 생성, 전파, 소멸되고 어떤 흐름에서 어떻게 전파되는지 등을 만드는 역할
나머지
- FlowDroid Core가 지원하는 기능들을 보조한다.
- Source Sink Manager: 소스 싱크를 구별한다.
- Native Call Handler: native 함수를 어떻게 처리할지에 대해 도움을 준다.
Component Lifecycle을 고려한 모델링 기법
- 컴포넌트들은 AndroidManifest.xml에 등록되어 있다.
- lifecycle의 실행 순서를 알 수 없다.
- 따라서 가능한 모든 흐름에 대해 모델링한다.
- Callback 함수는 언제 실행될지 모르므로 임의의 위치에 등장하는 것으로 가정한다.
- 개별 컴포넌트의 실행 순서도 임의의 순서로 가정한다. 무엇이 먼저 실행될지 모르므로 가능한 모든 조합을 고려한다.
- 개별 컴포넌트를 각각 모델링하고 app에 존재하는 모든 컴포넌트들을 합쳐서 하나의 main 함수를 생성하고, 추후 분석에서 entry point로 사용한다.
Taint Propagation Rules
normal flow | 함수 호출이나 리턴이 없는 흐름 |
call flow | 함수 호출이 있는 흐름. call flow가 일어나면 해당 함수로 흐름이 넘어간다. |
return flow | 함수가 return할 때 일어나는 흐름 |
call-to-return flow | call 함수지만 시스템에서 native 함수처럼 특별하게 처리해야 될 경우에 특별한 로직을 넣는 흐름 |
Stubdroid
- Android framework를 미리 모델링해서 가지고 있는 것
- Android framework를 Flowdroid를 이용해서 하나하나 분석하는 것은 비효율적이고 시간이 많이 들기 때문에 pre-compute하는 것
- Stubdroid를 사용하면 Flowdroid의 실행 시간 단축이 가능하다.
Native 함수 처리
- 지금까지의 모든 분석기는 Java 기준이기 때문에 C/C++로 짜여진 라이브러리의 실행 흐름 분석이 불가
- Modeling 또는 Over-approximation 중 하나 이상을 사용하여 해결한다. Flowdroid는 둘 다 사용한다.
Modeling | 일부 또는 자주 쓰이는 라이브러리의 모델링을 진행한다. |
Over-approximation | 블랙박스 접근법. 어떤 함수의 parameter 중 1개라도 tainted 되었다면, 나머지 parameter와 return value를 모두 tainted 되었다고 간주한다. |
연구 동향
~ 2015년 | 연구 분야의 탄생 |
~ 2018년 | 연구 발전의 정점: 대표적인 도구들의 자리잡음 (Flowdroid, Amandroid, Droidsafe) 대표적인 도구들의 성능을 비교하는 연구들이 등장 Static Analysis의 challenges를 해결하려는 연구들이 등장 |
~ 2019년 | 다양한 분야로의 발전 |
앞으로 | Static Taint Analysis의 한계 ① Native 라이브러리의 비중 증가 ② 정확도 및 시간의 문제 Static Taint Analysis의 활용 ① 머신 러닝 ② Energy Leak Detection 디지털 포렌식에의 적용 - Source를 수집하고자 하는 증거, Sink를 데이터의 저장 위치로 하면 자동화 포렌식을 할 수 있다. - 분석가: 분석 시간 단축, 분석 정확도 증가 - 피의자: 불필요한 개인정보 유출 방지 |