@Override public void onResultsAvailable( IInfoflowCFG cfg, InfoflowResults results) { // Dump the results if (results == null) { print("No results found."); } else { for (ResultSinkInfo sink : results.getResults().keySet()) { print("Found a flow to sink " + sink + ", from the following sources:"); for (ResultSourceInfo source : results.getResults().get(sink)) { print("\t- " + source.getSource() + " (in " + cfg.getMethodOf(source.getSource()).getSignature() + ")"); if (source.getPath() != null && !source.getPath().isEmpty()) print("\t\ton Path " + source.getPath()); } } } }
/** * Analyzes the given APK file for data flows * @param fileName The full path and file name of the APK file to analyze * @param enableImplicitFlows True if implicit flows shall be tracked, * otherwise false * @param enableStaticFields True if taints in static fields shall be tracked, * otherwise false * @param flowSensitiveAliasing True if a flow-sensitive alias analysis * shall be used, otherwise false * @return The data leaks found in the given APK file * @throws IOException Thrown if the given APK file or any other required * file could not be found * @throws XmlPullParserException Thrown if the Android manifest file could * not be read. */ public InfoflowResults analyzeAPKFile(String fileName, boolean enableImplicitFlows, boolean enableStaticFields, boolean flowSensitiveAliasing) throws IOException, XmlPullParserException { String androidJars = System.getenv("ANDROID_JARS"); if (androidJars == null) androidJars = System.getProperty("ANDROID_JARS"); if (androidJars == null) throw new RuntimeException("Android JAR dir not set"); System.out.println("Loading Android.jar files from " + androidJars); SetupApplication setupApplication = new SetupApplication(androidJars, fileName); setupApplication.setTaintWrapper(new EasyTaintWrapper("EasyTaintWrapperSource.txt")); setupApplication.calculateSourcesSinksEntrypoints("SourcesAndSinks.txt"); setupApplication.setEnableImplicitFlows(enableImplicitFlows); setupApplication.setEnableStaticFieldTracking(enableStaticFields); setupApplication.setFlowSensitiveAliasing(flowSensitiveAliasing); return setupApplication.runInfoflow(); }
@Test(timeout = 300000) public void aliasStrongUpdateTest() { final String sinkMethod = "<soot.jimple.infoflow.test.HeapTestCode: " + "void leakData(soot.jimple.infoflow.test.HeapTestCode$Data)>"; final String sourceMethod = "<soot.jimple.infoflow.test.HeapTestCode: " + "soot.jimple.infoflow.test.HeapTestCode$Data getSecretData()>"; Infoflow infoflow = initInfoflow(); infoflow.setInspectSources(false); infoflow.setInspectSinks(false); infoflow.setEnableImplicitFlows(false); List<String> epoints = new ArrayList<String>(); epoints.add("<soot.jimple.infoflow.test.HeapTestCode: void aliasStrongUpdateTest()>"); infoflow.computeInfoflow(appPath, libPath, epoints, Collections.singleton(sourceMethod), Collections.singleton(sinkMethod)); Assert.assertTrue(infoflow.isResultAvailable()); InfoflowResults map = infoflow.getResults(); Assert.assertEquals(1, map.size()); Assert.assertTrue(map.containsSinkMethod(sinkMethod)); Assert.assertTrue(map.isPathBetweenMethods(sinkMethod, sourceMethod)); }
@Test public void runTestInsecureBank() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile(false); // 7 leaks + 1x inter-component communication (server ip going through an intent) Assert.assertEquals(12, res.size()); Assert.assertTrue(res.isPathBetweenMethods(activity_startActivity, activity_findViewById)); Assert.assertTrue(res.isPathBetweenMethods(log_e, activity_getIntent)); Assert.assertTrue(res.isPathBetweenMethods(log_e, activity_findViewById)); Assert.assertTrue(res.isPathBetweenMethods(log_e, bundle_getString)); Assert.assertTrue(res.isPathBetweenMethods(log_e, urlConnection_openConnection)); Assert.assertTrue(res.isPathBetweenMethods(log_d, cursor_getString)); Assert.assertTrue(res.isPathBetweenMethods(sharedPrefs_putString, activity_findViewById)); Assert.assertTrue(res.isPathBetweenMethods(sharedPrefs_putString, activity_findViewById)); Assert.assertTrue(res.isPathBetweenMethods(log_i, activity_findViewById)); Assert.assertTrue(res.isPathBetweenMethods(url_init, activity_getIntent)); Assert.assertTrue(res.isPathBetweenMethods(url_init, activity_findViewById)); Assert.assertTrue(res.isPathBetweenMethods(url_init, bundle_getString)); }
protected void checkInfoflow(Infoflow infoflow, int resultCount){ if(infoflow.isResultAvailable()){ InfoflowResults map = infoflow.getResults(); assertEquals(resultCount, map.size()); assertTrue(map.containsSinkMethod(sink) || map.containsSinkMethod(sinkInt) || map.containsSinkMethod(sinkBoolean) || map.containsSinkMethod(sinkDouble)); assertTrue(map.isPathBetweenMethods(sink, sourceDeviceId) || map.isPathBetweenMethods(sink, sourceIMEI) // implicit flows || map.isPathBetweenMethods(sink, sourcePwd) || map.isPathBetweenMethods(sink, sourceBundleGet) || map.isPathBetweenMethods(sinkInt, sourceDeviceId) || map.isPathBetweenMethods(sinkInt, sourceIMEI) || map.isPathBetweenMethods(sinkInt, sourceIMSI) || map.isPathBetweenMethods(sinkInt, sourceLongitude) || map.isPathBetweenMethods(sinkBoolean, sourceDeviceId) || map.isPathBetweenMethods(sinkDouble, sourceLongitude)); }else{ fail("result is not available"); } }
/** * Analyzes the given APK file for data flows * @param fileName The full path and file name of the APK file to analyze * @param enableImplicitFlows True if implicit flows shall be tracked, * otherwise false * @return The data leaks found in the given APK file * @throws IOException Thrown if the given APK file or any other required * file could not be found * @throws XmlPullParserException Thrown if the Android manifest file could * not be read. */ public InfoflowResults analyzeAPKFile(String fileName, boolean enableImplicitFlows) throws IOException, XmlPullParserException { String androidJars = System.getenv("ANDROID_JARS"); if (androidJars == null) androidJars = System.getProperty("ANDROID_JARS"); if (androidJars == null) throw new RuntimeException("Android JAR dir not set"); System.out.println("Loading Android.jar files from " + androidJars); String droidBenchDir = System.getenv("DROIDBENCH"); if (droidBenchDir == null) droidBenchDir = System.getProperty("DROIDBENCH"); if (droidBenchDir == null) throw new RuntimeException("DroidBench dir not set"); System.out.println("Loading DroidBench from " + droidBenchDir); SetupApplication setupApplication = new SetupApplication(androidJars, droidBenchDir + File.separator + fileName); setupApplication.setTaintWrapper(new EasyTaintWrapper("EasyTaintWrapperSource.txt")); setupApplication.calculateSourcesSinksEntrypoints("SourcesAndSinks.txt"); setupApplication.setEnableImplicitFlows(enableImplicitFlows); return setupApplication.runInfoflow(); }
/** * Analyzes the given APK file for data flows * @param enableImplicitFlows True if implicit flows shall be tracked, * otherwise false * @return The data leaks found in the given APK file * @throws IOException Thrown if the given APK file or any other required * file could not be found * @throws XmlPullParserException Thrown if the Android manifest file could * not be read. */ private InfoflowResults analyzeAPKFile(boolean enableImplicitFlows) throws IOException, XmlPullParserException { String androidJars = System.getenv("ANDROID_JARS"); if (androidJars == null) androidJars = System.getProperty("ANDROID_JARS"); if (androidJars == null) throw new RuntimeException("Android JAR dir not set"); System.out.println("Loading Android.jar files from " + androidJars); SetupApplication setupApplication = new SetupApplication(androidJars, "insecureBank" + File.separator + "InsecureBank.apk"); setupApplication.setTaintWrapper(new EasyTaintWrapper("EasyTaintWrapperSource.txt")); setupApplication.setEnableImplicitFlows(enableImplicitFlows); setupApplication.setLayoutMatchingMode(LayoutMatchingMode.MatchAll); setupApplication.calculateSourcesSinksEntrypoints("SourcesAndSinks.txt"); return setupApplication.runInfoflow(); }
/** * Analyzes the given APK file for data flows with a given xml file * @param apkFileName The full path and file name of the APK file to analyze * @param xmlFileName The full path and file name of the xml file where sources and sinks are defined * @param enableImplicitFlows True if implicit flows shall be tracked, * otherwise false * @return The data leaks found in the given APK file * @throws IOException Thrown if the given APK file or any other required * file could not be found * @throws XmlPullParserException Thrown if the Android manifest file could * not be read. */ public InfoflowResults analyzeAPKFile(String apkFileName, String xmlFileName, boolean enableImplicitFlows, boolean enableStaticFields, boolean flowSensitiveAliasing) throws IOException, XmlPullParserException { String androidJars = System.getenv("ANDROID_JARS"); if (androidJars == null) androidJars = System.getProperty("ANDROID_JARS"); if (androidJars == null) throw new RuntimeException("Android JAR dir not set"); System.out.println("Loading Android.jar files from " + androidJars); SetupApplication setupApplication = new SetupApplication(androidJars, apkFileName); setupApplication.setTaintWrapper(new EasyTaintWrapper("EasyTaintWrapperSource.txt")); setupApplication.calculateSourcesSinksEntrypoints(xmlFileName); setupApplication.setEnableImplicitFlows(enableImplicitFlows); setupApplication.setEnableStaticFieldTracking(enableStaticFields); setupApplication.setFlowSensitiveAliasing(flowSensitiveAliasing); return setupApplication.runInfoflow(); }
@Test(timeout=300000) @Ignore // TODO: SPARK issue, maybe context-insensitive CFG public void runTestVirtualDispatch3() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("GeneralJava/VirtualDispatch3.apk"); if (res != null) Assert.assertEquals(0, res.size()); }
protected void negativeCheckInfoflow(Infoflow infoflow){ if(infoflow.isResultAvailable()){ InfoflowResults map = infoflow.getResults(); for(String sink : sinkArray){ if(map.containsSinkMethod(sink)){ fail("sink is reached: " +sink); } } assertEquals(0, map.size()); }else{ fail("result is not available"); } }
@Test(timeout=300000) @Ignore // not yet supported public void runTestMerge1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("Aliasing/Merge1.apk"); if (res != null) Assert.assertEquals(0, res.size()); }
@Test(timeout=300000) @Ignore // Unregistering callbacks is not supported public void runTestUnregister1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("Callbacks/Unregister1.apk"); Assert.assertNotNull(res); Assert.assertEquals(0, res.size()); }
@Test(timeout=300000) @Ignore // Callback ordering is not supported public void runTestOrdering1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("Callbacks/Ordering1.apk"); Assert.assertNotNull(res); Assert.assertEquals(0, res.size()); }
public SMTPreparationPhase(IInfoflowCFG cfg, InfoflowResults results) { this.cfg = cfg; this.results = results; }
@Test(timeout=300000) public void runTestContentProvider1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("EmulatorDetection/ContentProvider1.apk"); Assert.assertEquals(2, res.size()); }
@Test(timeout=300000) public void runTestRegisterGlobal1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("Callbacks/RegisterGlobal1.apk"); Assert.assertNotNull(res); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) public void runTestPlayStore1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("EmulatorDetection/PlayStore1.apk"); Assert.assertEquals(2, res.size()); }
@Test(timeout=300000) public void runTestArrayAccess1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("ArraysAndLists/ArrayAccess1.apk"); Assert.assertEquals(0, res.size()); }
@Test(timeout=300000) public void runTestArrayAccess2() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("ArraysAndLists/ArrayAccess2.apk"); Assert.assertEquals(0, res.size()); }
@Test(timeout=300000) public void runTestArrayCopy1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("ArraysAndLists/ArrayCopy1.apk"); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) @Ignore // not supported yet public void runTestArrayToString1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("ArraysAndLists/ArrayToString1.apk"); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) public void runTestHashMapAccess1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("ArraysAndLists/HashMapAccess1.apk"); Assert.assertEquals(0, res.size()); }
@Test(timeout=300000) public void runTestListAccess1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("ArraysAndLists/ListAccess1.apk"); Assert.assertEquals(0, res.size()); }
@Test(timeout=300000) public void runTestRegisterGlobal2() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("Callbacks/RegisterGlobal2.apk"); Assert.assertNotNull(res); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) @Ignore // not supported yet, but should not be too hard to implement public void runTestApplicationModeling1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("AndroidSpecific/ApplicationModeling1.apk"); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) public void runTestDirectLeak1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("AndroidSpecific/DirectLeak1.apk"); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) public void runTestInactiveActivity() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("AndroidSpecific/InactiveActivity.apk"); if (res != null) Assert.assertEquals(0, res.size()); }
@Test(timeout=300000) public void runTestLibrary2() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("AndroidSpecific/Library2.apk"); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) public void runTestLogNoLeak() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("AndroidSpecific/LogNoLeak.apk"); if (res != null) Assert.assertEquals(0, res.size()); }
@Test(timeout=300000) public void runTestObfuscation1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("AndroidSpecific/Obfuscation1.apk"); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) public void runTestParcel1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("AndroidSpecific/Parcel1.apk"); Assert.assertEquals(1, res.size()); }
@Override public InfoflowResults getResults() { return results; }
@Override public InfoflowResults getResults() { return this.results; }
@Test(timeout=300000) @Ignore // not supported, would require taint tracking via files public void runTestPrivateDataLeak3() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("AndroidSpecific/PrivateDataLeak3.apk"); Assert.assertEquals(2, res.size()); }
@Test(timeout=300000) public void runPublicAPIField1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("AndroidSpecific/PublicAPIField1.apk"); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) public void runPublicAPIField2() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("AndroidSpecific/PublicAPIField2.apk"); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) public void runView1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("AndroidSpecific/View1.apk"); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) public void runTestClone1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("GeneralJava/Clone1.apk"); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) public void runTestLoop1() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("GeneralJava/Loop1.apk"); Assert.assertEquals(1, res.size()); }
@Test(timeout=300000) public void runTestLoop2() throws IOException, XmlPullParserException { InfoflowResults res = analyzeAPKFile("GeneralJava/Loop2.apk"); Assert.assertEquals(1, res.size()); }