Android Master Key Vulnerability Android Bug 8219321 2013/08/06 http://johnzon3.tistory.com Johnzone
内容 1. 개요... 2 1.1. 취약점요약... 2 1.2. 취약점정보... 2 2. 분석... 2 2.1. 기본개념... 2 2.2. 공격방법... 4 3. 방어대책... 7 4. References... 8
1. 개요 1.1. 취약점요약 이것은 Android security Bug 8219321 와 Master Key Vulnerability 로알려진취약점입니다. Android 1.6 부터 4.2 까지어플리케이션의암호화서명을정확하게체크하지않습니다. 이때 APK 파일은 ZIP 파일형식을가지고있는데만약같은이름의서로다른두개의 Entry 가존재할경우공격자는 APK 파일에암호화서명에위반되지않는임의의파일을생성할수있습니다. 1.2. 취약점정보 취약점이름 Android Master Key Vulnerability (Android Bug 8219321) 최초발견일자 2013/02 월 (Android Bug 8219321) CVE 명 CVE-2013-4787 CVE 등록일자 2013/07/09 위험등급 높음 (9.3) 2. 분석 2.1. 기본개념 APK 파일은 ZIP 파일형태로이루어져있습니다. 이때 APK 파일은 META-INF 폴더에서 MANIFEST.MF 파일을참조하여해당파일의위변조상황을 ZipFile 라는클래스에서 HashMap 형태로저장하게되는데 classes.dex 라는같은이름의파일이존재하게될경우 HashMap 클래스에서는중복을허용하지않아해당값을덮어쓰는취약점이존재합니다. 이경우 APK 파일을따로자가서명 (Self Signing) 하지않아도사용할수있습니다.
Manifest-Version: 1.0 Created-By: 1.0 (Android) Name: resources.arsc SHA1-Digest: PeGR4Th/o6th5FTq2s9UqSSsj80= Name: AndroidManifest.xml SHA1-Digest: Bx4FbcrctpgqEVmtxuOrNoAz3yI= Name: classes.dex SHA1-Digest: QhhKIzuo/WSxPZtUcbi+1me/BB0=.. <MANIFEST.MF> 해당 APK 파일은각파일의 Hash 정보를 Manifest.MF 에저장합니다. 이것은나중에 Android 의 PackageParser 에서해당 APK 파일을가지고오게되는데이때 ZipFile.java 클래스에서해당정보를 HashMap 클래스형태로담당합니다. 해당 APK 파일안에는여러가지파일이존재하는이때사용된암호화서명과일치하지않을경우설치가진행되지않습니다. 이때 HashMap<Key, Value> 에대해서간단하게살펴보겠습니다. HashMap<String, String> hashmap = new HashMap<String, String>(); hashmap.put( resources.arsc, PeGR4Th/o6th5FTq2s9UqSSsj80= ); hashmap.put( AndroidManifest.xml, Bx4FbcrctpgqEVmtxuOrNoAz3yI= ); hashmap.put( classes.dex, QhhKIzuo/WSxPZtUcbi+1me/BB0= ); 이형태로저장이되어관리됩니다. 이때 HashMap 은 Key 의중복이허용되지않습니다. 만약똑같은 Key 가두개이상존재한다면, 제일마지막 Value 가저장이됩니다.
HashMap<String, String> hashmap = new HashMap<String, String>(); hashmap.put( resources.arsc, PeGR4Th/o6th5FTq2s9UqSSsj80= ); hashmap.put( AndroidManifest.xml, Bx4FbcrctpgqEVmtxuOrNoAz3yI= ); hashmap.put( classes.dex,????? ); // 알수없는위변조된 dex 파일이있을경우 hashmap.put( classes.dex, QhhKIzuo/WSxPZtUcbi+1me/BB0= ); ZipFile.java 에서는해당파일이존재하더라도 classes.dex 라는 Key 가두개존재하므로 제일나중에집어넣은 classes.dex 파일의 value 로덮어쓰게됩니다. 2.2. 공격방법 http://johnzon3.tistory.com/attachment/cfile9.uf@2332394751ff842719b3bb.apk 기본적인 HelloWorld app 화면입니다. 해당앱은임의의코드를삽입하면서주소록을볼수있도록 permission 을추가했습니다. 이경우방법이 2 가지가있습니다. 1. 기존의 dex 파일을 smali 코드를수정하여리패키징 2. AndroidManifest.xml 에있는해당패키지, 클래스들을그대로복원하여해당소스를재구성.
해당앱의경우소스가간단하기때문에 2 번방법을사용하도록하겠습니다. public class MainActivity extends Activity { @Override protected void oncreate(bundle savedinstancestate) { LinearLayout linear = new LinearLayout(this); TextView tv = new TextView(this); ArrayList<Contact> list = getcontactlist(); String result = null; for (int i = 0; i < list.size(); i++) { result+=list.get(i).tostring()+"\n"; } tv.settext(result); linear.addview(tv); super.oncreate(savedinstancestate); setcontentview(linear); } 기존의앱에있던패키지명과동일하고해당클래스명도동일하게구성하였지만 activity_main.xml 을불러오는코드가아닌자바코드에서 getcontactlist 라는함수를만들어주소록을불러오고, TextView 로표시하는코드입니다. 해당파일을컴파일하고 classes.dex 파일을가지고옵니다. 그리고 dex 파일을구별하기위해서 evil.dex 파일이라고파일명을변경하였습니다. classes.dex -> Mission 에서가지고온원본 dex 파일 (Helloworld) evil.dex -> 삽입하려는악성 dex 파일 ( 주소록표시 ) Mission.apk -> 주소록 permission 이들어간 HelloWorld 파일
이제변조가될 apk 의 zip entry 순서는다음과같아야합니다. HashMap 은나중의결과를덮어쓰므로해당암호화서명을덮어쓰기위해서는원본 classes.dex 파일이뒤로와야합니다. 다음에 Hex Editor 와같은도구를통해 evil.dex -> classes.dex 로변경합니다. 이렇게만들어진해당앱을 JarSigner 로검증하게되면검증되지않습니다. 하지만앱설치는가능합니다. 이때 Dalvik 머신은기존의위변조되었던 evil.dex 가 zip 파일내부에서먼저실행되므로 악성행위가담겨져있는코드가실행이됩니다.
해당공격을통해삽입된 dex 파일이실행되었음을확인할수있습니다. 3. 방어대책 1. 다운로드할어플리케이션의게시자를확인해봐야합니다. 2. 해당프레임워크가취약한버젼인지확인하고패치해야합니다. http://bluebox.com/corporate-blog/free-scanner-to-manage-risk-of-major-androidvulnerability/ 해당앱에서무료로해당디바이스가취약한지확인해주는어플을공개하고있습니다.
4. References [1] : http://bluebox.com/corporate-blog/bluebox-uncovers-android-master-key/ [2] : http://bluebox.com/corporate-blog/free-scanner-to-manage-risk-of-major-androidvulnerability/