sqlite android 卸载后_android安全测试静态分析之存储[一]
概述存储数据对于许多移动应用程序至关重要。传统观点认为,应将尽可能少的敏感数据存储在永久本地存储中。但是,在大多数实际情况下,必须存储某种类型的用户数据。例如,就可用性而言,要求用户在应用每次启动时输入一个非常复杂的密码并不是一个好主意。为了避免这种情况,大多数应用程序必须在本地缓存某种身份验证令牌。如果给定方案需要,还可以保存个人身份信息(PII)和其他类型的敏感数据。如果敏感数据没有...
概述
存储数据对于许多移动应用程序至关重要。传统观点认为,应将尽可能少的敏感数据存储在永久本地存储中。但是,在大多数实际情况下,必须存储某种类型的用户数据。例如,就可用性而言,要求用户在应用每次启动时输入一个非常复杂的密码并不是一个好主意。为了避免这种情况,大多数应用程序必须在本地缓存某种身份验证令牌。如果给定方案需要,还可以保存个人身份信息(PII)和其他类型的敏感数据。
如果敏感数据没有得到持久存储的应用程序的适当保护,则很容易受到攻击。该应用程序可能能够将数据存储在多个位置,例如,在设备上或在外部SD卡上。当您尝试利用这类问题时,请考虑可能会处理许多信息并将其存储在不同的位置。
首先,重要的是识别由移动应用程序处理并由用户输入的信息的种类。接下来,确定对攻击者可能有价值的敏感数据(例如,密码,信用卡信息,PII)并不总是一件容易的事,它很大程度上取决于目标应用程序的上下文。
泄露敏感信息会带来多种后果,包括解密信息。通常,攻击者可能会识别此信息并将其用于其他攻击,例如社交工程(如果已公开PII),帐户劫持(如果已公开会话信息或身份验证令牌)以及从具有以下功能的应用中收集信息:付款方式(攻击和滥用它们)。
数据存储概述
Android根据用户,开发人员和应用程序的需求提供了多种数据存储方法。例如,某些应用程序使用数据存储来跟踪用户设置或用户提供的数据。可以通过几种方式持久存储该用例的数据。以下持久性存储技术列表已在Android平台上广泛使用:
-
Shared Preferences
-
SQLite Databases
-
Firebase Databases
-
Realm Databases
-
Internal Storage
-
External Storage
-
Keystore
除此之外,Android中还针对各种用例构建了许多其他功能,这些功能也可能导致数据存储,因此也应分别进行测试,例如:
-
Logging Functions
-
Android Backups
-
Processes Memory
-
Keyboard Caches
-
Screenshots
了解每个相关的数据存储功能以正确执行适当的测试用例很重要。
Shared Preferences
SharedPreferences API通常用于永久保存键值对小集合。存储在SharedPreferences对象中的数据将写入纯XML文件中。可以将SharedPreferences对象声明为世界可读(所有应用程序都可以访问)或私有的。滥用SharedPreferences API通常会导致敏感数据暴露。考虑以下示例:
java示例:
SharedPreferences sharedPref = getSharedPreferences("key", MODE_WORLD_READABLE);SharedPreferences.Editor editor = sharedPref.edit();editor.putString("username", "administrator");editor.putString("password", "supersecret");editor.commit();
调用活动后,将使用提供的数据创建文件key.xml。此代码违反了几种最佳做法。
-
用户名和密码以明文形式存储在中
/data/data//shared_prefs/key.xml。<?xml version='1.0' encoding='utf-8' standalone='yes' ?> administrator supersecret -
MODE_WORLD_READABLE
允许所有应用程序访问和读取的内容key.xml`。root@hermes:/data/data/sg.vp.owasp_mobile.myfirstapp/shared_prefs # ls -la-rw-rw-r-- u0_a118 170 2016-04-23 16:51 key.xml
请注意,
MODE_WORLD_READABLE并且MODE_WORLD_WRITEABLE从API级别17开始不推荐使用。尽管较新的设备可能不受此影响,但是如果编译的android:targetSdkVersion值小于17的应用程序运行在Android 4.2之前发布的操作系统版本(API级别17,则可能会受到影响) )。
Databases
如上所述,Android平台提供了许多数据库选项。每个数据库选项都有其自己的怪癖和方法.
SQLite Database (Unencrypted)
SQLite是一个SQL数据库引擎,用于将数据存储在.db文件中。Android SDK内置了对SQLite数据库的支持。用于管理数据库的主要软件包是android.database.sqlite。例如,您可以使用以下代码在活动中存储敏感信息:
java示例:
SQLiteDatabase notSoSecure = openOrCreateDatabase("privateNotSoSecure", MODE_PRIVATE, null);notSoSecure.execSQL("CREATE TABLE IF NOT EXISTS Accounts(Username VARCHAR, Password VARCHAR);");notSoSecure.execSQL("INSERT INTO Accounts VALUES('admin','AdminPass');");notSoSecure.close();
调用活动后,privateNotSoSecure将使用提供的数据创建数据库文件并将其存储在明文文件中/data/data//databases/privateNotSoSecure。
除了SQLite数据库外,数据库的目录可能还包含几个文件:
-
Journal files: 这些是用于实现原子提交和回滚的临时文件。
-
Lock files:锁定文件是锁定和日记功能的一部分,该功能旨在提高SQLite并发性并减少编写程序不足的问题。
敏感信息不应存储在未加密的SQLite数据库中。
SQLite Databases (Encrypted)
使用库SQLCipher,可以对SQLite数据库进行密码加密。
java示例:
SQLiteDatabase secureDB = SQLiteDatabase.openOrCreateDatabase(database, "password123", null);secureDB.execSQL("CREATE TABLE IF NOT EXISTS Accounts(Username VARCHAR,Password VARCHAR);");secureDB.execSQL("INSERT INTO Accounts VALUES('admin','AdminPassEnc');");secureDB.close();
检索数据库密钥的安全方法包括:
-
打开应用后,要求用户使用PIN或密码对数据库解密(弱密码和PIN容易受到暴力攻击)
-
将密钥存储在服务器上,并仅允许通过Web服务对其进行访问(这样,仅当设备在线时才能使用该应用程序)
Firebase Real-time Databases
Firebase是一个包含超过15种产品的开发平台,其中之一是Firebase实时数据库。应用程序开发人员可以利用它来存储数据并与NoSQL云托管数据库同步。数据存储为JSON,并实时同步到每个连接的客户端,即使应用程序脱机也保持可用。
可以通过以下网络调用来识别配置错误的Firebase实例:
https://_firebaseProjectName_.firebaseio.com/.json
firebaseProjectName可以从通过逆向工程应用程序的移动设备应用程序来检索。或者,可以使用Firebase Scanner,这是一个使上述任务自动化的python脚本,如下所示:
python FirebaseScanner.py -p < pathOfAPKFile >python FirebaseScanner.py -f < commaSeperatedFirebaseProjectNames >
Realm Databases
可以使用配置文件中存储的密钥对数据库及其内容进行加密
//the getKey() method either gets the key from the server or from a KeyStore, or is derived from a password.RealmConfiguration config = new RealmConfiguration.Builder() .encryptionKey(getKey()) .build();Realm realm = Realm.getInstance(config);
如果数据库未加密,则应该能够获取数据。如果数据库已加密,请确定密钥是否在源或资源中进行了硬编码,以及是否在不受保护的共享首选项或其他位置存储了密钥。
Internal Storage
您可以将文件保存到设备的内部存储中。默认情况下,保存到内部存储器的文件是容器化的,设备上的其他应用程序无法访问。当用户卸载您的应用程序时,这些文件将被删除。以下代码段会将敏感数据持久存储到内部存储中。
Java示例:
FileOutputStream fos = null;try { fos = openFileOutput(FILENAME, Context.MODE_PRIVATE); fos.write(test.getBytes()); fos.close();} catch (FileNotFoundException e) { e.printStackTrace();} catch (IOException e) { e.printStackTrace();}
应该检查文件模式,以确保只有应用程序可以访问文件。可以使用设置此访问权限MODE_PRIVATE。诸如MODE_WORLD_READABLE(不推荐使用)和MODE_WORLD_WRITEABLE(不推荐使用)之类的模式可能会带来安全风险。
搜索该类FileInputStream以找出哪些文件已打开并在应用程序中读取。
External Storage
每个与Android兼容的设备都支持共享的外部存储。该存储可以是可移动的(例如SD卡)或内部的(不可移动)。保存到外部存储器的文件是世界可读的。启用USB大容量存储后,用户可以修改它们。您可以使用以下代码段将敏感信息作为文件内容持久存储到外部存储中password.txt。
Java示例:
File file = new File (Environment.getExternalFilesDir(), "password.txt");String password = "SecretPassword";FileOutputStream fos; fos = new FileOutputStream(file); fos.write(password.getBytes()); fos.close();
当用户卸载应用程序时,存储在应用程序文件夹(data/data//)外的文件不会被删除
值得注意的是,攻击者可以使用外部存储来允许在某些情况下对应用程序进行任意控制。
KeyStore
下期~
~~以上,END~~
推荐阅读点击阅读☞性能测试中的可伸缩性测试
点击阅读☞shell语言进行接口自动化
点击阅读☞100多种最佳软件测试工具介绍-1
点击阅读☞数据库基础.1
点击阅读☞自动化之UI(autoit)

更多推荐



所有评论(0)