跳到内容

安全软件工程/DroidBench

存储库文件导航

DroidBench 2.0

DroidBench是一个开放测试套件,用于评估专门针对Android应用程序的污染分析工具的有效性。该套件可用于评估静态和动态污染分析,但特别是它包含有趣的静态分析问题的测试用例(字段敏感性、对象敏感性、访问路径长度的权衡等),以及特定于Android的挑战,如正确建模应用程序的生命周期,充分处理异步回调并与UI交互。

该发行版包含一个包含所有源代码项目以及易于编译的APK的eclipse工作区。

DroidBench由Christian Fritz、Steven Arzt和Siegfried Rasthofer创建EC SPRIDE安全软件工程组.另一个与DroidBench目标相同的基于Java的基准套件是安全工作台其中重点介绍了用Java编写的基于Web的应用程序。

我们欢迎您的贡献!

非常欢迎您为DroidBench贡献更多测试用例。为此,请派生项目,提交适当的Eclipse源项目和APK,更新此README,然后向我们发送拉请求。

2.0版

2.0版包含以下120个测试用例:

混叠

  • 合并1:将敏感数据分配给堆对象,然后对其进行乱序处理。只泄漏了常量数据。

数组和列表

  • 数组访问1:将污染值和未污染值存储在数组中,然后泄漏未污染值。数组索引是常量。
  • 数组访问2:将污染值和未污染值存储在数组中,然后泄漏未污染值。计算阵列索引。
  • 阵列副本1:将受污染的值存储在数组中,然后使用System.arraycopy将数据复制到新数组,然后泄漏到日志中。
  • 排列到字符串1:IMEI存储在String的数组中,然后使用Arrays.toString()将其转换回String。
  • 哈希映射访问1:将受污染和未受污染的值存储在哈希映射中,然后泄漏未受污染值。映射键是常量。
  • 列表访问1:污染值和未污染值都存储在列表中。只有未着色的值会泄漏。
  • 多维数组1:将受污染的值存储在二维数组中,并通过指向包含受污染值的切片的引用访问该值。

回调

  • 匿名Class1:为匿名内部类中的位置更新注册回调处理程序,并在回调中泄漏传入的位置数据。
  • 按钮1:用户单击按钮后调用接收器。按钮处理程序是通过XML定义的。
  • 按钮2:只有按特定顺序单击按钮才会导致数据泄漏。
  • 按钮3:在另一个回调处理程序中注册了一个新回调。第二个处理程序泄漏第一个处理程序获得的数据。
  • 按钮4:用户单击按钮后调用接收器。按钮处理程序是使用include指令通过XML定义的。
  • 按钮5:IMEI是在Activity的onCreate()期间获得的,随后通过布局的xml中定义的onClick回调泄漏。请注意,第一次单击仅将IMEI存储到按钮提示中。只有第二次点击才会真正泄漏。
  • 位置泄漏1:注册侦听器以进行位置更新,存储值并在生命周期中稍后泄漏。
  • 位置泄漏2:与LocationLeak1类似,但活动类直接实现回调接口。
  • 位置泄漏3:与LocationLeak1类似,但回调处理程序位于使用接口与活动解耦的专用类中。
  • 方法覆盖1:覆盖内部Android方法以隐藏泄漏。
  • 多处理程序1:包含两个活动和两个处理程序,如果正确的活动与正确的处理程序一起使用,则不会泄漏任何数据。
  • 订购1:在初始化变量的处理程序注册之前泄漏变量内容。
  • 寄存器全局1:源和接收器都是全局(应用程序级)生命周期处理程序的一部分。
  • 注销1:在调用回调之前注册并直接注销回调。因此,回调中的代码永远不会泄漏任何数据。

场和对象灵敏度

  • 现场灵敏度1:受污染和未受污染的数据都存储在数据对象中;未着色的值被泄漏。
  • 现场敏感性2:与FieldSensitivity1类似,但源和接收器调用分布在整个生命周期中。
  • 现场灵敏度3:受污染和未受污染的数据都存储在数据对象中;被污染的价值被泄露了。源和接收器调用分布在整个生命周期中。
  • 现场灵敏度4:在污染字段之前发送字段内容。
  • 继承的对象1:基于条件选择对象的实际类型。只有一种可能导致泄漏。
  • 对象灵敏度1:将受污染的值写入对象,将未受污染的写入相同类型的另一个对象。泄漏未着色的值。
  • 对象灵敏度2:将受污染的值写入字段,然后用未被污染的数据覆盖它。

应用程序间通信

  • 回音器:接收数据并将其回传给发送方。
  • 发送SMS:读取设备ID,通过Echoer传递,然后通过文本消息发送。
  • 开始结果活动1:读取用户的地理位置(通过GPS),通过Echoer传递,然后将其写入文件。

组件间通信

  • 活动沟通1:包含使用静态字段进行通信的两个活动。
  • 活动沟通2:IMEI在一个Activity中获得,并存储在Intent的额外部分中,用于启动下一个Activaty,然后该Activity会将IMEI泄漏到日志中。
  • 活动沟通3:使用类名启动另一个“活动”。IEMI在要启动的活动中泄漏。
  • 活动沟通4:启动另一个“活动”的意图是通过连接两个常量字符串创建的。要启动的活动泄漏了作为Intent的附加项传入的IMEI。
  • 活动沟通5:使用常量组件的Name和Intent.setComponent启动“活动”。启动的“活动”将IMEI泄漏到日志中。
  • 活动沟通6:启动另一个活动的意向通过LinkedList的add()传递,并使用LinkedList.get()检索。检索到的Intent用于启动泄漏的Activity。
  • 活动沟通7:创建Activity类,并使用实例对象上的getClass()检索其类名。然后使用类名启动第二个Activity,该Activity从Intent的extra中泄漏IMEI信息。
  • 活动沟通8:Intent启动另一个Activity的操作通过LinkedList.get()传递并检索。检索到的字符串用于启动泄漏的“活动”。
  • 广播TaintandLeak1:IMEI是在活动中获得的,并存储在以编程方式注册的BroadcastReceiver的Intent之外的Intent中。接收方泄漏IMEI信息。
  • 部件不在清单1中:IMEI在一个Activity中获得,并存储在Intent中,以启动不在AndroidManifest.xml中的泄漏Activity。由于无效,因此不会发生泄漏。
  • 事件排序1:IMEI获取并存储在次要活动(InFlowActivity)的SharedPreferences中。第一个活动(OutFlowActivity)启动第二个活动。第二次启动第二个活动时,IMEI会泄漏到日志中。
  • 意向接收器1:活动导致受污染的值泄漏。
  • 意向接收器2:与IntentSink类似,但该值是在XML中定义的回调方法中发送的。
  • 意向来源1:两个受污染的泄漏:第一个是受污染的值使用startActivityForResult的意图泄漏到另一个应用程序。另一个是onActivityResult方法将意图作为受污染的数据进行记录。
  • 服务通信1:IMEI被获取并发送到服务,然后该服务会泄漏Messenger处理程序中的信息。
  • 共享首选项1:IMEI是在一个“活动”中获取的,并存储在另一“活动”泄漏的SharedPreferences中。
  • 单体1:IMEI存储在一个“活动”中的单例对象中,并在另一个“活动”中泄漏。
  • 无法解决的Intent1:应用程序尝试在无法静态解析的Intent中启动Activity。两个Activity中的一个可以基于随机布尔值启动,并且它们都会将IMEI从启动Activity泄漏到日志。

生命周期

  • 活动生命周期1:对跨活动生命周期分布的源和汇的调用。
  • 活动生命周期2:从包含泄漏受污染值的生命周期方法的超类继承的活动类。
  • 活动生命周期3:对跨实例状态处理方法分布的源和汇的调用。
  • 活动生命周期4:在上获取污染值onPause()并在稍后重新启动活动时泄漏。
  • 活动保存状态1:IMEI在onSaveInstanceState()期间通过捆绑包的持久性保存,并在下次onCreate()时泄漏
  • 应用程序生命周期1:在启动应用程序时获取机密值,并在主活动的onResume()方法中发送。
  • 应用程序生命周期2:在启动应用程序时获取秘密值,并在应用程序的低内存回调中发送。
  • 应用程序生命周期3:在初始化内容提供程序时获取机密值,并将其泄漏到应用程序的onCreate()方法中。
  • 异步事件排序1:在onResume()期间获取IMEI,并在onStop()期间通过在onLowMemory()中覆盖来泄漏IMEI。
  • 广播接收器生命周期1:对广播接收器生命周期中分布的源和汇的调用。
  • 广播接收器生命周期2:敏感数据在onCreate()中读取,并在动态注册的广播接收器中发送。
  • 事件排序1:IMEI是在第一次调用onLowMemory时获得的,在第二次调用onLawMemorys时泄漏,但只有在两者之间没有发生onContentChanged()。
  • 碎片生命周期1:对跨片段生命周期分布的源和汇的调用。
  • 服务生命周期1:对跨服务生命周期分布的源和汇的调用。
  • 服务生命周期2:IMEI在onStartCommand结束时获取,并存储到服务的字段中。服务命令第二次启动时泄漏。
  • 共享首选项更改1:onCreate(),IMEI被放入SharedPreferences,并触发onSharedPrefenceChanged(),然后将IMEI泄漏到Android日志。

通用Java

  • 克隆1:IMEI被添加到链接列表,列表被克隆到新列表,然后新列表中受感染的成员被泄漏。
  • DirectBuffer(直接缓冲区):受污染的ByteBuffers不足/过度的测试用例。
  • 例外情况1:将受污染的值保存到局部变量中,引发异常并在异常处理程序中发送该值。
  • 例外情况2:将受污染的值保存到本地变量中,隐式引发异常(ArrayIndexOutOfBounds),并在异常处理程序中发送数据。
  • 例外情况3:将受污染的值保存到局部变量中,但不会调用将其发送出去的异常处理程序。
  • 例外4:抛出包含受污染值的异常并将其发送到异常处理程序中。
  • 工厂方法1:从Android操作系统中包含的工厂方法获取LocationManager,读取位置并泄漏。
  • 回路1:包含简单循环和数据泄漏。
  • 回路2:通过回调检索位置信息并通过嵌套循环泄漏。
  • 序列化1:通过ObjectOutputStream和ObjectInputStreamIMEI获取并序列化/反序列化。
  • 源代码特定1:使用不寻常的代码构造a=p?b:c。
  • 启动具有机密的进程1:IMEI是通过ProcessBuilder的start()获取和泄漏的。
  • 静态初始化1:将受污染的值传递到静态初始化方法中。
  • 静态初始化2:在类的静态初始化过程中获取敏感数据,并在非状态代码中泄漏
  • 静态初始化3:IMEI是在静态初始值设定项期间获得的,存储并覆盖在“活动”的字段中,该字段在开始时未被污染。
  • 字符串格式设置符1:IMEI被传递给格式化程序,然后格式化的缓冲区在泄漏到日志之前被转换回String。
  • 字符串模式匹配1:IMEI与.*正则表达式匹配,匹配的组被泄漏。
  • 字符串到字符数组1:IMEI被获取并存储在char[]中,然后在泄露到日志之前将其转换为String。
  • 字符串到输出流1:获取IMEI并通过ByteArrayOutputStream作为String字节传递回String。
  • 无法访问的代码:将受污染的数据传递到从未调用的方法中。
  • 虚拟调度1:根据单击计数器的不同,会实例化一个或另一个类。然而,实际上只有一个类泄漏数据,这是唯一一个泄漏常量字符串的类。
  • 虚拟调度2:基类中的方法返回未着色的信息,派生类之一中的相同方法返回敏感(IMEI)信息。该信息随后通过短信泄露。
  • *虚拟调度3:两个类实现了一个接口,但其中只有一个类返回敏感数据。然而,泄漏发生在仅返回常量数据的另一个实现上。
  • *虚拟调度4:类似于VirtualDispatch3,但类型信息稍多。

其他特定机器人

  • 应用程序建模1:将IMEI存储在Application的对象中,然后在其他Activity中泄漏它。
  • 直接泄漏1:通过活动的SMS读取并发送设备id创建时()事件。
  • 非活动活动:禁用活动中的数据泄漏。
  • LogNoLeak(日志无泄漏):将未着色的数据写入日志文件。
  • 模糊处理1:此APK包含自己的android.telephony实现。电话管理器。然而,在真实设备上,预加载的操作系统实现将始终隐藏自定义的操作系统,并且您将始终获得真实的IMEI。在Galaxy Nexus 4上进行测试,但不能保证模拟器。
  • 图书馆1:不是独立的测试用例,是Library2的一部分。
  • 图书馆2:IMEI在自定义库中读取,然后在应用程序中泄漏。
  • 私人数据泄漏1:包含各种挑战的摘要测试用例。
  • 私人数据泄漏2:泄漏密码字段中的值。
  • 私人数据泄露3:IMEI被写入一个文件,再次读取,然后泄露。
  • 公共API字段1:获得IMEI并将其转换为2个浮点数,如PointF的x和y。PointF的值泄漏。
  • 公共API字段2:IMEI作为数据持有者检索并存储到Intent.action。

隐式流

  • 隐含流量1-4:隐式流的测试用例。

反思

  • 反思1:敏感数据存储在反射类的字段中,然后直接再次读取并泄漏。
  • 反思2:敏感数据存储在反射类的字段中,使用“未知”类中实现的方法再次读取并泄漏。
  • 反思3:敏感数据使用setter存储在反射类中,使用getter读回,然后泄漏。未使用目标类的类型信息。
  • 反思4:使用反射类中的函数读取敏感数据,并使用同一反射类中另一个函数泄漏。

螺纹加工

  • 异步任务1:敏感数据在onCreate()中读取,并在使用Android的AsyncTask机制启动的专用线程中发送。
  • Java线程1:敏感数据在onCreate()中读取,并在使用Java的正常线程机制启动的专用线程中发送。
  • Java线程2:敏感数据在onCreate()中读取,并在使用Java的Runnable机制启动的专用线程中发送。
  • 执行人1:敏感数据在onCreate()中读取,并在使用Java的Executor机制启动的专用线程中发送。
  • 织机1:敏感数据在onCreate()中读取并排队等待托管Android Looper的自定义线程,该线程的处理程序会发送数据。

模拟器检测

  • 仿真程序检测内容提供商1:此测试用例通过检查内容提供商中的IMEI来检测Android模拟器。如果应用程序在真实手机上运行,IMEI只会在活动中通过短信发送。
  • 仿真程序检测_IMEI1:此测试用例通过截断从IMEI计算的位置泄漏的机密数据来检测Android模拟器。在模拟器上,IMEI应为00..0。
  • EmulatorDetection_PlayStore1仿真程序:此测试用例通过手机上是否安装了Play Store应用程序来检测Android模拟器。IMEI仅在应用程序在真实手机上运行时通过短信发送。

致谢

除其他外,我们要感谢以下组织作出了贡献DroidBench的测试用例:

关于

用于评估Android污染分析工具稳定性的微基准套件

资源

星星

观察者

叉子

包装

未发布包

语言文字