From 577118d6a05d33dadb294319278e2c6d9fc17029 Mon Sep 17 00:00:00 2001 From: Tony Trummer Date: Wed, 16 Sep 2015 17:56:23 -0700 Subject: [PATCH] Improved Extra detection, refactoring of function names, minor bug fixes --- README.md | 0 exploitAPKs/qark/app/build.gradle | 91 +- exploitAPKs/qark/app/proguard-rules.pro | 0 .../java/com/secbro/qark/ApplicationTest.java | 0 .../qark/app/src/main/AndroidManifest.xml | 0 .../qark/app/src/main/ic_launcher-web.png | Bin .../qark/app/src/main/ic_launcher_2-web.png | Bin .../app/src/main/ic_launcher_droid-web.png | Bin .../BroadcastIntentSnifferActivity.java | 2 +- .../BroadcastIntentSnifferFragment.java | 4 +- .../services/BroadcastStealerService.java | 2 +- .../res/drawable-hdpi/drawer_shadow.9.png | Bin .../res/drawable-hdpi/ic_add_black_24dp.png | Bin .../src/main/res/drawable-hdpi/ic_drawer.png | Bin .../res/drawable-mdpi/drawer_shadow.9.png | Bin .../res/drawable-mdpi/ic_add_black_24dp.png | Bin .../src/main/res/drawable-mdpi/ic_drawer.png | Bin .../main/res/drawable-xhdpi/custom_intent.png | Bin .../res/drawable-xhdpi/drawer_shadow.9.png | Bin .../src/main/res/drawable-xhdpi/header2.png | Bin .../res/drawable-xhdpi/ic_add_black_24dp.png | Bin .../src/main/res/drawable-xhdpi/ic_drawer.png | Bin .../drawable-xhdpi/ic_folder_black_24dp.png | Bin .../drawable-xhdpi/ic_launch_black_24dp.png | Bin .../drawable-xhdpi/ic_mouse_black_24dp.png | Bin .../drawable-xhdpi/ic_public_black_24dp.png | Bin .../ic_visibility_black_24dp.png | Bin .../src/main/res/drawable-xhdpi/qark_512.png | Bin .../src/main/res/drawable-xhdpi/web_view.png | Bin .../res/drawable-xxhdpi/drawer_shadow.9.png | Bin .../src/main/res/drawable-xxhdpi/header3.png | Bin .../src/main/res/drawable-xxhdpi/header4.png | Bin .../res/drawable-xxhdpi/ic_add_black_24dp.png | Bin .../main/res/drawable-xxhdpi/ic_drawer.png | Bin .../drawable-xxhdpi/ic_launch_black_24dp.png | Bin .../drawable-xxhdpi/ic_mouse_black_24dp.png | Bin .../drawable-xxhdpi/ic_public_black_24dp.png | Bin .../ic_visibility_black_24dp.png | Bin .../main/res/drawable-xxhdpi/qark_drawer.png | Bin .../qark/app/src/main/res/drawable/ic_one.png | Bin .../res/drawable/mipmap-hdpi/ic_launcher.png | Bin .../drawable/mipmap-hdpi/ic_launcher_2.png | Bin .../res/drawable/mipmap-mdpi/ic_launcher.png | Bin .../drawable/mipmap-mdpi/ic_launcher_2.png | Bin .../res/drawable/mipmap-xhdpi/ic_launcher.png | Bin .../drawable/mipmap-xhdpi/ic_launcher_2.png | Bin .../drawable/mipmap-xxhdpi/ic_launcher.png | Bin .../drawable/mipmap-xxhdpi/ic_launcher_2.png | Bin .../drawable/mipmap-xxxhdpi/ic_launcher.png | Bin .../drawable/mipmap-xxxhdpi/ic_launcher_2.png | Bin .../activity_choose_intent_use_case.xml | 0 .../layout/activity_create_custom_intent.xml | 0 .../activity_exploit_exported_result.xml | 0 .../res/layout/activity_intent_sender.xml | 0 .../main/res/layout/activity_top_level.xml | 0 .../res/layout/activity_web_view_tests.xml | 0 .../res/layout/fragment_broadcast_stealer.xml | 0 ...gment_exploit_exported_activity_params.xml | 0 .../fragment_exported_activity_list.xml | 0 .../layout/fragment_exported_components.xml | 0 .../fragment_exported_receiver_list.xml | 0 .../main/res/layout/fragment_file_browser.xml | 0 .../res/layout/fragment_intent_sender.xml | 0 .../res/layout/fragment_navigation_drawer.xml | 0 .../layout/fragment_tap_jacking_exploit.xml | 0 .../main/res/layout/fragment_top_level.xml | 0 .../res/layout/fragment_web_view_tests.xml | 0 .../app/src/main/res/layout/nav_header.xml | 0 .../src/main/res/layout/tap_jacking_toast.xml | 0 .../qark/app/src/main/res/layout/toolbar.xml | 0 .../qark/app/src/main/res/layout/webview.xml | 0 .../app/src/main/res/menu/drawer_view.xml | 0 .../src/main/res/menu/menu_intent_sender.xml | 0 .../qark/app/src/main/res/menu/menu_main.xml | 0 .../src/main/res/menu/menu_web_view_tests.xml | 0 .../src/main/res/mipmap-xxxhdpi/qark_512.png | Bin .../app/src/main/res/values-w820dp/dimens.xml | 0 .../qark/app/src/main/res/values/colors.xml | 0 .../qark/app/src/main/res/values/dimens.xml | 0 .../app/src/main/res/values/extraKeys.xml | 0 .../qark/app/src/main/res/values/intentID.xml | 0 .../qark/app/src/main/res/values/strings.xml | 0 .../qark/app/src/main/res/values/styles.xml | 0 exploitAPKs/qark/build.gradle | 0 .../qark/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 exploitAPKs/qark/gradlew.bat | 0 exploitAPKs/qark/settings.gradle | 0 lib/BeautifulSoup.py | 0 lib/__init__.py | 0 lib/argparse.py | 0 lib/axmlparserpy/__init__.py | 0 lib/axmlparserpy/apk.py | 0 lib/axmlparserpy/axmlparser.py | 0 lib/axmlparserpy/axmlprinter.py | 0 lib/axmlparserpy/bytecode.py | 0 lib/axmlparserpy/stringblock.py | 0 lib/axmlparserpy/typeconstants.py | 0 lib/blessed/LICENSE | 0 lib/blessed/__init__.py | 0 lib/blessed/formatters.py | 0 lib/blessed/keyboard.py | 0 lib/blessed/sequences.py | 0 lib/blessed/terminal.py | 0 lib/blessed/tests/accessories.py | 0 lib/blessed/tests/test_core.py | 0 lib/blessed/tests/test_formatters.py | 0 lib/blessed/tests/test_keyboard.py | 0 lib/blessed/tests/test_length_sequence.py | 0 lib/blessed/tests/test_sequences.py | 0 lib/blessed/tests/test_wrap.py | 0 lib/blessings/LICENSE | 0 lib/blessings/__init__.py | 0 lib/blessings/tests.py | 0 lib/bs4/__init__.py | 0 lib/bs4/builder/__init__.py | 0 lib/bs4/builder/_html5lib.py | 0 lib/bs4/builder/_htmlparser.py | 0 lib/bs4/builder/_lxml.py | 0 lib/bs4/dammit.py | 0 lib/bs4/diagnose.py | 0 lib/bs4/element.py | 0 lib/bs4/testing.py | 0 lib/bs4/tests/__init__.py | 0 lib/bs4/tests/test_builder_registry.py | 0 lib/bs4/tests/test_docs.py | 0 lib/bs4/tests/test_html5lib.py | 0 lib/bs4/tests/test_htmlparser.py | 0 lib/bs4/tests/test_lxml.py | 0 lib/bs4/tests/test_soup.py | 0 lib/bs4/tests/test_tree.py | 0 lib/cfr_0_96.jar | Bin lib/colorama/LICENSE.txt | 0 lib/colorama/__init__.py | 0 lib/colorama/ansi.py | 0 lib/colorama/ansitowin32.py | 0 lib/colorama/initialise.py | 0 lib/colorama/win32.py | 0 lib/colorama/winterm.py | 0 lib/coloredlogs.py | 0 lib/dex2jar/lib/asm-all-3.3.1.jar | Bin lib/dex2jar/lib/commons-lite-1.15.jar | Bin lib/dex2jar/lib/dex-ir-1.12.jar | Bin lib/dex2jar/lib/dex-reader-1.15.jar | Bin lib/dex2jar/lib/dex-tools-0.0.9.15.jar | Bin lib/dex2jar/lib/dex-translator-0.0.9.15.jar | Bin lib/dex2jar/lib/jar-rename-1.6.jar | Bin lib/dex2jar/lib/jasmin-p2.5.jar | Bin lib/html5lib/__init__.py | 0 lib/html5lib/constants.py | 0 lib/html5lib/filters/__init__.py | 0 lib/html5lib/filters/_base.py | 0 .../filters/alphabeticalattributes.py | 0 lib/html5lib/filters/inject_meta_charset.py | 0 lib/html5lib/filters/lint.py | 0 lib/html5lib/filters/optionaltags.py | 0 lib/html5lib/filters/sanitizer.py | 0 lib/html5lib/filters/whitespace.py | 0 lib/html5lib/html5parser.py | 0 lib/html5lib/ihatexml.py | 0 lib/html5lib/inputstream.py | 0 lib/html5lib/sanitizer.py | 0 lib/html5lib/serializer/__init__.py | 0 lib/html5lib/serializer/htmlserializer.py | 0 lib/html5lib/tests/__init__.py | 0 lib/html5lib/tests/mockParser.py | 0 .../tests/performance/concatenation.py | 0 lib/html5lib/tests/support.py | 0 lib/html5lib/tests/test_encoding.py | 0 lib/html5lib/tests/test_parser.py | 0 lib/html5lib/tests/test_parser2.py | 0 lib/html5lib/tests/test_sanitizer.py | 0 lib/html5lib/tests/test_serializer.py | 0 lib/html5lib/tests/test_stream.py | 0 lib/html5lib/tests/test_tokenizer.py | 0 lib/html5lib/tests/test_treeadapters.py | 0 lib/html5lib/tests/test_treewalkers.py | 0 lib/html5lib/tests/test_whitespace_filter.py | 0 .../testdata/encoding/chardet/test_big5.txt | 0 .../tests/testdata/encoding/test-yahoo-jp.dat | 0 .../tests/testdata/encoding/tests1.dat | 0 .../tests/testdata/encoding/tests2.dat | 0 .../tests/testdata/sanitizer/tests1.dat | 0 .../tests/testdata/serializer/core.test | 0 .../tests/testdata/serializer/injectmeta.test | 0 .../testdata/serializer/optionaltags.test | 0 .../tests/testdata/serializer/options.test | 0 .../tests/testdata/serializer/whitespace.test | 0 .../tests/testdata/sniffer/htmlOrFeed.json | 0 .../testdata/tokenizer/contentModelFlags.test | 0 .../tests/testdata/tokenizer/domjs.test | 0 .../tests/testdata/tokenizer/entities.test | 0 .../tests/testdata/tokenizer/escapeFlag.test | 0 .../testdata/tokenizer/namedEntities.test | 0 .../testdata/tokenizer/numericEntities.test | 0 .../tokenizer/pendingSpecChanges.test | 0 .../tests/testdata/tokenizer/test1.test | 0 .../tests/testdata/tokenizer/test2.test | 0 .../tests/testdata/tokenizer/test3.test | 0 .../tests/testdata/tokenizer/test4.test | 0 .../testdata/tokenizer/unicodeChars.test | 0 .../tokenizer/unicodeCharsProblematic.test | 0 .../testdata/tokenizer/xmlViolation.test | 0 .../testdata/tree-construction/adoption01.dat | 0 .../testdata/tree-construction/adoption02.dat | 0 .../testdata/tree-construction/comments01.dat | 0 .../testdata/tree-construction/doctype01.dat | 0 .../tree-construction/domjs-unsafe.dat | Bin .../testdata/tree-construction/entities01.dat | 0 .../testdata/tree-construction/entities02.dat | 0 .../tree-construction/html5test-com.dat | 0 .../testdata/tree-construction/inbody01.dat | 0 .../testdata/tree-construction/isindex.dat | 0 .../tree-construction/main-element.dat | 0 ...pending-spec-changes-plain-text-unsafe.dat | Bin .../pending-spec-changes.dat | 0 .../tree-construction/plain-text-unsafe.dat | Bin .../tree-construction/scriptdata01.dat | 0 .../tree-construction/scripted/adoption01.dat | 0 .../tree-construction/scripted/ark.dat | 0 .../tree-construction/scripted/webkit01.dat | 0 .../testdata/tree-construction/tables01.dat | 0 .../testdata/tree-construction/template.dat | 0 .../testdata/tree-construction/tests1.dat | 0 .../testdata/tree-construction/tests10.dat | 0 .../testdata/tree-construction/tests11.dat | 0 .../testdata/tree-construction/tests12.dat | 0 .../testdata/tree-construction/tests14.dat | 0 .../testdata/tree-construction/tests15.dat | 0 .../testdata/tree-construction/tests16.dat | 0 .../testdata/tree-construction/tests17.dat | 0 .../testdata/tree-construction/tests18.dat | 0 .../testdata/tree-construction/tests19.dat | 0 .../testdata/tree-construction/tests2.dat | 0 .../testdata/tree-construction/tests20.dat | 0 .../testdata/tree-construction/tests21.dat | 0 .../testdata/tree-construction/tests22.dat | 0 .../testdata/tree-construction/tests23.dat | 0 .../testdata/tree-construction/tests24.dat | 0 .../testdata/tree-construction/tests25.dat | 0 .../testdata/tree-construction/tests26.dat | 0 .../testdata/tree-construction/tests3.dat | 0 .../testdata/tree-construction/tests4.dat | 0 .../testdata/tree-construction/tests5.dat | 0 .../testdata/tree-construction/tests6.dat | 0 .../testdata/tree-construction/tests7.dat | 0 .../testdata/tree-construction/tests8.dat | 0 .../testdata/tree-construction/tests9.dat | 0 .../tree-construction/tests_innerHTML_1.dat | 0 .../testdata/tree-construction/tricky01.dat | 0 .../testdata/tree-construction/webkit01.dat | 0 .../testdata/tree-construction/webkit02.dat | 0 lib/html5lib/tests/tokenizertotree.py | 0 lib/html5lib/tokenizer.py | 0 lib/html5lib/treeadapters/__init__.py | 0 lib/html5lib/treeadapters/sax.py | 0 lib/html5lib/treebuilders/__init__.py | 0 lib/html5lib/treebuilders/_base.py | 0 lib/html5lib/treebuilders/dom.py | 0 lib/html5lib/treebuilders/etree.py | 0 lib/html5lib/treebuilders/etree_lxml.py | 0 lib/html5lib/treewalkers/__init__.py | 0 lib/html5lib/treewalkers/_base.py | 0 lib/html5lib/treewalkers/dom.py | 0 lib/html5lib/treewalkers/etree.py | 0 lib/html5lib/treewalkers/genshistream.py | 0 lib/html5lib/treewalkers/lxmletree.py | 0 lib/html5lib/treewalkers/pulldom.py | 0 lib/html5lib/trie/__init__.py | 0 lib/html5lib/trie/_base.py | 0 lib/html5lib/trie/datrie.py | 0 lib/html5lib/trie/py.py | 0 lib/html5lib/utils.py | 0 lib/jd-core-java-1.2.jar | Bin lib/jquery/styles.css | 0 lib/plyj/LICENSE.TXT | 0 lib/plyj/__init__.py | 0 lib/plyj/model.py | 0 lib/plyj/parser.py | 0 lib/procyon/LICENSE.TXT | 0 lib/procyon/procyon-decompiler-0.5.28.jar | Bin lib/procyon/procyon-decompiler-0.5.29.jar | Bin lib/progressbar/LICENSE.txt | 0 lib/progressbar/__init__.py | 0 lib/progressbar/compat.py | 0 lib/progressbar/widgets.py | 0 lib/pubsub/LICENSE_BSD_Simple.txt | 0 lib/pubsub/README.txt | 0 lib/pubsub/RELEASE_NOTES.txt | 0 lib/pubsub/__init__.py | 0 lib/pubsub/core/__init__.py | 0 lib/pubsub/core/arg1/__init__.py | 0 lib/pubsub/core/arg1/listenerimpl.py | 0 lib/pubsub/core/arg1/publisher.py | 0 lib/pubsub/core/arg1/publishermixin.py | 0 lib/pubsub/core/arg1/topicargspecimpl.py | 0 lib/pubsub/core/arg1/topicmgrimpl.py | 0 lib/pubsub/core/callables.py | 0 lib/pubsub/core/imp2.py | 0 lib/pubsub/core/itopicdefnprovider.py | 0 lib/pubsub/core/kwargs/__init__.py | 0 lib/pubsub/core/kwargs/datamsg.py | 0 lib/pubsub/core/kwargs/listenerimpl.py | 0 lib/pubsub/core/kwargs/publisher.py | 0 lib/pubsub/core/kwargs/publishermixin.py | 0 lib/pubsub/core/kwargs/topicargspecimpl.py | 0 lib/pubsub/core/kwargs/topicmgrimpl.py | 0 lib/pubsub/core/listener.py | 0 lib/pubsub/core/listenerbase.py | 0 lib/pubsub/core/notificationmgr.py | 0 lib/pubsub/core/publisherbase.py | 0 lib/pubsub/core/topicargspec.py | 0 lib/pubsub/core/topicdefnprovider.py | 0 lib/pubsub/core/topicexc.py | 0 lib/pubsub/core/topicmgr.py | 0 lib/pubsub/core/topicobj.py | 0 lib/pubsub/core/topictreetraverser.py | 0 lib/pubsub/core/topicutils.py | 0 lib/pubsub/core/treeconfig.py | 0 lib/pubsub/core/validatedefnargs.py | 0 lib/pubsub/core/weakmethod.py | 0 lib/pubsub/policies.py | 0 lib/pubsub/pub.py | 0 lib/pubsub/py2and3.py | 0 lib/pubsub/setuparg1.py | 0 lib/pubsub/setupkwargs.py | 0 lib/pubsub/utils/__init__.py | 0 lib/pubsub/utils/exchandling.py | 0 lib/pubsub/utils/misc.py | 0 lib/pubsub/utils/notification.py | 0 lib/pubsub/utils/topictreeprinter.py | 0 lib/pubsub/utils/xmltopicdefnprovider.py | 0 lib/pyfiglet/README | 0 modules/DetermineMinSDK.py | 8 +- modules/GeneralIssues.py | 6 +- modules/__init__.py | 0 modules/adb.py | 297 +++++-- modules/certValidation.py | 60 +- modules/common.py | 55 +- modules/contentProvider.py | 2 +- modules/createSploit.py | 48 +- modules/cryptoFlaws.py | 22 +- modules/exportedPreferenceActivity.py | 14 +- modules/externalMethodDeclarations.py | 50 +- modules/findBoundServices.py | 8 +- modules/findBroadcasts.py | 20 +- modules/findMethods.py | 816 ++++++++++-------- modules/findPending.py | 40 +- modules/findTapJacking.py | 4 +- modules/localMethodDeclarations.py | 16 +- modules/sdkManager.py | 78 +- modules/unpackAPK.py | 10 +- modules/useCheckPermission.py | 4 +- modules/writeExploit.py | 40 +- poc/BURL_WARNING.html | 0 poc/FILE_SYS_WARN.html | 0 poc/JS_WARNING.html | 0 qark.py | 153 ++-- .../OWASP-GoatDroid-0.9/dbs/fourgoats/db.lck | Bin 38 -> 38 bytes .../dbs/fourgoats/seg0/c550.dat | Bin 8192 -> 8192 bytes .../dbs/herdfinancial/db.lck | Bin 38 -> 38 bytes .../dbs/herdfinancial/log/log.ctrl | Bin 0 -> 48 bytes .../dbs/herdfinancial/log/log1.dat | Bin 0 -> 1048576 bytes .../dbs/herdfinancial/log/logmirror.ctrl | Bin 0 -> 48 bytes sampleApps/goatdroid/goatdroid.apk | Bin template3/css/bootstrap_remote.min.css | 0 template3/css/fonts.css | 0 template3/css/styles_remote.css | 0 template3/fonts/lato1.woff2 | Bin template3/fonts/lato2.woff2 | Bin template3/fonts/lato3.woff2 | Bin template3/fonts/lato4.woff2 | Bin template3/fonts/lato5.woff2 | Bin template3/fonts/lato6.woff2 | Bin template3/fonts/oswald1.woff2 | Bin template3/fonts/oswald2.woff2 | Bin template3/fonts/oswald3.woff2 | Bin template3/fonts/oswald4.woff2 | Bin template3/fonts/oswald5.woff2 | Bin template3/fonts/oswald6.woff2 | Bin template3/fonts/oswald7.woff2 | Bin template3/fonts/oswald8.woff2 | Bin template3/js/highlight/CHANGES.md | 0 template3/js/highlight/LICENSE | 0 template3/js/highlight/README.md | 0 template3/js/highlight/README.ru.md | 0 template3/js/highlight/highlight.pack.js | 0 template3/js/highlight/styles/agate.css | 0 .../js/highlight/styles/androidstudio.css | 0 template3/js/highlight/styles/arta.css | 0 template3/js/highlight/styles/ascetic.css | 0 .../js/highlight/styles/atelier-cave.dark.css | 0 .../highlight/styles/atelier-cave.light.css | 0 .../js/highlight/styles/atelier-dune.dark.css | 0 .../highlight/styles/atelier-dune.light.css | 0 .../highlight/styles/atelier-estuary.dark.css | 0 .../styles/atelier-estuary.light.css | 0 .../highlight/styles/atelier-forest.dark.css | 0 .../highlight/styles/atelier-forest.light.css | 0 .../highlight/styles/atelier-heath.dark.css | 0 .../highlight/styles/atelier-heath.light.css | 0 .../styles/atelier-lakeside.dark.css | 0 .../styles/atelier-lakeside.light.css | 0 .../highlight/styles/atelier-plateau.dark.css | 0 .../styles/atelier-plateau.light.css | 0 .../highlight/styles/atelier-savanna.dark.css | 0 .../styles/atelier-savanna.light.css | 0 .../highlight/styles/atelier-seaside.dark.css | 0 .../styles/atelier-seaside.light.css | 0 .../styles/atelier-sulphurpool.dark.css | 0 .../styles/atelier-sulphurpool.light.css | 0 template3/js/highlight/styles/brown_paper.css | 0 .../js/highlight/styles/brown_papersq.png | Bin .../js/highlight/styles/codepen-embed.css | 0 .../js/highlight/styles/color-brewer.css | 0 template3/js/highlight/styles/dark.css | 0 template3/js/highlight/styles/darkula.css | 0 template3/js/highlight/styles/default.css | 0 template3/js/highlight/styles/docco.css | 0 template3/js/highlight/styles/far.css | 0 template3/js/highlight/styles/foundation.css | 0 template3/js/highlight/styles/github-gist.css | 0 template3/js/highlight/styles/github.css | 0 template3/js/highlight/styles/googlecode.css | 0 template3/js/highlight/styles/hybrid.css | 0 template3/js/highlight/styles/idea.css | 0 template3/js/highlight/styles/ir_black.css | 0 template3/js/highlight/styles/kimbie.dark.css | 0 .../js/highlight/styles/kimbie.light.css | 0 template3/js/highlight/styles/magula.css | 0 template3/js/highlight/styles/mono-blue.css | 0 template3/js/highlight/styles/monokai.css | 0 .../js/highlight/styles/monokai_sublime.css | 0 template3/js/highlight/styles/obsidian.css | 0 .../js/highlight/styles/paraiso.dark.css | 0 .../js/highlight/styles/paraiso.light.css | 0 template3/js/highlight/styles/pojoaque.css | 0 template3/js/highlight/styles/pojoaque.jpg | Bin template3/js/highlight/styles/railscasts.css | 0 template3/js/highlight/styles/rainbow.css | 0 template3/js/highlight/styles/school_book.css | 0 template3/js/highlight/styles/school_book.png | Bin .../js/highlight/styles/solarized_dark.css | 0 .../js/highlight/styles/solarized_light.css | 0 template3/js/highlight/styles/sunburst.css | 0 .../highlight/styles/tomorrow-night-blue.css | 0 .../styles/tomorrow-night-bright.css | 0 .../styles/tomorrow-night-eighties.css | 0 .../js/highlight/styles/tomorrow-night.css | 0 template3/js/highlight/styles/tomorrow.css | 0 template3/js/highlight/styles/vs.css | 0 template3/js/highlight/styles/xcode.css | 0 template3/js/highlight/styles/zenburn.css | 0 template3/js/html5.js | 0 template3/js/jquery-2.1.4.min.js | 0 455 files changed, 1127 insertions(+), 723 deletions(-) mode change 100755 => 100644 README.md mode change 100755 => 100644 exploitAPKs/qark/app/build.gradle mode change 100755 => 100644 exploitAPKs/qark/app/proguard-rules.pro mode change 100755 => 100644 exploitAPKs/qark/app/src/androidTest/java/com/secbro/qark/ApplicationTest.java mode change 100755 => 100644 exploitAPKs/qark/app/src/main/AndroidManifest.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/ic_launcher-web.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/ic_launcher_2-web.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/ic_launcher_droid-web.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-hdpi/drawer_shadow.9.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-hdpi/ic_add_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-hdpi/ic_drawer.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-mdpi/drawer_shadow.9.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-mdpi/ic_add_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-mdpi/ic_drawer.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xhdpi/custom_intent.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xhdpi/header2.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_add_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_drawer.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_folder_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_launch_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_mouse_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_public_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_visibility_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xhdpi/qark_512.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xhdpi/web_view.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/header3.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/header4.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_add_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_drawer.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_launch_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_mouse_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_public_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_visibility_black_24dp.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/qark_drawer.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable/ic_one.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable/mipmap-hdpi/ic_launcher.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable/mipmap-hdpi/ic_launcher_2.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable/mipmap-mdpi/ic_launcher.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable/mipmap-mdpi/ic_launcher_2.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable/mipmap-xhdpi/ic_launcher.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable/mipmap-xhdpi/ic_launcher_2.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable/mipmap-xxhdpi/ic_launcher.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable/mipmap-xxhdpi/ic_launcher_2.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable/mipmap-xxxhdpi/ic_launcher.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/drawable/mipmap-xxxhdpi/ic_launcher_2.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/activity_choose_intent_use_case.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/activity_create_custom_intent.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/activity_exploit_exported_result.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/activity_intent_sender.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/activity_top_level.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/activity_web_view_tests.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/fragment_broadcast_stealer.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/fragment_exploit_exported_activity_params.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/fragment_exported_activity_list.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/fragment_exported_components.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/fragment_exported_receiver_list.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/fragment_file_browser.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/fragment_intent_sender.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/fragment_navigation_drawer.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/fragment_tap_jacking_exploit.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/fragment_top_level.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/fragment_web_view_tests.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/nav_header.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/tap_jacking_toast.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/toolbar.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/layout/webview.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/menu/drawer_view.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/menu/menu_intent_sender.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/menu/menu_main.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/menu/menu_web_view_tests.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/mipmap-xxxhdpi/qark_512.png mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/values-w820dp/dimens.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/values/colors.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/values/dimens.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/values/extraKeys.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/values/intentID.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/values/strings.xml mode change 100755 => 100644 exploitAPKs/qark/app/src/main/res/values/styles.xml mode change 100755 => 100644 exploitAPKs/qark/build.gradle mode change 100755 => 100644 exploitAPKs/qark/gradle/wrapper/gradle-wrapper.jar mode change 100755 => 100644 exploitAPKs/qark/gradle/wrapper/gradle-wrapper.properties mode change 100755 => 100644 exploitAPKs/qark/gradlew.bat mode change 100755 => 100644 exploitAPKs/qark/settings.gradle mode change 100755 => 100644 lib/BeautifulSoup.py mode change 100755 => 100644 lib/__init__.py mode change 100755 => 100644 lib/argparse.py mode change 100755 => 100644 lib/axmlparserpy/__init__.py mode change 100755 => 100644 lib/axmlparserpy/apk.py mode change 100755 => 100644 lib/axmlparserpy/axmlparser.py mode change 100755 => 100644 lib/axmlparserpy/axmlprinter.py mode change 100755 => 100644 lib/axmlparserpy/bytecode.py mode change 100755 => 100644 lib/axmlparserpy/stringblock.py mode change 100755 => 100644 lib/axmlparserpy/typeconstants.py mode change 100755 => 100644 lib/blessed/LICENSE mode change 100755 => 100644 lib/blessed/__init__.py mode change 100755 => 100644 lib/blessed/formatters.py mode change 100755 => 100644 lib/blessed/keyboard.py mode change 100755 => 100644 lib/blessed/sequences.py mode change 100755 => 100644 lib/blessed/terminal.py mode change 100755 => 100644 lib/blessed/tests/accessories.py mode change 100755 => 100644 lib/blessed/tests/test_core.py mode change 100755 => 100644 lib/blessed/tests/test_formatters.py mode change 100755 => 100644 lib/blessed/tests/test_keyboard.py mode change 100755 => 100644 lib/blessed/tests/test_length_sequence.py mode change 100755 => 100644 lib/blessed/tests/test_sequences.py mode change 100755 => 100644 lib/blessed/tests/test_wrap.py mode change 100755 => 100644 lib/blessings/LICENSE mode change 100755 => 100644 lib/blessings/__init__.py mode change 100755 => 100644 lib/blessings/tests.py mode change 100755 => 100644 lib/bs4/__init__.py mode change 100755 => 100644 lib/bs4/builder/__init__.py mode change 100755 => 100644 lib/bs4/builder/_html5lib.py mode change 100755 => 100644 lib/bs4/builder/_htmlparser.py mode change 100755 => 100644 lib/bs4/builder/_lxml.py mode change 100755 => 100644 lib/bs4/dammit.py mode change 100755 => 100644 lib/bs4/diagnose.py mode change 100755 => 100644 lib/bs4/element.py mode change 100755 => 100644 lib/bs4/testing.py mode change 100755 => 100644 lib/bs4/tests/__init__.py mode change 100755 => 100644 lib/bs4/tests/test_builder_registry.py mode change 100755 => 100644 lib/bs4/tests/test_docs.py mode change 100755 => 100644 lib/bs4/tests/test_html5lib.py mode change 100755 => 100644 lib/bs4/tests/test_htmlparser.py mode change 100755 => 100644 lib/bs4/tests/test_lxml.py mode change 100755 => 100644 lib/bs4/tests/test_soup.py mode change 100755 => 100644 lib/bs4/tests/test_tree.py mode change 100755 => 100644 lib/cfr_0_96.jar mode change 100755 => 100644 lib/colorama/LICENSE.txt mode change 100755 => 100644 lib/colorama/__init__.py mode change 100755 => 100644 lib/colorama/ansi.py mode change 100755 => 100644 lib/colorama/ansitowin32.py mode change 100755 => 100644 lib/colorama/initialise.py mode change 100755 => 100644 lib/colorama/win32.py mode change 100755 => 100644 lib/colorama/winterm.py mode change 100755 => 100644 lib/coloredlogs.py mode change 100755 => 100644 lib/dex2jar/lib/asm-all-3.3.1.jar mode change 100755 => 100644 lib/dex2jar/lib/commons-lite-1.15.jar mode change 100755 => 100644 lib/dex2jar/lib/dex-ir-1.12.jar mode change 100755 => 100644 lib/dex2jar/lib/dex-reader-1.15.jar mode change 100755 => 100644 lib/dex2jar/lib/dex-tools-0.0.9.15.jar mode change 100755 => 100644 lib/dex2jar/lib/dex-translator-0.0.9.15.jar mode change 100755 => 100644 lib/dex2jar/lib/jar-rename-1.6.jar mode change 100755 => 100644 lib/dex2jar/lib/jasmin-p2.5.jar mode change 100755 => 100644 lib/html5lib/__init__.py mode change 100755 => 100644 lib/html5lib/constants.py mode change 100755 => 100644 lib/html5lib/filters/__init__.py mode change 100755 => 100644 lib/html5lib/filters/_base.py mode change 100755 => 100644 lib/html5lib/filters/alphabeticalattributes.py mode change 100755 => 100644 lib/html5lib/filters/inject_meta_charset.py mode change 100755 => 100644 lib/html5lib/filters/lint.py mode change 100755 => 100644 lib/html5lib/filters/optionaltags.py mode change 100755 => 100644 lib/html5lib/filters/sanitizer.py mode change 100755 => 100644 lib/html5lib/filters/whitespace.py mode change 100755 => 100644 lib/html5lib/html5parser.py mode change 100755 => 100644 lib/html5lib/ihatexml.py mode change 100755 => 100644 lib/html5lib/inputstream.py mode change 100755 => 100644 lib/html5lib/sanitizer.py mode change 100755 => 100644 lib/html5lib/serializer/__init__.py mode change 100755 => 100644 lib/html5lib/serializer/htmlserializer.py mode change 100755 => 100644 lib/html5lib/tests/__init__.py mode change 100755 => 100644 lib/html5lib/tests/mockParser.py mode change 100755 => 100644 lib/html5lib/tests/performance/concatenation.py mode change 100755 => 100644 lib/html5lib/tests/support.py mode change 100755 => 100644 lib/html5lib/tests/test_encoding.py mode change 100755 => 100644 lib/html5lib/tests/test_parser.py mode change 100755 => 100644 lib/html5lib/tests/test_parser2.py mode change 100755 => 100644 lib/html5lib/tests/test_sanitizer.py mode change 100755 => 100644 lib/html5lib/tests/test_serializer.py mode change 100755 => 100644 lib/html5lib/tests/test_stream.py mode change 100755 => 100644 lib/html5lib/tests/test_tokenizer.py mode change 100755 => 100644 lib/html5lib/tests/test_treeadapters.py mode change 100755 => 100644 lib/html5lib/tests/test_treewalkers.py mode change 100755 => 100644 lib/html5lib/tests/test_whitespace_filter.py mode change 100755 => 100644 lib/html5lib/tests/testdata/encoding/chardet/test_big5.txt mode change 100755 => 100644 lib/html5lib/tests/testdata/encoding/test-yahoo-jp.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/encoding/tests1.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/encoding/tests2.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/sanitizer/tests1.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/serializer/core.test mode change 100755 => 100644 lib/html5lib/tests/testdata/serializer/injectmeta.test mode change 100755 => 100644 lib/html5lib/tests/testdata/serializer/optionaltags.test mode change 100755 => 100644 lib/html5lib/tests/testdata/serializer/options.test mode change 100755 => 100644 lib/html5lib/tests/testdata/serializer/whitespace.test mode change 100755 => 100644 lib/html5lib/tests/testdata/sniffer/htmlOrFeed.json mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/contentModelFlags.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/domjs.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/entities.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/escapeFlag.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/namedEntities.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/numericEntities.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/pendingSpecChanges.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/test1.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/test2.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/test3.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/test4.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/unicodeChars.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/unicodeCharsProblematic.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tokenizer/xmlViolation.test mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/adoption01.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/adoption02.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/comments01.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/doctype01.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/domjs-unsafe.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/entities01.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/entities02.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/html5test-com.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/inbody01.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/isindex.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/main-element.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/pending-spec-changes-plain-text-unsafe.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/pending-spec-changes.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/plain-text-unsafe.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/scriptdata01.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/scripted/adoption01.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/scripted/ark.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/scripted/webkit01.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tables01.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/template.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests1.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests10.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests11.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests12.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests14.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests15.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests16.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests17.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests18.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests19.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests2.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests20.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests21.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests22.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests23.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests24.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests25.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests26.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests3.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests4.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests5.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests6.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests7.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests8.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests9.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tests_innerHTML_1.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/tricky01.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/webkit01.dat mode change 100755 => 100644 lib/html5lib/tests/testdata/tree-construction/webkit02.dat mode change 100755 => 100644 lib/html5lib/tests/tokenizertotree.py mode change 100755 => 100644 lib/html5lib/tokenizer.py mode change 100755 => 100644 lib/html5lib/treeadapters/__init__.py mode change 100755 => 100644 lib/html5lib/treeadapters/sax.py mode change 100755 => 100644 lib/html5lib/treebuilders/__init__.py mode change 100755 => 100644 lib/html5lib/treebuilders/_base.py mode change 100755 => 100644 lib/html5lib/treebuilders/dom.py mode change 100755 => 100644 lib/html5lib/treebuilders/etree.py mode change 100755 => 100644 lib/html5lib/treebuilders/etree_lxml.py mode change 100755 => 100644 lib/html5lib/treewalkers/__init__.py mode change 100755 => 100644 lib/html5lib/treewalkers/_base.py mode change 100755 => 100644 lib/html5lib/treewalkers/dom.py mode change 100755 => 100644 lib/html5lib/treewalkers/etree.py mode change 100755 => 100644 lib/html5lib/treewalkers/genshistream.py mode change 100755 => 100644 lib/html5lib/treewalkers/lxmletree.py mode change 100755 => 100644 lib/html5lib/treewalkers/pulldom.py mode change 100755 => 100644 lib/html5lib/trie/__init__.py mode change 100755 => 100644 lib/html5lib/trie/_base.py mode change 100755 => 100644 lib/html5lib/trie/datrie.py mode change 100755 => 100644 lib/html5lib/trie/py.py mode change 100755 => 100644 lib/html5lib/utils.py mode change 100755 => 100644 lib/jd-core-java-1.2.jar mode change 100755 => 100644 lib/jquery/styles.css mode change 100755 => 100644 lib/plyj/LICENSE.TXT mode change 100755 => 100644 lib/plyj/__init__.py mode change 100755 => 100644 lib/plyj/model.py mode change 100755 => 100644 lib/plyj/parser.py mode change 100755 => 100644 lib/procyon/LICENSE.TXT mode change 100755 => 100644 lib/procyon/procyon-decompiler-0.5.28.jar mode change 100755 => 100644 lib/procyon/procyon-decompiler-0.5.29.jar mode change 100755 => 100644 lib/progressbar/LICENSE.txt mode change 100755 => 100644 lib/progressbar/__init__.py mode change 100755 => 100644 lib/progressbar/compat.py mode change 100755 => 100644 lib/progressbar/widgets.py mode change 100755 => 100644 lib/pubsub/LICENSE_BSD_Simple.txt mode change 100755 => 100644 lib/pubsub/README.txt mode change 100755 => 100644 lib/pubsub/RELEASE_NOTES.txt mode change 100755 => 100644 lib/pubsub/__init__.py mode change 100755 => 100644 lib/pubsub/core/__init__.py mode change 100755 => 100644 lib/pubsub/core/arg1/__init__.py mode change 100755 => 100644 lib/pubsub/core/arg1/listenerimpl.py mode change 100755 => 100644 lib/pubsub/core/arg1/publisher.py mode change 100755 => 100644 lib/pubsub/core/arg1/publishermixin.py mode change 100755 => 100644 lib/pubsub/core/arg1/topicargspecimpl.py mode change 100755 => 100644 lib/pubsub/core/arg1/topicmgrimpl.py mode change 100755 => 100644 lib/pubsub/core/callables.py mode change 100755 => 100644 lib/pubsub/core/imp2.py mode change 100755 => 100644 lib/pubsub/core/itopicdefnprovider.py mode change 100755 => 100644 lib/pubsub/core/kwargs/__init__.py mode change 100755 => 100644 lib/pubsub/core/kwargs/datamsg.py mode change 100755 => 100644 lib/pubsub/core/kwargs/listenerimpl.py mode change 100755 => 100644 lib/pubsub/core/kwargs/publisher.py mode change 100755 => 100644 lib/pubsub/core/kwargs/publishermixin.py mode change 100755 => 100644 lib/pubsub/core/kwargs/topicargspecimpl.py mode change 100755 => 100644 lib/pubsub/core/kwargs/topicmgrimpl.py mode change 100755 => 100644 lib/pubsub/core/listener.py mode change 100755 => 100644 lib/pubsub/core/listenerbase.py mode change 100755 => 100644 lib/pubsub/core/notificationmgr.py mode change 100755 => 100644 lib/pubsub/core/publisherbase.py mode change 100755 => 100644 lib/pubsub/core/topicargspec.py mode change 100755 => 100644 lib/pubsub/core/topicdefnprovider.py mode change 100755 => 100644 lib/pubsub/core/topicexc.py mode change 100755 => 100644 lib/pubsub/core/topicmgr.py mode change 100755 => 100644 lib/pubsub/core/topicobj.py mode change 100755 => 100644 lib/pubsub/core/topictreetraverser.py mode change 100755 => 100644 lib/pubsub/core/topicutils.py mode change 100755 => 100644 lib/pubsub/core/treeconfig.py mode change 100755 => 100644 lib/pubsub/core/validatedefnargs.py mode change 100755 => 100644 lib/pubsub/core/weakmethod.py mode change 100755 => 100644 lib/pubsub/policies.py mode change 100755 => 100644 lib/pubsub/pub.py mode change 100755 => 100644 lib/pubsub/py2and3.py mode change 100755 => 100644 lib/pubsub/setuparg1.py mode change 100755 => 100644 lib/pubsub/setupkwargs.py mode change 100755 => 100644 lib/pubsub/utils/__init__.py mode change 100755 => 100644 lib/pubsub/utils/exchandling.py mode change 100755 => 100644 lib/pubsub/utils/misc.py mode change 100755 => 100644 lib/pubsub/utils/notification.py mode change 100755 => 100644 lib/pubsub/utils/topictreeprinter.py mode change 100755 => 100644 lib/pubsub/utils/xmltopicdefnprovider.py mode change 100755 => 100644 lib/pyfiglet/README mode change 100755 => 100644 modules/__init__.py mode change 100755 => 100644 poc/BURL_WARNING.html mode change 100755 => 100644 poc/FILE_SYS_WARN.html mode change 100755 => 100644 poc/JS_WARNING.html create mode 100644 sampleApps/goatdroid/OWASP-GoatDroid-0.9/dbs/herdfinancial/log/log.ctrl create mode 100644 sampleApps/goatdroid/OWASP-GoatDroid-0.9/dbs/herdfinancial/log/log1.dat create mode 100644 sampleApps/goatdroid/OWASP-GoatDroid-0.9/dbs/herdfinancial/log/logmirror.ctrl mode change 100755 => 100644 sampleApps/goatdroid/goatdroid.apk mode change 100755 => 100644 template3/css/bootstrap_remote.min.css mode change 100755 => 100644 template3/css/fonts.css mode change 100755 => 100644 template3/css/styles_remote.css mode change 100755 => 100644 template3/fonts/lato1.woff2 mode change 100755 => 100644 template3/fonts/lato2.woff2 mode change 100755 => 100644 template3/fonts/lato3.woff2 mode change 100755 => 100644 template3/fonts/lato4.woff2 mode change 100755 => 100644 template3/fonts/lato5.woff2 mode change 100755 => 100644 template3/fonts/lato6.woff2 mode change 100755 => 100644 template3/fonts/oswald1.woff2 mode change 100755 => 100644 template3/fonts/oswald2.woff2 mode change 100755 => 100644 template3/fonts/oswald3.woff2 mode change 100755 => 100644 template3/fonts/oswald4.woff2 mode change 100755 => 100644 template3/fonts/oswald5.woff2 mode change 100755 => 100644 template3/fonts/oswald6.woff2 mode change 100755 => 100644 template3/fonts/oswald7.woff2 mode change 100755 => 100644 template3/fonts/oswald8.woff2 mode change 100755 => 100644 template3/js/highlight/CHANGES.md mode change 100755 => 100644 template3/js/highlight/LICENSE mode change 100755 => 100644 template3/js/highlight/README.md mode change 100755 => 100644 template3/js/highlight/README.ru.md mode change 100755 => 100644 template3/js/highlight/highlight.pack.js mode change 100755 => 100644 template3/js/highlight/styles/agate.css mode change 100755 => 100644 template3/js/highlight/styles/androidstudio.css mode change 100755 => 100644 template3/js/highlight/styles/arta.css mode change 100755 => 100644 template3/js/highlight/styles/ascetic.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-cave.dark.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-cave.light.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-dune.dark.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-dune.light.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-estuary.dark.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-estuary.light.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-forest.dark.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-forest.light.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-heath.dark.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-heath.light.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-lakeside.dark.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-lakeside.light.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-plateau.dark.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-plateau.light.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-savanna.dark.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-savanna.light.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-seaside.dark.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-seaside.light.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-sulphurpool.dark.css mode change 100755 => 100644 template3/js/highlight/styles/atelier-sulphurpool.light.css mode change 100755 => 100644 template3/js/highlight/styles/brown_paper.css mode change 100755 => 100644 template3/js/highlight/styles/brown_papersq.png mode change 100755 => 100644 template3/js/highlight/styles/codepen-embed.css mode change 100755 => 100644 template3/js/highlight/styles/color-brewer.css mode change 100755 => 100644 template3/js/highlight/styles/dark.css mode change 100755 => 100644 template3/js/highlight/styles/darkula.css mode change 100755 => 100644 template3/js/highlight/styles/default.css mode change 100755 => 100644 template3/js/highlight/styles/docco.css mode change 100755 => 100644 template3/js/highlight/styles/far.css mode change 100755 => 100644 template3/js/highlight/styles/foundation.css mode change 100755 => 100644 template3/js/highlight/styles/github-gist.css mode change 100755 => 100644 template3/js/highlight/styles/github.css mode change 100755 => 100644 template3/js/highlight/styles/googlecode.css mode change 100755 => 100644 template3/js/highlight/styles/hybrid.css mode change 100755 => 100644 template3/js/highlight/styles/idea.css mode change 100755 => 100644 template3/js/highlight/styles/ir_black.css mode change 100755 => 100644 template3/js/highlight/styles/kimbie.dark.css mode change 100755 => 100644 template3/js/highlight/styles/kimbie.light.css mode change 100755 => 100644 template3/js/highlight/styles/magula.css mode change 100755 => 100644 template3/js/highlight/styles/mono-blue.css mode change 100755 => 100644 template3/js/highlight/styles/monokai.css mode change 100755 => 100644 template3/js/highlight/styles/monokai_sublime.css mode change 100755 => 100644 template3/js/highlight/styles/obsidian.css mode change 100755 => 100644 template3/js/highlight/styles/paraiso.dark.css mode change 100755 => 100644 template3/js/highlight/styles/paraiso.light.css mode change 100755 => 100644 template3/js/highlight/styles/pojoaque.css mode change 100755 => 100644 template3/js/highlight/styles/pojoaque.jpg mode change 100755 => 100644 template3/js/highlight/styles/railscasts.css mode change 100755 => 100644 template3/js/highlight/styles/rainbow.css mode change 100755 => 100644 template3/js/highlight/styles/school_book.css mode change 100755 => 100644 template3/js/highlight/styles/school_book.png mode change 100755 => 100644 template3/js/highlight/styles/solarized_dark.css mode change 100755 => 100644 template3/js/highlight/styles/solarized_light.css mode change 100755 => 100644 template3/js/highlight/styles/sunburst.css mode change 100755 => 100644 template3/js/highlight/styles/tomorrow-night-blue.css mode change 100755 => 100644 template3/js/highlight/styles/tomorrow-night-bright.css mode change 100755 => 100644 template3/js/highlight/styles/tomorrow-night-eighties.css mode change 100755 => 100644 template3/js/highlight/styles/tomorrow-night.css mode change 100755 => 100644 template3/js/highlight/styles/tomorrow.css mode change 100755 => 100644 template3/js/highlight/styles/vs.css mode change 100755 => 100644 template3/js/highlight/styles/xcode.css mode change 100755 => 100644 template3/js/highlight/styles/zenburn.css mode change 100755 => 100644 template3/js/html5.js mode change 100755 => 100644 template3/js/jquery-2.1.4.min.js diff --git a/README.md b/README.md old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/build.gradle b/exploitAPKs/qark/app/build.gradle old mode 100755 new mode 100644 index 208cd049..a5b3d48a --- a/exploitAPKs/qark/app/build.gradle +++ b/exploitAPKs/qark/app/build.gradle @@ -1,8 +1,95 @@ apply plugin: 'com.android.application' +import org.codehaus.groovy.runtime.StackTraceUtils + +int[] sdksAvailable() { + + def sdks = new ByteArrayOutputStream() + exec { + commandLine androidSDKDir()+'tools/android', 'list' + standardOutput = sdks + } + sdks = sdks + // get the output + .toString() + // split to strings + .split('\n') + // leave only strings with API levels + .findAll { it ==~ /\s*API level:.*/ } + // extract the API levels + .collect { (it =~ /\s*API level:\s*(\d+).*/)[0][1].toInteger() } + // sort from highest to lowest + .sort( { a, b -> b <=> a } ) + sdks +} + +int highestSdkAvailable(int defaultSdk) { + try { + def sdks = sdksAvailable() + def highestSdk = sdks[0] + if (highestSdk != null) { + println "Using highest found SDK " + highestSdk + highestSdk + } else { + println "No installed SDKs found. Using default SDK " + defaultSdk + defaultSdk + } + } catch (any) { + println "Exception while determining highest SDK. Using default SDK " + + defaultSdk + StackTraceUtils.sanitize(any).printStackTrace() + defaultSdk + } +} + +String androidSDKDir() { + def androidExecPath = new ByteArrayOutputStream() + exec { + commandLine 'pwd' + standardOutput = androidExecPath + } + + def path = androidExecPath.toString().substring(0, androidExecPath.toString().lastIndexOf('/build/qark/app')) + println path + "/settings.properties" + + Properties properties = new Properties() + File propertiesFile = new File(path + '/settings.properties') + propertiesFile.withInputStream { + properties.load(it) + } + println properties.AndroidSDKPath + + return properties.AndroidSDKPath +} + +String[] buildToolsAvailable() { + def buildToolsDir = new File(androidSDKDir(), "build-tools") + buildToolsDir.list().sort { a, b -> b <=> a } +} + +String latestBuildToolsAvailable(String defaultBuildTools) { + try { + def buildToolsVersions = buildToolsAvailable() + def latestBuildTools = buildToolsVersions[0] + if (latestBuildTools != null) { + println "Using latest found build tools " + latestBuildTools + latestBuildTools + } else { + println "No installed build tools found. Using default build tools " + + defaultBuildTools + defaultBuildTools + } + } catch (any) { + println "Exception while determining latest build tools. Using default build tools " + + defaultBuildTools + StackTraceUtils.sanitize(any).printStackTrace() + defaultBuildTools + } +} + android { - compileSdkVersion 21 - buildToolsVersion "21.1.2" + compileSdkVersion highestSdkAvailable(21) + buildToolsVersion latestBuildToolsAvailable("21.1.2") defaultConfig { applicationId 'com.secbro.qark' minSdkVersion 7 diff --git a/exploitAPKs/qark/app/proguard-rules.pro b/exploitAPKs/qark/app/proguard-rules.pro old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/androidTest/java/com/secbro/qark/ApplicationTest.java b/exploitAPKs/qark/app/src/androidTest/java/com/secbro/qark/ApplicationTest.java old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/AndroidManifest.xml b/exploitAPKs/qark/app/src/main/AndroidManifest.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/ic_launcher-web.png b/exploitAPKs/qark/app/src/main/ic_launcher-web.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/ic_launcher_2-web.png b/exploitAPKs/qark/app/src/main/ic_launcher_2-web.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/ic_launcher_droid-web.png b/exploitAPKs/qark/app/src/main/ic_launcher_droid-web.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/java/com/secbro/qark/intentsniffer/BroadcastIntentSnifferActivity.java b/exploitAPKs/qark/app/src/main/java/com/secbro/qark/intentsniffer/BroadcastIntentSnifferActivity.java index cdbb9485..d22b41ce 100644 --- a/exploitAPKs/qark/app/src/main/java/com/secbro/qark/intentsniffer/BroadcastIntentSnifferActivity.java +++ b/exploitAPKs/qark/app/src/main/java/com/secbro/qark/intentsniffer/BroadcastIntentSnifferActivity.java @@ -28,7 +28,7 @@ protected void onCreate(Bundle savedInstanceState) { SharedPreferences prefs = this.getSharedPreferences( getPackageName(), Context.MODE_PRIVATE); TextView textview = (TextView) findViewById(R.id.activity_broadcast_stealer_text_view); - textview.setText(prefs.getString("foo", "default" )); + textview.setText(prefs.getString("foo", "Listening..." )); Intent msgIntent = new Intent(this, BroadcastStealerService.class); msgIntent.setAction("Start"); startService(msgIntent); diff --git a/exploitAPKs/qark/app/src/main/java/com/secbro/qark/intentsniffer/BroadcastIntentSnifferFragment.java b/exploitAPKs/qark/app/src/main/java/com/secbro/qark/intentsniffer/BroadcastIntentSnifferFragment.java index 6fed883f..9ef42853 100644 --- a/exploitAPKs/qark/app/src/main/java/com/secbro/qark/intentsniffer/BroadcastIntentSnifferFragment.java +++ b/exploitAPKs/qark/app/src/main/java/com/secbro/qark/intentsniffer/BroadcastIntentSnifferFragment.java @@ -39,7 +39,7 @@ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, getActivity().getPackageName(), Context.MODE_PRIVATE); TextView textview = (TextView) retVal.findViewById(R.id.activity_broadcast_stealer_text_view); - textview.setText(prefs.getString("foo", "default" )); + textview.setText(prefs.getString("foo", "Listening..." )); Intent msgIntent = new Intent(this.getActivity(), BroadcastStealerService.class); msgIntent.setAction("Start"); this.getActivity().startService(msgIntent); @@ -53,7 +53,7 @@ public void onResume() { getActivity().getPackageName(), Context.MODE_PRIVATE); TextView textview = (TextView) this.getActivity().findViewById(R.id.activity_broadcast_stealer_text_view); - textview.setText(prefs.getString("foo", "default" )); + textview.setText(prefs.getString("foo", "Listening..." )); super.onResume(); } diff --git a/exploitAPKs/qark/app/src/main/java/com/secbro/qark/intentsniffer/services/BroadcastStealerService.java b/exploitAPKs/qark/app/src/main/java/com/secbro/qark/intentsniffer/services/BroadcastStealerService.java index 68c4d1cb..3dc94256 100644 --- a/exploitAPKs/qark/app/src/main/java/com/secbro/qark/intentsniffer/services/BroadcastStealerService.java +++ b/exploitAPKs/qark/app/src/main/java/com/secbro/qark/intentsniffer/services/BroadcastStealerService.java @@ -47,7 +47,7 @@ public void onReceive(Context context, Intent intent) { Object value = bundle.get(key); SharedPreferences prefs = getSharedPreferences( getPackageName(), Context.MODE_PRIVATE); - prefs.edit().putString("foo", prefs.getString("foo", "default") + "\n " + "KEY: " + key + "VALUE: " + value.toString()).apply(); + prefs.edit().putString("foo", prefs.getString("foo", "Listening...") + "\n " + "KEY: " + key + "VALUE: " + value.toString()).apply(); } Log.i("BroadcastStealerService", "intent received"); } diff --git a/exploitAPKs/qark/app/src/main/res/drawable-hdpi/drawer_shadow.9.png b/exploitAPKs/qark/app/src/main/res/drawable-hdpi/drawer_shadow.9.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-hdpi/ic_add_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-hdpi/ic_add_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-hdpi/ic_drawer.png b/exploitAPKs/qark/app/src/main/res/drawable-hdpi/ic_drawer.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-mdpi/drawer_shadow.9.png b/exploitAPKs/qark/app/src/main/res/drawable-mdpi/drawer_shadow.9.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-mdpi/ic_add_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-mdpi/ic_add_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-mdpi/ic_drawer.png b/exploitAPKs/qark/app/src/main/res/drawable-mdpi/ic_drawer.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/custom_intent.png b/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/custom_intent.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png b/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/header2.png b/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/header2.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_add_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_add_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_drawer.png b/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_drawer.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_folder_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_folder_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_launch_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_launch_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_mouse_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_mouse_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_public_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_public_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_visibility_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/ic_visibility_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/qark_512.png b/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/qark_512.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/web_view.png b/exploitAPKs/qark/app/src/main/res/drawable-xhdpi/web_view.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png b/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/header3.png b/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/header3.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/header4.png b/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/header4.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_add_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_add_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_drawer.png b/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_drawer.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_launch_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_launch_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_mouse_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_mouse_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_public_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_public_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_visibility_black_24dp.png b/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/ic_visibility_black_24dp.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/qark_drawer.png b/exploitAPKs/qark/app/src/main/res/drawable-xxhdpi/qark_drawer.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable/ic_one.png b/exploitAPKs/qark/app/src/main/res/drawable/ic_one.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable/mipmap-hdpi/ic_launcher.png b/exploitAPKs/qark/app/src/main/res/drawable/mipmap-hdpi/ic_launcher.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable/mipmap-hdpi/ic_launcher_2.png b/exploitAPKs/qark/app/src/main/res/drawable/mipmap-hdpi/ic_launcher_2.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable/mipmap-mdpi/ic_launcher.png b/exploitAPKs/qark/app/src/main/res/drawable/mipmap-mdpi/ic_launcher.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable/mipmap-mdpi/ic_launcher_2.png b/exploitAPKs/qark/app/src/main/res/drawable/mipmap-mdpi/ic_launcher_2.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable/mipmap-xhdpi/ic_launcher.png b/exploitAPKs/qark/app/src/main/res/drawable/mipmap-xhdpi/ic_launcher.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable/mipmap-xhdpi/ic_launcher_2.png b/exploitAPKs/qark/app/src/main/res/drawable/mipmap-xhdpi/ic_launcher_2.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable/mipmap-xxhdpi/ic_launcher.png b/exploitAPKs/qark/app/src/main/res/drawable/mipmap-xxhdpi/ic_launcher.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable/mipmap-xxhdpi/ic_launcher_2.png b/exploitAPKs/qark/app/src/main/res/drawable/mipmap-xxhdpi/ic_launcher_2.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable/mipmap-xxxhdpi/ic_launcher.png b/exploitAPKs/qark/app/src/main/res/drawable/mipmap-xxxhdpi/ic_launcher.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/drawable/mipmap-xxxhdpi/ic_launcher_2.png b/exploitAPKs/qark/app/src/main/res/drawable/mipmap-xxxhdpi/ic_launcher_2.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/activity_choose_intent_use_case.xml b/exploitAPKs/qark/app/src/main/res/layout/activity_choose_intent_use_case.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/activity_create_custom_intent.xml b/exploitAPKs/qark/app/src/main/res/layout/activity_create_custom_intent.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/activity_exploit_exported_result.xml b/exploitAPKs/qark/app/src/main/res/layout/activity_exploit_exported_result.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/activity_intent_sender.xml b/exploitAPKs/qark/app/src/main/res/layout/activity_intent_sender.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/activity_top_level.xml b/exploitAPKs/qark/app/src/main/res/layout/activity_top_level.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/activity_web_view_tests.xml b/exploitAPKs/qark/app/src/main/res/layout/activity_web_view_tests.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/fragment_broadcast_stealer.xml b/exploitAPKs/qark/app/src/main/res/layout/fragment_broadcast_stealer.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/fragment_exploit_exported_activity_params.xml b/exploitAPKs/qark/app/src/main/res/layout/fragment_exploit_exported_activity_params.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/fragment_exported_activity_list.xml b/exploitAPKs/qark/app/src/main/res/layout/fragment_exported_activity_list.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/fragment_exported_components.xml b/exploitAPKs/qark/app/src/main/res/layout/fragment_exported_components.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/fragment_exported_receiver_list.xml b/exploitAPKs/qark/app/src/main/res/layout/fragment_exported_receiver_list.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/fragment_file_browser.xml b/exploitAPKs/qark/app/src/main/res/layout/fragment_file_browser.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/fragment_intent_sender.xml b/exploitAPKs/qark/app/src/main/res/layout/fragment_intent_sender.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/fragment_navigation_drawer.xml b/exploitAPKs/qark/app/src/main/res/layout/fragment_navigation_drawer.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/fragment_tap_jacking_exploit.xml b/exploitAPKs/qark/app/src/main/res/layout/fragment_tap_jacking_exploit.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/fragment_top_level.xml b/exploitAPKs/qark/app/src/main/res/layout/fragment_top_level.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/fragment_web_view_tests.xml b/exploitAPKs/qark/app/src/main/res/layout/fragment_web_view_tests.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/nav_header.xml b/exploitAPKs/qark/app/src/main/res/layout/nav_header.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/tap_jacking_toast.xml b/exploitAPKs/qark/app/src/main/res/layout/tap_jacking_toast.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/toolbar.xml b/exploitAPKs/qark/app/src/main/res/layout/toolbar.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/layout/webview.xml b/exploitAPKs/qark/app/src/main/res/layout/webview.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/menu/drawer_view.xml b/exploitAPKs/qark/app/src/main/res/menu/drawer_view.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/menu/menu_intent_sender.xml b/exploitAPKs/qark/app/src/main/res/menu/menu_intent_sender.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/menu/menu_main.xml b/exploitAPKs/qark/app/src/main/res/menu/menu_main.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/menu/menu_web_view_tests.xml b/exploitAPKs/qark/app/src/main/res/menu/menu_web_view_tests.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/mipmap-xxxhdpi/qark_512.png b/exploitAPKs/qark/app/src/main/res/mipmap-xxxhdpi/qark_512.png old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/values-w820dp/dimens.xml b/exploitAPKs/qark/app/src/main/res/values-w820dp/dimens.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/values/colors.xml b/exploitAPKs/qark/app/src/main/res/values/colors.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/values/dimens.xml b/exploitAPKs/qark/app/src/main/res/values/dimens.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/values/extraKeys.xml b/exploitAPKs/qark/app/src/main/res/values/extraKeys.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/values/intentID.xml b/exploitAPKs/qark/app/src/main/res/values/intentID.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/values/strings.xml b/exploitAPKs/qark/app/src/main/res/values/strings.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/app/src/main/res/values/styles.xml b/exploitAPKs/qark/app/src/main/res/values/styles.xml old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/build.gradle b/exploitAPKs/qark/build.gradle old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/gradle/wrapper/gradle-wrapper.jar b/exploitAPKs/qark/gradle/wrapper/gradle-wrapper.jar old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/gradle/wrapper/gradle-wrapper.properties b/exploitAPKs/qark/gradle/wrapper/gradle-wrapper.properties old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/gradlew.bat b/exploitAPKs/qark/gradlew.bat old mode 100755 new mode 100644 diff --git a/exploitAPKs/qark/settings.gradle b/exploitAPKs/qark/settings.gradle old mode 100755 new mode 100644 diff --git a/lib/BeautifulSoup.py b/lib/BeautifulSoup.py old mode 100755 new mode 100644 diff --git a/lib/__init__.py b/lib/__init__.py old mode 100755 new mode 100644 diff --git a/lib/argparse.py b/lib/argparse.py old mode 100755 new mode 100644 diff --git a/lib/axmlparserpy/__init__.py b/lib/axmlparserpy/__init__.py old mode 100755 new mode 100644 diff --git a/lib/axmlparserpy/apk.py b/lib/axmlparserpy/apk.py old mode 100755 new mode 100644 diff --git a/lib/axmlparserpy/axmlparser.py b/lib/axmlparserpy/axmlparser.py old mode 100755 new mode 100644 diff --git a/lib/axmlparserpy/axmlprinter.py b/lib/axmlparserpy/axmlprinter.py old mode 100755 new mode 100644 diff --git a/lib/axmlparserpy/bytecode.py b/lib/axmlparserpy/bytecode.py old mode 100755 new mode 100644 diff --git a/lib/axmlparserpy/stringblock.py b/lib/axmlparserpy/stringblock.py old mode 100755 new mode 100644 diff --git a/lib/axmlparserpy/typeconstants.py b/lib/axmlparserpy/typeconstants.py old mode 100755 new mode 100644 diff --git a/lib/blessed/LICENSE b/lib/blessed/LICENSE old mode 100755 new mode 100644 diff --git a/lib/blessed/__init__.py b/lib/blessed/__init__.py old mode 100755 new mode 100644 diff --git a/lib/blessed/formatters.py b/lib/blessed/formatters.py old mode 100755 new mode 100644 diff --git a/lib/blessed/keyboard.py b/lib/blessed/keyboard.py old mode 100755 new mode 100644 diff --git a/lib/blessed/sequences.py b/lib/blessed/sequences.py old mode 100755 new mode 100644 diff --git a/lib/blessed/terminal.py b/lib/blessed/terminal.py old mode 100755 new mode 100644 diff --git a/lib/blessed/tests/accessories.py b/lib/blessed/tests/accessories.py old mode 100755 new mode 100644 diff --git a/lib/blessed/tests/test_core.py b/lib/blessed/tests/test_core.py old mode 100755 new mode 100644 diff --git a/lib/blessed/tests/test_formatters.py b/lib/blessed/tests/test_formatters.py old mode 100755 new mode 100644 diff --git a/lib/blessed/tests/test_keyboard.py b/lib/blessed/tests/test_keyboard.py old mode 100755 new mode 100644 diff --git a/lib/blessed/tests/test_length_sequence.py b/lib/blessed/tests/test_length_sequence.py old mode 100755 new mode 100644 diff --git a/lib/blessed/tests/test_sequences.py b/lib/blessed/tests/test_sequences.py old mode 100755 new mode 100644 diff --git a/lib/blessed/tests/test_wrap.py b/lib/blessed/tests/test_wrap.py old mode 100755 new mode 100644 diff --git a/lib/blessings/LICENSE b/lib/blessings/LICENSE old mode 100755 new mode 100644 diff --git a/lib/blessings/__init__.py b/lib/blessings/__init__.py old mode 100755 new mode 100644 diff --git a/lib/blessings/tests.py b/lib/blessings/tests.py old mode 100755 new mode 100644 diff --git a/lib/bs4/__init__.py b/lib/bs4/__init__.py old mode 100755 new mode 100644 diff --git a/lib/bs4/builder/__init__.py b/lib/bs4/builder/__init__.py old mode 100755 new mode 100644 diff --git a/lib/bs4/builder/_html5lib.py b/lib/bs4/builder/_html5lib.py old mode 100755 new mode 100644 diff --git a/lib/bs4/builder/_htmlparser.py b/lib/bs4/builder/_htmlparser.py old mode 100755 new mode 100644 diff --git a/lib/bs4/builder/_lxml.py b/lib/bs4/builder/_lxml.py old mode 100755 new mode 100644 diff --git a/lib/bs4/dammit.py b/lib/bs4/dammit.py old mode 100755 new mode 100644 diff --git a/lib/bs4/diagnose.py b/lib/bs4/diagnose.py old mode 100755 new mode 100644 diff --git a/lib/bs4/element.py b/lib/bs4/element.py old mode 100755 new mode 100644 diff --git a/lib/bs4/testing.py b/lib/bs4/testing.py old mode 100755 new mode 100644 diff --git a/lib/bs4/tests/__init__.py b/lib/bs4/tests/__init__.py old mode 100755 new mode 100644 diff --git a/lib/bs4/tests/test_builder_registry.py b/lib/bs4/tests/test_builder_registry.py old mode 100755 new mode 100644 diff --git a/lib/bs4/tests/test_docs.py b/lib/bs4/tests/test_docs.py old mode 100755 new mode 100644 diff --git a/lib/bs4/tests/test_html5lib.py b/lib/bs4/tests/test_html5lib.py old mode 100755 new mode 100644 diff --git a/lib/bs4/tests/test_htmlparser.py b/lib/bs4/tests/test_htmlparser.py old mode 100755 new mode 100644 diff --git a/lib/bs4/tests/test_lxml.py b/lib/bs4/tests/test_lxml.py old mode 100755 new mode 100644 diff --git a/lib/bs4/tests/test_soup.py b/lib/bs4/tests/test_soup.py old mode 100755 new mode 100644 diff --git a/lib/bs4/tests/test_tree.py b/lib/bs4/tests/test_tree.py old mode 100755 new mode 100644 diff --git a/lib/cfr_0_96.jar b/lib/cfr_0_96.jar old mode 100755 new mode 100644 diff --git a/lib/colorama/LICENSE.txt b/lib/colorama/LICENSE.txt old mode 100755 new mode 100644 diff --git a/lib/colorama/__init__.py b/lib/colorama/__init__.py old mode 100755 new mode 100644 diff --git a/lib/colorama/ansi.py b/lib/colorama/ansi.py old mode 100755 new mode 100644 diff --git a/lib/colorama/ansitowin32.py b/lib/colorama/ansitowin32.py old mode 100755 new mode 100644 diff --git a/lib/colorama/initialise.py b/lib/colorama/initialise.py old mode 100755 new mode 100644 diff --git a/lib/colorama/win32.py b/lib/colorama/win32.py old mode 100755 new mode 100644 diff --git a/lib/colorama/winterm.py b/lib/colorama/winterm.py old mode 100755 new mode 100644 diff --git a/lib/coloredlogs.py b/lib/coloredlogs.py old mode 100755 new mode 100644 diff --git a/lib/dex2jar/lib/asm-all-3.3.1.jar b/lib/dex2jar/lib/asm-all-3.3.1.jar old mode 100755 new mode 100644 diff --git a/lib/dex2jar/lib/commons-lite-1.15.jar b/lib/dex2jar/lib/commons-lite-1.15.jar old mode 100755 new mode 100644 diff --git a/lib/dex2jar/lib/dex-ir-1.12.jar b/lib/dex2jar/lib/dex-ir-1.12.jar old mode 100755 new mode 100644 diff --git a/lib/dex2jar/lib/dex-reader-1.15.jar b/lib/dex2jar/lib/dex-reader-1.15.jar old mode 100755 new mode 100644 diff --git a/lib/dex2jar/lib/dex-tools-0.0.9.15.jar b/lib/dex2jar/lib/dex-tools-0.0.9.15.jar old mode 100755 new mode 100644 diff --git a/lib/dex2jar/lib/dex-translator-0.0.9.15.jar b/lib/dex2jar/lib/dex-translator-0.0.9.15.jar old mode 100755 new mode 100644 diff --git a/lib/dex2jar/lib/jar-rename-1.6.jar b/lib/dex2jar/lib/jar-rename-1.6.jar old mode 100755 new mode 100644 diff --git a/lib/dex2jar/lib/jasmin-p2.5.jar b/lib/dex2jar/lib/jasmin-p2.5.jar old mode 100755 new mode 100644 diff --git a/lib/html5lib/__init__.py b/lib/html5lib/__init__.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/constants.py b/lib/html5lib/constants.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/filters/__init__.py b/lib/html5lib/filters/__init__.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/filters/_base.py b/lib/html5lib/filters/_base.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/filters/alphabeticalattributes.py b/lib/html5lib/filters/alphabeticalattributes.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/filters/inject_meta_charset.py b/lib/html5lib/filters/inject_meta_charset.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/filters/lint.py b/lib/html5lib/filters/lint.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/filters/optionaltags.py b/lib/html5lib/filters/optionaltags.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/filters/sanitizer.py b/lib/html5lib/filters/sanitizer.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/filters/whitespace.py b/lib/html5lib/filters/whitespace.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/html5parser.py b/lib/html5lib/html5parser.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/ihatexml.py b/lib/html5lib/ihatexml.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/inputstream.py b/lib/html5lib/inputstream.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/sanitizer.py b/lib/html5lib/sanitizer.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/serializer/__init__.py b/lib/html5lib/serializer/__init__.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/serializer/htmlserializer.py b/lib/html5lib/serializer/htmlserializer.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/__init__.py b/lib/html5lib/tests/__init__.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/mockParser.py b/lib/html5lib/tests/mockParser.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/performance/concatenation.py b/lib/html5lib/tests/performance/concatenation.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/support.py b/lib/html5lib/tests/support.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/test_encoding.py b/lib/html5lib/tests/test_encoding.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/test_parser.py b/lib/html5lib/tests/test_parser.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/test_parser2.py b/lib/html5lib/tests/test_parser2.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/test_sanitizer.py b/lib/html5lib/tests/test_sanitizer.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/test_serializer.py b/lib/html5lib/tests/test_serializer.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/test_stream.py b/lib/html5lib/tests/test_stream.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/test_tokenizer.py b/lib/html5lib/tests/test_tokenizer.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/test_treeadapters.py b/lib/html5lib/tests/test_treeadapters.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/test_treewalkers.py b/lib/html5lib/tests/test_treewalkers.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/test_whitespace_filter.py b/lib/html5lib/tests/test_whitespace_filter.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/encoding/chardet/test_big5.txt b/lib/html5lib/tests/testdata/encoding/chardet/test_big5.txt old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/encoding/test-yahoo-jp.dat b/lib/html5lib/tests/testdata/encoding/test-yahoo-jp.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/encoding/tests1.dat b/lib/html5lib/tests/testdata/encoding/tests1.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/encoding/tests2.dat b/lib/html5lib/tests/testdata/encoding/tests2.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/sanitizer/tests1.dat b/lib/html5lib/tests/testdata/sanitizer/tests1.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/serializer/core.test b/lib/html5lib/tests/testdata/serializer/core.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/serializer/injectmeta.test b/lib/html5lib/tests/testdata/serializer/injectmeta.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/serializer/optionaltags.test b/lib/html5lib/tests/testdata/serializer/optionaltags.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/serializer/options.test b/lib/html5lib/tests/testdata/serializer/options.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/serializer/whitespace.test b/lib/html5lib/tests/testdata/serializer/whitespace.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/sniffer/htmlOrFeed.json b/lib/html5lib/tests/testdata/sniffer/htmlOrFeed.json old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/contentModelFlags.test b/lib/html5lib/tests/testdata/tokenizer/contentModelFlags.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/domjs.test b/lib/html5lib/tests/testdata/tokenizer/domjs.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/entities.test b/lib/html5lib/tests/testdata/tokenizer/entities.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/escapeFlag.test b/lib/html5lib/tests/testdata/tokenizer/escapeFlag.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/namedEntities.test b/lib/html5lib/tests/testdata/tokenizer/namedEntities.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/numericEntities.test b/lib/html5lib/tests/testdata/tokenizer/numericEntities.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/pendingSpecChanges.test b/lib/html5lib/tests/testdata/tokenizer/pendingSpecChanges.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/test1.test b/lib/html5lib/tests/testdata/tokenizer/test1.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/test2.test b/lib/html5lib/tests/testdata/tokenizer/test2.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/test3.test b/lib/html5lib/tests/testdata/tokenizer/test3.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/test4.test b/lib/html5lib/tests/testdata/tokenizer/test4.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/unicodeChars.test b/lib/html5lib/tests/testdata/tokenizer/unicodeChars.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/unicodeCharsProblematic.test b/lib/html5lib/tests/testdata/tokenizer/unicodeCharsProblematic.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tokenizer/xmlViolation.test b/lib/html5lib/tests/testdata/tokenizer/xmlViolation.test old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/adoption01.dat b/lib/html5lib/tests/testdata/tree-construction/adoption01.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/adoption02.dat b/lib/html5lib/tests/testdata/tree-construction/adoption02.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/comments01.dat b/lib/html5lib/tests/testdata/tree-construction/comments01.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/doctype01.dat b/lib/html5lib/tests/testdata/tree-construction/doctype01.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/domjs-unsafe.dat b/lib/html5lib/tests/testdata/tree-construction/domjs-unsafe.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/entities01.dat b/lib/html5lib/tests/testdata/tree-construction/entities01.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/entities02.dat b/lib/html5lib/tests/testdata/tree-construction/entities02.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/html5test-com.dat b/lib/html5lib/tests/testdata/tree-construction/html5test-com.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/inbody01.dat b/lib/html5lib/tests/testdata/tree-construction/inbody01.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/isindex.dat b/lib/html5lib/tests/testdata/tree-construction/isindex.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/main-element.dat b/lib/html5lib/tests/testdata/tree-construction/main-element.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/pending-spec-changes-plain-text-unsafe.dat b/lib/html5lib/tests/testdata/tree-construction/pending-spec-changes-plain-text-unsafe.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/pending-spec-changes.dat b/lib/html5lib/tests/testdata/tree-construction/pending-spec-changes.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/plain-text-unsafe.dat b/lib/html5lib/tests/testdata/tree-construction/plain-text-unsafe.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/scriptdata01.dat b/lib/html5lib/tests/testdata/tree-construction/scriptdata01.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/scripted/adoption01.dat b/lib/html5lib/tests/testdata/tree-construction/scripted/adoption01.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/scripted/ark.dat b/lib/html5lib/tests/testdata/tree-construction/scripted/ark.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/scripted/webkit01.dat b/lib/html5lib/tests/testdata/tree-construction/scripted/webkit01.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tables01.dat b/lib/html5lib/tests/testdata/tree-construction/tables01.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/template.dat b/lib/html5lib/tests/testdata/tree-construction/template.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests1.dat b/lib/html5lib/tests/testdata/tree-construction/tests1.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests10.dat b/lib/html5lib/tests/testdata/tree-construction/tests10.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests11.dat b/lib/html5lib/tests/testdata/tree-construction/tests11.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests12.dat b/lib/html5lib/tests/testdata/tree-construction/tests12.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests14.dat b/lib/html5lib/tests/testdata/tree-construction/tests14.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests15.dat b/lib/html5lib/tests/testdata/tree-construction/tests15.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests16.dat b/lib/html5lib/tests/testdata/tree-construction/tests16.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests17.dat b/lib/html5lib/tests/testdata/tree-construction/tests17.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests18.dat b/lib/html5lib/tests/testdata/tree-construction/tests18.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests19.dat b/lib/html5lib/tests/testdata/tree-construction/tests19.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests2.dat b/lib/html5lib/tests/testdata/tree-construction/tests2.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests20.dat b/lib/html5lib/tests/testdata/tree-construction/tests20.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests21.dat b/lib/html5lib/tests/testdata/tree-construction/tests21.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests22.dat b/lib/html5lib/tests/testdata/tree-construction/tests22.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests23.dat b/lib/html5lib/tests/testdata/tree-construction/tests23.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests24.dat b/lib/html5lib/tests/testdata/tree-construction/tests24.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests25.dat b/lib/html5lib/tests/testdata/tree-construction/tests25.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests26.dat b/lib/html5lib/tests/testdata/tree-construction/tests26.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests3.dat b/lib/html5lib/tests/testdata/tree-construction/tests3.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests4.dat b/lib/html5lib/tests/testdata/tree-construction/tests4.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests5.dat b/lib/html5lib/tests/testdata/tree-construction/tests5.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests6.dat b/lib/html5lib/tests/testdata/tree-construction/tests6.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests7.dat b/lib/html5lib/tests/testdata/tree-construction/tests7.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests8.dat b/lib/html5lib/tests/testdata/tree-construction/tests8.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests9.dat b/lib/html5lib/tests/testdata/tree-construction/tests9.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tests_innerHTML_1.dat b/lib/html5lib/tests/testdata/tree-construction/tests_innerHTML_1.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/tricky01.dat b/lib/html5lib/tests/testdata/tree-construction/tricky01.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/webkit01.dat b/lib/html5lib/tests/testdata/tree-construction/webkit01.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/testdata/tree-construction/webkit02.dat b/lib/html5lib/tests/testdata/tree-construction/webkit02.dat old mode 100755 new mode 100644 diff --git a/lib/html5lib/tests/tokenizertotree.py b/lib/html5lib/tests/tokenizertotree.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/tokenizer.py b/lib/html5lib/tokenizer.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treeadapters/__init__.py b/lib/html5lib/treeadapters/__init__.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treeadapters/sax.py b/lib/html5lib/treeadapters/sax.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treebuilders/__init__.py b/lib/html5lib/treebuilders/__init__.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treebuilders/_base.py b/lib/html5lib/treebuilders/_base.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treebuilders/dom.py b/lib/html5lib/treebuilders/dom.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treebuilders/etree.py b/lib/html5lib/treebuilders/etree.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treebuilders/etree_lxml.py b/lib/html5lib/treebuilders/etree_lxml.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treewalkers/__init__.py b/lib/html5lib/treewalkers/__init__.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treewalkers/_base.py b/lib/html5lib/treewalkers/_base.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treewalkers/dom.py b/lib/html5lib/treewalkers/dom.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treewalkers/etree.py b/lib/html5lib/treewalkers/etree.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treewalkers/genshistream.py b/lib/html5lib/treewalkers/genshistream.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treewalkers/lxmletree.py b/lib/html5lib/treewalkers/lxmletree.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/treewalkers/pulldom.py b/lib/html5lib/treewalkers/pulldom.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/trie/__init__.py b/lib/html5lib/trie/__init__.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/trie/_base.py b/lib/html5lib/trie/_base.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/trie/datrie.py b/lib/html5lib/trie/datrie.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/trie/py.py b/lib/html5lib/trie/py.py old mode 100755 new mode 100644 diff --git a/lib/html5lib/utils.py b/lib/html5lib/utils.py old mode 100755 new mode 100644 diff --git a/lib/jd-core-java-1.2.jar b/lib/jd-core-java-1.2.jar old mode 100755 new mode 100644 diff --git a/lib/jquery/styles.css b/lib/jquery/styles.css old mode 100755 new mode 100644 diff --git a/lib/plyj/LICENSE.TXT b/lib/plyj/LICENSE.TXT old mode 100755 new mode 100644 diff --git a/lib/plyj/__init__.py b/lib/plyj/__init__.py old mode 100755 new mode 100644 diff --git a/lib/plyj/model.py b/lib/plyj/model.py old mode 100755 new mode 100644 diff --git a/lib/plyj/parser.py b/lib/plyj/parser.py old mode 100755 new mode 100644 diff --git a/lib/procyon/LICENSE.TXT b/lib/procyon/LICENSE.TXT old mode 100755 new mode 100644 diff --git a/lib/procyon/procyon-decompiler-0.5.28.jar b/lib/procyon/procyon-decompiler-0.5.28.jar old mode 100755 new mode 100644 diff --git a/lib/procyon/procyon-decompiler-0.5.29.jar b/lib/procyon/procyon-decompiler-0.5.29.jar old mode 100755 new mode 100644 diff --git a/lib/progressbar/LICENSE.txt b/lib/progressbar/LICENSE.txt old mode 100755 new mode 100644 diff --git a/lib/progressbar/__init__.py b/lib/progressbar/__init__.py old mode 100755 new mode 100644 diff --git a/lib/progressbar/compat.py b/lib/progressbar/compat.py old mode 100755 new mode 100644 diff --git a/lib/progressbar/widgets.py b/lib/progressbar/widgets.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/LICENSE_BSD_Simple.txt b/lib/pubsub/LICENSE_BSD_Simple.txt old mode 100755 new mode 100644 diff --git a/lib/pubsub/README.txt b/lib/pubsub/README.txt old mode 100755 new mode 100644 diff --git a/lib/pubsub/RELEASE_NOTES.txt b/lib/pubsub/RELEASE_NOTES.txt old mode 100755 new mode 100644 diff --git a/lib/pubsub/__init__.py b/lib/pubsub/__init__.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/__init__.py b/lib/pubsub/core/__init__.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/arg1/__init__.py b/lib/pubsub/core/arg1/__init__.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/arg1/listenerimpl.py b/lib/pubsub/core/arg1/listenerimpl.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/arg1/publisher.py b/lib/pubsub/core/arg1/publisher.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/arg1/publishermixin.py b/lib/pubsub/core/arg1/publishermixin.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/arg1/topicargspecimpl.py b/lib/pubsub/core/arg1/topicargspecimpl.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/arg1/topicmgrimpl.py b/lib/pubsub/core/arg1/topicmgrimpl.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/callables.py b/lib/pubsub/core/callables.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/imp2.py b/lib/pubsub/core/imp2.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/itopicdefnprovider.py b/lib/pubsub/core/itopicdefnprovider.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/kwargs/__init__.py b/lib/pubsub/core/kwargs/__init__.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/kwargs/datamsg.py b/lib/pubsub/core/kwargs/datamsg.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/kwargs/listenerimpl.py b/lib/pubsub/core/kwargs/listenerimpl.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/kwargs/publisher.py b/lib/pubsub/core/kwargs/publisher.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/kwargs/publishermixin.py b/lib/pubsub/core/kwargs/publishermixin.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/kwargs/topicargspecimpl.py b/lib/pubsub/core/kwargs/topicargspecimpl.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/kwargs/topicmgrimpl.py b/lib/pubsub/core/kwargs/topicmgrimpl.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/listener.py b/lib/pubsub/core/listener.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/listenerbase.py b/lib/pubsub/core/listenerbase.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/notificationmgr.py b/lib/pubsub/core/notificationmgr.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/publisherbase.py b/lib/pubsub/core/publisherbase.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/topicargspec.py b/lib/pubsub/core/topicargspec.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/topicdefnprovider.py b/lib/pubsub/core/topicdefnprovider.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/topicexc.py b/lib/pubsub/core/topicexc.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/topicmgr.py b/lib/pubsub/core/topicmgr.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/topicobj.py b/lib/pubsub/core/topicobj.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/topictreetraverser.py b/lib/pubsub/core/topictreetraverser.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/topicutils.py b/lib/pubsub/core/topicutils.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/treeconfig.py b/lib/pubsub/core/treeconfig.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/validatedefnargs.py b/lib/pubsub/core/validatedefnargs.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/core/weakmethod.py b/lib/pubsub/core/weakmethod.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/policies.py b/lib/pubsub/policies.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/pub.py b/lib/pubsub/pub.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/py2and3.py b/lib/pubsub/py2and3.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/setuparg1.py b/lib/pubsub/setuparg1.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/setupkwargs.py b/lib/pubsub/setupkwargs.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/utils/__init__.py b/lib/pubsub/utils/__init__.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/utils/exchandling.py b/lib/pubsub/utils/exchandling.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/utils/misc.py b/lib/pubsub/utils/misc.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/utils/notification.py b/lib/pubsub/utils/notification.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/utils/topictreeprinter.py b/lib/pubsub/utils/topictreeprinter.py old mode 100755 new mode 100644 diff --git a/lib/pubsub/utils/xmltopicdefnprovider.py b/lib/pubsub/utils/xmltopicdefnprovider.py old mode 100755 new mode 100644 diff --git a/lib/pyfiglet/README b/lib/pyfiglet/README old mode 100755 new mode 100644 diff --git a/modules/DetermineMinSDK.py b/modules/DetermineMinSDK.py index 618d30f2..4d9ef3a9 100644 --- a/modules/DetermineMinSDK.py +++ b/modules/DetermineMinSDK.py @@ -15,7 +15,7 @@ from xml.dom import minidom from lib.BeautifulSoup import BeautifulSoup from distutils.version import StrictVersion -from modules.unpackAPK import unpack, findManifestInUnpackedAPK +from modules.unpackAPK import unpack, find_manifest_in_unpacked_apk import plistlib from modules import common from urllib2 import HTTPError @@ -25,7 +25,7 @@ common.logger = logging.getLogger() logger = logging.getLogger(__name__) -def findGradle(): +def find_gradle(): version=0 files=[] for (dirpath,dirname, filenames) in os.walk(common.sourceDirectory): @@ -43,7 +43,7 @@ def findGradle(): version=version.findall(str(m[0]))[0] return version -def determineMinSDK(): +def determine_min_sdk(): """ Determines the minimum SDK version supported by the vulnerable application\n As a fallback, it allows the user to search Google PlayStore to identify the minimum SDK version if the data is unavailable in manifest.xml @@ -65,7 +65,7 @@ def determineMinSDK(): if common.minSdkVersion==0: if common.source_or_apk==2: - common.minSdkVersion=findGradle() + common.minSdkVersion=find_gradle() if common.minSdkVersion==0: common.logger.info("We were unable to find the minimum SDK version in your source.") determineSdk='m' diff --git a/modules/GeneralIssues.py b/modules/GeneralIssues.py index 872293be..0f7f649b 100644 --- a/modules/GeneralIssues.py +++ b/modules/GeneralIssues.py @@ -16,7 +16,7 @@ common.logger = logging.getLogger() logger = logging.getLogger(__name__) -def verifyAllowBackup(app): +def verify_allow_backup(app): """ Check if AllowBackup option is enabled in manifest.xml """ @@ -36,7 +36,7 @@ def verifyAllowBackup(app): except Exception as e: print e.message -def verifyCustomPermissions(): +def verify_custom_permissions(): """ Verify if the application defines any custom permissions """ @@ -54,7 +54,7 @@ def verifyCustomPermissions(): logger.debug(common.config.get('qarkhelper', 'NO_PERM_PROT')) return -def verifyDebuggable(app): +def verify_debuggable(app): ''' Verify whether the debuggable flag is set in the manifest ''' diff --git a/modules/__init__.py b/modules/__init__.py old mode 100755 new mode 100644 diff --git a/modules/adb.py b/modules/adb.py index 5985bd18..f3eb4556 100644 --- a/modules/adb.py +++ b/modules/adb.py @@ -5,16 +5,32 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.''' -from modules import common,intents,report +from modules import common,findExtras,report import re -def showAdbCommands(component,compType,packageName): +def show_adb_commands(component,compType,packageName): #Print ADB commands for exploitation cmd_list=[] cmd_list.append([]) #BUG - THIS PRINTS DUPS - #TODO - re-implement the extras, just want to make sure it looks good first - #suggest_extras=raw_input("Would you like us to suggest extras to add? (y/n) ") + extra_parameters=[] + extra_parameters.append('[-e|--es ...]') + extra_parameters.append('[--esn ...]') + extra_parameters.append('[--ez ...]') + extra_parameters.append('[--ei ...]') + extra_parameters.append('[--el ...]') + extra_parameters.append('[--ef ...]') + extra_parameters.append('[--eu ...]') + extra_parameters.append('[--ecn ]') + extra_parameters.append('[--eia [, [, [, [,0: #find extra suggestions for the intents in c[1], if any extras_list=[] - extras_list+=intents.find_extras(str(c[1]),common.sourceDirectory) - if len(extras_list)>0: - for t in extras_list: - if re.match(r'^\..*',str(c[1])): - command = "adb shell am start -a \"" + c[0] + "\" -n \""+packageName+"/"+packageName+str(c[1])+"\""+" --es "+str(t)+" \"EXTRA_VALUE_IN_QUOTES\"" - else: - command = "adb shell am start -a \"" + c[0] + "\" -n \""+packageName+"/"+str(c[1])+"\""+" --es "+str(t)+" \"EXTRA_VALUE_IN_QUOTES\"" - print command - report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, command, None, "activity") - else: + extras_list.append([]) + entries=common.get_entry_for_component('activity') + output=False + for n in entries: + tmp_extra=findExtras.find_extras(str(c[1]),n) + if tmp_extra not in extras_list: + extras_list+=tmp_extra + if len(extras_list)>2: + for t in range(1,(len(extras_list)-1)): + if str(extras_list[t]) not in type_list: + if re.match(r'^\..*',str(c[1])): + baseIntent = "adb shell am start -a \"" + c[0] + "\" -n \""+packageName+"/"+packageName+str(c[1])+"\"" + else: + baseIntent = "adb shell am start -a \"" + c[0] + "\" -n \""+packageName+"/"+str(c[1])+"\"" + simple_type=True + if extras_list[t+1]=='String': + baseIntent+=" --es " + elif extras_list[t+1]=='Boolean': + baseIntent+=" --ez " + elif extras_list[t+1]=='Int': + baseIntent+=" --ei " + elif extras_list[t+1]=='Long': + baseIntent+=" --el " + elif extras_list[t+1]=='Float': + baseIntent+=" --ef " + else: + simple_type=False + + if simple_type: + extra_type=str(extras_list[t+1]) + print baseIntent+"\""+str(extras_list[t])+"\" \"Insert"+extra_type+"Here\"" + output=True + #TODO, Need to think of a better way to do this + #This is excluding all the known types, because every second element is type + elif str(extras_list[t]) not in type_list: + common.logger.info("Extra: " + str(extras_list[t])+" is not a simple type, or could not be determined. You'll need to append the parameter which corresponds with the correct data type, followed by a key and value, both in quotes.") + print "Example: "+baseIntent+str(" --es \"YOURKEYHERE\" \"YOURVALUEHERE\"") + print "Here are your options for different data types: " + for x in extra_parameters: + print str(x) + print "\n" + output=True + report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, baseIntent, None, "activity") + extras_list=[] + if not output: if re.match(r'^\..*',str(c[1])): - command = "adb shell am start -a \"" + c[0] + "\" -n \""+packageName+"/"+packageName+str(c[1])+"\"" + baseIntent = "adb shell am start -a \"" + c[0] + "\" -n \""+packageName+"/"+packageName+str(c[1])+"\"" else: - command = "adb shell am start -a \"" + c[0] + "\" -n \""+packageName+"/"+str(c[1])+"\"" - print command - report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, command, None, "activity") + baseIntent = "adb shell am start -a \"" + c[0] + "\" -n \""+packageName+"/"+str(c[1])+"\"" + print baseIntent else: common.logger.debug("No intent filter on: " + str(component)) extras_list=[] - extras_list+=intents.find_extras(str(component),common.sourceDirectory) + entries=common.get_entry_for_component('activity') + output=False + last_extra='' + for n in entries: + tmp_extra=findExtras.find_extras(str(component),n) + if tmp_extra not in extras_list: + if str(tmp_extra)!=str(last_extra): + extras_list+=tmp_extra + last_extra=str(tmp_extra) if len(extras_list)>0: + for t in range(1,(len(extras_list)-1)): + if str(extras_list[t]) not in type_list: + if re.match(r'^\..*',str(component)): + baseIntent = "adb shell am start -n \""+packageName+"/"+packageName+str(component)+"\"" + else: + baseIntent = "adb shell am start -n \""+packageName+"/"+str(component)+"\"" + simple_type=True + if extras_list[t+1]=='String': + baseIntent+=" --es " + elif extras_list[t+1]=='Boolean': + baseIntent+=" --ez " + elif extras_list[t+1]=='Int': + baseIntent+=" --ei " + elif extras_list[t+1]=='Long': + baseIntent+=" --el " + elif extras_list[t+1]=='Float': + baseIntent+=" --ef " + elif extras_list[t+1]=='Uri': + baseIntent+=" -d " + else: + simple_type=False + + if simple_type: + extra_type=str(extras_list[t+1]) + print baseIntent+str(extras_list[t])+" \"Insert"+extra_type+"Here\"" + output=True + #TODO, Need to think of a better way to do this + #This is excluding all the known types, because every second element is type + elif str(extras_list[t]) not in type_list: + common.logger.info("Extra: " + str(extras_list[t])+" is not a simple type, or could not be determined. You'll need to append the parameter which corresponds with the correct data type, followed by a key and value, both in quotes.") + print "Example: "+baseIntent+str(" --es \"YOURKEYHERE\" \"YOURVALUEHERE\"") + print "Here are your options for different data types: " + for x in extra_parameters: + print str(x) + print "\n" + ouput=True + report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, baseIntent, None, "activity") + extras_list=[] + if not output: if re.match(r'^\..*',str(component)): - command = "adb shell am start -n \""+packageName+"/"+packageName+component+"\"" - else: - command = "adb shell am start -n \""+packageName+"/"+component+"\"" - print command - extras = [] - for e in extras_list: - extras.append("Possible extras to send: " + str(e)) - print "Possible extras to send: " + str(e) - report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, command, extras, "activity") - else: - if re.match(r'^\..*',str(component)): - command = "adb shell am start -n \""+packageName+"/"+packageName+component+"\"" + baseIntent = "adb shell am start -n \""+packageName+"/"+packageName+str(component)+"\"" else: - command = "adb shell am start -n \""+packageName+"/"+component+"\"" - print command - report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, command, None, "activity") + baseIntent = "adb shell am start -n \""+packageName+"/"+str(component)+"\"" + print baseIntent + elif str(compType)=='service': #BUG - THIS PRINTS DUPS without the below for node in common.xmldoc.getElementsByTagName('service'): @@ -76,49 +162,126 @@ def showAdbCommands(component,compType,packageName): cmd_list=common.dedup(cmd_list) for c in cmd_list: if len(c)>0: + output=False extras_list=[] - extras_list+=intents.find_extras(str(c[1]),common.sourceDirectory) + entries=common.get_entry_for_component('service') + for n in entries: + tmp_extra=findExtras.find_extras(str(c[1]),n) + if tmp_extra not in extras_list: + extras_list+=tmp_extra if len(extras_list)>0: - for t in extras_list: - if re.match(r'^\..*',str(c[1])): - command = "adb shell am startservice " +packageName+"/"+packageName+str(c[1])+" --es "+str(t) - else: - command = "adb shell am startservice " +packageName+"/"+str(c[1])+" --es "+str(t) - print command - report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, command, None, "service") - else: + for t in range(1,(len(extras_list)-1)): + if str(extras_list[t]) not in type_list: + if re.match(r'^\..*',str(c[1])): + baseIntent = "adb shell am startservice -n \"" +packageName+"/"+packageName+str(c[1])+"\""+" -a \""+str(c[0])+"\"" + else: + baseIntent = "adb shell am startservice -n \"" +packageName+"/"+str(c[1])+"\""+" -a \""+str(c[0])+"\"" + simple_type=True + if extras_list[t+1]=='String': + baseIntent+=" --es " + elif extras_list[t+1]=='Boolean': + baseIntent+=" --ez " + elif extras_list[t+1]=='Int': + baseIntent+=" --ei " + elif extras_list[t+1]=='Long': + baseIntent+=" --el " + elif extras_list[t+1]=='Float': + baseIntent+=" --ef " + elif extras_list[t+1]=='Uri': + baseIntent+=" -d " + else: + simple_type=False + + if simple_type: + extra_type=str(extras_list[t+1]) + print baseIntent+str(extras_list[t])+" \"Insert"+extra_type+"Here\"" + output=True + #TODO, Need to think of a better way to do this + #This is excluding all the known types, because every second element is type + elif str(extras_list[t]) not in type_list: + common.logger.info("Extra: " + str(extras_list[t])+" is not a simple type, or could not be determined. You'll need to append the parameter which corresponds with the correct data type, followed by a key and value, both in quotes.") + print "Example: "+baseIntent+str(" --es \"YOURKEYHERE\" \"YOURVALUEHERE\"") + print "Here are your options for different data types: " + for x in extra_parameters: + print str(x) + print "\n" + output=True + report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, baseIntent, None, "service") + extras_list=[] + if not output: if re.match(r'^\..*',str(c[1])): - command = "adb shell am startservice " +packageName+"/"+packageName+str(c[1]) + baseIntent = "adb shell am startservice -n \"" +packageName+"/"+packageName+str(c[1])+"\"" else: - command = "adb shell am startservice " +packageName+"/"+str(c[1]) - print command - report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, command, None, "service") + baseIntent = "adb shell am startservice -n \"" +packageName+"/"+str(c[1])+"\"" + print baseIntent + report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, baseIntent, None, "service") + elif str(compType)=='receiver': for node in common.xmldoc.getElementsByTagName('receiver'): if node.attributes['android:name'].value==component: - for x in node.getElementsByTagName('intent-filter'): - for a in node.getElementsByTagName('action'): - cmd_list.append([a.attributes['android:name'].value,component]) - cmd_list=common.dedup(cmd_list) - for c in cmd_list: - if len(c)>0: - extras_list=[] - extras_list+=intents.find_extras(str(c[1]),common.sourceDirectory) - if len(extras_list)>0: - for t in extras_list: - baseIntent="adb shell am broadcast -a \""+str(c[0])+"\"" - print "Possible Extra: " + str(t) - baseIntent+=" --es "+str(t)+" \"YOURDATAHERE\"" + if len(node.getElementsByTagName('intent-filter'))>0: + for x in node.getElementsByTagName('intent-filter'): + for a in node.getElementsByTagName('action'): + cmd_list.append([a.attributes['android:name'].value,component]) + try: + cmd_list=common.dedup(cmd_list) + except Exception as e: + common.logger.error("Error de-duplicating command list in adb.py while processing receivers: " + str(e)) + for c in cmd_list: + if len(c)>0: + output=False + extras_list=[] + try: + entries=common.get_entry_for_component('receiver') + except Exception as e: + common.logger.error("Error getting entry point for receivers in adb.py: " + str(e) ) + for n in entries: + try: + tmp_extra=findExtras.find_extras(str(c[1]),n) + except Exception as e: + common.logger.error("Error finding extras for receivers in adb.py: " + str(e)) + if tmp_extra not in extras_list: + extras_list+=tmp_extra + if len(extras_list)>0: + for t in range(1,(len(extras_list)-1)): + if str(extras_list[t]) not in type_list: + baseIntent="adb shell am broadcast -a \""+str(c[0])+"\"" + simple_type=True + if extras_list[t+1]=='String': + baseIntent+=" --es " + elif extras_list[t+1]=='Boolean': + baseIntent+=" --ez " + elif extras_list[t+1]=='Int': + baseIntent+=" --ei " + elif extras_list[t+1]=='Long': + baseIntent+=" --el " + elif extras_list[t+1]=='Float': + baseIntent+=" --ef " + elif extras_list[t+1]=='Uri': + baseIntent+=" -d " + else: + simple_type=False + if simple_type: + extra_type=str(extras_list[t+1]) + print baseIntent+"\""+str(extras_list[t])+"\" \"Insert"+extra_type+"Here\"" + output=True + #TODO, Need to think of a better way to do this + #This is excluding all the known types, because every second element is type + elif str(extras_list[t]) not in type_list: + common.logger.info("Extra: " + str(extras_list[t])+" is not a simple type, or could not be determined. You'll need to append the parameter which corresponds with the correct data type, followed by a key and value, both in quotes.") + print "Example: "+baseIntent+str(" --es \"YOURKEYHERE\" \"YOURVALUEHERE\"") + print "Here are your options for different data types: " + for x in extra_parameters: + print str(x) + print "\n" + output=True + report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, baseIntent, None, "receiver") + extras_list=[] + if not output: + baseIntent = "adb shell am broadcast -a \""+str(c[0])+"\"" print baseIntent report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, baseIntent, None, "receiver") - common.logger.info("Sorry, the dynamic extra suggestions is still a work in progress. In the mean time, know that the --es flag is used for sending key/value pairs which are strings.") - common.logger.info("If the suggested extra does not appear quoted, it is either a CONSTANT or String variable, it should not be used literally as shown") - else: - command = "adb shell am broadcast -a \""+str(c[0])+"\"" - print command - report.write_adb_commands("adbcommands-issues-list", common.Severity.VULNERABILITY, command, None, "receiver") - elif str(compType)=='provider': for node in common.xmldoc.getElementsByTagName('provider'): if node.attributes['android:name'].value == component: diff --git a/modules/certValidation.py b/modules/certValidation.py index 6a4f0993..1cdc97d5 100644 --- a/modules/certValidation.py +++ b/modules/certValidation.py @@ -61,32 +61,32 @@ def validate(queue,height): if type(type_decl) is m.ClassDeclaration: for t in type_decl.body: try: - recursiveInsecureTrustManager(t,j,results) + recursive_insecure_trust_manager(t,j,results) except Exception as e: - common.logger.error("Unable to run recursiveInsecureTrustManager in certValidation.py: " + str(e)) + common.logger.error("Unable to run recursive_insecure_trust_manager in certValidation.py: " + str(e)) try: - recursiveAllowAllHostnameVerifier(t,j,results) + recursive_allow_all_hostname_verifier(t,j,results) except Exception as e: - common.logger.error("Unable to run recursiveAllowAllHostnameVerifier in certValidation.py: " + str(e)) + common.logger.error("Unable to run recursive_allow_all_hostname_verifier in certValidation.py: " + str(e)) try: - recursiveSSLSession(t,j,results) + recursive_ssl_session(t,j,results) except Exception as e: - common.logger.error("Unable to run recursiveSSLSession in certValidation.py: " + str(e)) + common.logger.error("Unable to run recursive_ssl_session in certValidation.py: " + str(e)) except Exception as e: if common.source_or_apk==2: - common.logger.error("findLocalMethodDeclarations returned an error in certValidation.py" + str(e)) + common.logger.error("Error in validate function of certValidation.py: " + str(e)) else: common.logger.error("Bad file: " + str(j) + ", this is not uncommon") try: - rescursiveFindVerify(None,j,results) + recursive_find_verify(None,j,results) except Exception as e: common.logger.error("Problem in findVerify function of certValidation.py: " + str(e)) warningGiven=False - unverifiedSessions(results) + unverified_sessions(results) queue.put(results) return -def recursiveInsecureTrustManager(t,filename,results): +def recursive_insecure_trust_manager(t,filename,results): if type(t) is m.MethodDeclaration: if str(t.name)=='checkServerTrusted': if len(t.body)==0: @@ -120,13 +120,13 @@ def recursiveInsecureTrustManager(t,filename,results): break #TODO - only want to check once, to see if it's only a return, can probably be replaced by len() elif type(t) is list: for x in t: - recursiveInsecureTrustManager(x,filename,results) + recursive_insecure_trust_manager(x,filename,results) elif hasattr(t,'_fields'): for f in t._fields: - recursiveInsecureTrustManager(getattr(t,f),filename,results) + recursive_insecure_trust_manager(getattr(t,f),filename,results) return -def recursiveAllowAllHostnameVerifier(t,filename,results): +def recursive_allow_all_hostname_verifier(t,filename,results): #TODO - This can be fleshed out to be more of an accurate, exhaustive check, but will suffice for now if type(t) is m.Assignment: if type(t.rhs) is m.InstanceCreation: @@ -169,13 +169,13 @@ def recursiveAllowAllHostnameVerifier(t,filename,results): results.append(issue) elif type(t) is list: for x in t: - recursiveAllowAllHostnameVerifier(x,filename,results) + recursive_allow_all_hostname_verifier(x,filename,results) elif hasattr(t,'_fields'): for f in t._fields: - recursiveAllowAllHostnameVerifier(getattr(t,f),filename,results) + recursive_allow_all_hostname_verifier(getattr(t,f),filename,results) return -def recursiveSSLSession(t,filename,results): +def recursive_ssl_session(t,filename,results): ''' Looks for use of a HostnameVerifier where no call to .verify is made ''' @@ -200,16 +200,16 @@ def recursiveSSLSession(t,filename,results): sslSessions.append(str(d.variable.name)) elif type(t) is list: for l in t: - recursiveSSLSession(l,filename,results) + recursive_ssl_session(l,filename,results) elif hasattr(t,'_fields'): for f in t._fields: - recursiveSSLSession(getattr(t,f),filename,results) + recursive_ssl_session(getattr(t,f),filename,results) except Exception as e: - common.logger.debug("Something went wrong in certValidation.py's recursiveSSLSession: " + str(e)) + common.logger.debug("Something went wrong in certValidation.py's recursive_ssl_session: " + str(e)) common.parsingerrors.add(str(filename)) return -def rescursiveFindVerify(q,filename,results): +def recursive_find_verify(q,filename,results): ''' Find all .verify methods ''' @@ -265,22 +265,22 @@ def rescursiveFindVerify(q,filename,results): for l in t: if type(l) is not None: verifyIteration=1 - rescursiveFindVerify(l,filename,results) + recursive_find_verify(l,filename,results) elif hasattr(t,'_fields'): for f in t._fields: if type(getattr(t,f)) is not None: verifyIteration=1 - rescursiveFindVerify(getattr(t,f),filename,results) + recursive_find_verify(getattr(t,f),filename,results) elif type(t) is list: for l in t: if type(l) is not None: verifyIteration=1 - rescursiveFindVerify(l,filename,results) + recursive_find_verify(l,filename,results) elif hasattr(t,'_fields'): for f in t._fields: if type(getattr(t,f)) is not None: verifyIteration=1 - rescursiveFindVerify(getattr(t,f),filename,results) + recursive_find_verify(getattr(t,f),filename,results) except Exception as e: common.logger.debug("Something went wrong in certValidation.py's findVerify: " + str(e)) report.write("parsingerror-issues-list", "Something went wrong in certValidation.py's findVerify: " + str(e), "strong") @@ -332,24 +332,24 @@ def rescursiveFindVerify(q,filename,results): elif type(q) is list: for l in q: if type(l) is not None: - rescursiveFindVerify(l,filename,results) + recursive_find_verify(l,filename,results) elif hasattr(q,'_fields'): for f in q._fields: if type(getattr(q,f)) is not None: - rescursiveFindVerify(getattr(q,f),filename,results) + recursive_find_verify(getattr(q,f),filename,results) elif type(q) is list: for l in q: if type(l) is not None: - rescursiveFindVerify(l,filename,results) + recursive_find_verify(l,filename,results) elif hasattr(q,'_fields'): for f in q._fields: if type(getattr(q,f)) is not None: - rescursiveFindVerify(getattr(q,f),filename,results) + recursive_find_verify(getattr(q,f),filename,results) verifyIteration=1 - unverifiedSessions(results) + unverified_sessions(results) return -def unverifiedSessions(results): +def unverified_sessions(results): global sslSessions #This is untested because I could not find a vulnerable app, which didn't have a custom .verify method for s in sslSessions: diff --git a/modules/common.py b/modules/common.py index 5f3cf718..546d11ff 100644 --- a/modules/common.py +++ b/modules/common.py @@ -53,6 +53,7 @@ config.read(script_location) manifest = "" java_files = [] +xml_files = [] keyFiles=[] minSdkVersion = 1 rootDir = "" @@ -69,6 +70,15 @@ badVerifiers = ['ALLOW_ALL_HOSTNAME_VERIFIER'] sourceDirectory="" parsingerrors = set() +file_not_found=[] + +#TODO - Double check this list against : https://android.googlesource.com/platform/frameworks/base/+/master/core/res/AndroidManifest.xml +#This is a list of broadcasts that only system apps should be able to send. If the attacker already has system level access, it's game over... +#TODO For readability, break this into multiple lines using \ +#TODO - This pages lists system-only Intents: http://developer.android.com/reference/android/content/Intent.html, which all seem to be included in the list below, but when we're not lazy, we shoudl verify this and break them out +#TODO - Need to double check that we're checking for protected Intents in all the right places below +protected_broadcasts=['android.intent.action.SCREEN_OFF','android.intent.action.SCREEN_ON','android.intent.action.USER_PRESENT','android.intent.action.TIME_TICK','android.intent.action.TIMEZONE_CHANGED','android.intent.action.BOOT_COMPLETED','android.intent.action.PACKAGE_INSTALL','android.intent.action.PACKAGE_ADDED','android.intent.action.PACKAGE_REPLACED','android.intent.action.MY_PACKAGE_REPLACED','android.intent.action.PACKAGE_REMOVED','android.intent.action.PACKAGE_FULLY_REMOVED','android.intent.action.PACKAGE_CHANGED','android.intent.action.PACKAGE_RESTARTED','android.intent.action.PACKAGE_DATA_CLEARED','android.intent.action.PACKAGE_FIRST_LAUNCH','android.intent.action.PACKAGE_NEEDS_VERIFICATION','android.intent.action.PACKAGE_VERIFIED','android.intent.action.UID_REMOVED','android.intent.action.QUERY_PACKAGE_RESTART','android.intent.action.CONFIGURATION_CHANGED','android.intent.action.LOCALE_CHANGED','android.intent.action.BATTERY_CHANGED','android.intent.action.BATTERY_LOW','android.intent.action.BATTERY_OKAY','android.intent.action.ACTION_POWER_CONNECTED','android.intent.action.ACTION_POWER_DISCONNECTED','android.intent.action.ACTION_SHUTDOWN','android.intent.action.DEVICE_STORAGE_LOW','android.intent.action.DEVICE_STORAGE_OK','android.intent.action.DEVICE_STORAGE_FULL','android.intent.action.DEVICE_STORAGE_NOT_FULL','android.intent.action.NEW_OUTGOING_CALL','android.intent.action.REBOOT','android.intent.action.DOCK_EVENT','android.intent.action.MASTER_CLEAR_NOTIFICATION','android.intent.action.USER_ADDED','android.intent.action.USER_REMOVED','android.intent.action.USER_STOPPED','android.intent.action.USER_BACKGROUND','android.intent.action.USER_FOREGROUND','android.intent.action.USER_SWITCHED','android.app.action.ENTER_CAR_MODE','android.app.action.EXIT_CAR_MODE','android.app.action.ENTER_DESK_MODE','android.app.action.EXIT_DESK_MODE','android.appwidget.action.APPWIDGET_UPDATE_OPTIONS','android.appwidget.action.APPWIDGET_DELETED','android.appwidget.action.APPWIDGET_DISABLED','android.appwidget.action.APPWIDGET_ENABLED','android.backup.intent.RUN','android.backup.intent.CLEAR','android.backup.intent.INIT','android.bluetooth.adapter.action.STATE_CHANGED','android.bluetooth.adapter.action.SCAN_MODE_CHANGED','android.bluetooth.adapter.action.DISCOVERY_STARTED','android.bluetooth.adapter.action.DISCOVERY_FINISHED','android.bluetooth.adapter.action.LOCAL_NAME_CHANGED','android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED','android.bluetooth.device.action.FOUND','android.bluetooth.device.action.DISAPPEARED','android.bluetooth.device.action.CLASS_CHANGED','android.bluetooth.device.action.ACL_CONNECTED','android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED','android.bluetooth.device.action.ACL_DISCONNECTED','android.bluetooth.device.action.NAME_CHANGED','android.bluetooth.device.action.BOND_STATE_CHANGED','android.bluetooth.device.action.NAME_FAILED','android.bluetooth.device.action.PAIRING_REQUEST','android.bluetooth.device.action.PAIRING_CANCEL','android.bluetooth.device.action.CONNECTION_ACCESS_REPLY','android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED','android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED','android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT','android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED','android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED','android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED','android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED','android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED','android.hardware.usb.action.USB_STATE','android.hardware.usb.action.USB_ACCESSORY_ATTACHED','android.hardware.usb.action.USB_ACCESSORY_ATTACHED','android.hardware.usb.action.USB_DEVICE_ATTACHED','android.hardware.usb.action.USB_DEVICE_DETACHED','android.intent.action.HEADSET_PLUG','android.intent.action.ANALOG_AUDIO_DOCK_PLUG','android.intent.action.DIGITAL_AUDIO_DOCK_PLUG','android.intent.action.HDMI_AUDIO_PLUG','android.intent.action.USB_AUDIO_ACCESSORY_PLUG','android.intent.action.USB_AUDIO_DEVICE_PLUG','android.net.conn.CONNECTIVITY_CHANGE','android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE','android.net.conn.DATA_ACTIVITY_CHANGE','android.net.conn.BACKGROUND_DATA_SETTING_CHANGED','android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED','android.nfc.action.LLCP_LINK_STATE_CHANGED','com.android.nfc_extras.action.RF_FIELD_ON_DETECTED','com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED','com.android.nfc_extras.action.AID_SELECTED','android.nfc.action.TRANSACTION_DETECTED','android.intent.action.CLEAR_DNS_CACHE','android.intent.action.PROXY_CHANGE','android.os.UpdateLock.UPDATE_LOCK_CHANGED','android.intent.action.DREAMING_STARTED','android.intent.action.DREAMING_STOPPED','android.intent.action.ANY_DATA_STATE','com.android.server.WifiManager.action.START_SCAN','com.android.server.WifiManager.action.DELAYED_DRIVER_STOP','android.net.wifi.WIFI_STATE_CHANGED','android.net.wifi.WIFI_AP_STATE_CHANGED','android.net.wifi.WIFI_SCAN_AVAILABLE','android.net.wifi.SCAN_RESULTS','android.net.wifi.RSSI_CHANGED','android.net.wifi.STATE_CHANGE','android.net.wifi.LINK_CONFIGURATION_CHANGED','android.net.wifi.CONFIGURED_NETWORKS_CHANGE','android.net.wifi.supplicant.CONNECTION_CHANGE','android.net.wifi.supplicant.STATE_CHANGE','android.net.wifi.p2p.STATE_CHANGED','android.net.wifi.p2p.DISCOVERY_STATE_CHANGE','android.net.wifi.p2p.THIS_DEVICE_CHANGED','android.net.wifi.p2p.PEERS_CHANGED','android.net.wifi.p2p.CONNECTION_STATE_CHANGE','android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED','android.net.conn.TETHER_STATE_CHANGED','android.net.conn.INET_CONDITION_ACTION','android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE','android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE','android.intent.action.AIRPLANE_MODE','android.intent.action.ADVANCED_SETTINGS','android.intent.action.BUGREPORT_FINISHED','android.intent.action.ACTION_IDLE_MAINTENANCE_START','android.intent.action.ACTION_IDLE_MAINTENANCE_END','android.intent.action.SERVICE_STATE','android.intent.action.RADIO_TECHNOLOGY','android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED','android.intent.action.SIG_STR','android.intent.action.ANY_DATA_STATE','android.intent.action.DATA_CONNECTION_FAILED','android.intent.action.SIM_STATE_CHANGED','android.intent.action.NETWORK_SET_TIME','android.intent.action.NETWORK_SET_TIMEZONE','android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS','android.intent.action.ACTION_MDN_STATE_CHANGED','android.provider.Telephony.SPN_STRINGS_UPDATED','android.provider.Telephony.SIM_FULL','com.android.internal.telephony.data-restart-trysetup','com.android.internal.telephony.data-stall'] + ''' This is here specifically because we saw an issue with the import of html5lib in python on some machines Better to have a scan and no html report, than no scan @@ -297,6 +307,17 @@ def find_java(path): list_of_files.append(os.path.join(dirpath,filename)) return list_of_files +def find_xml(path): + """ + Given an absolute path, find and return all R.java files in a list + + """ + list_of_files = [] + for (dirpath, dirnames, filenames) in os.walk(path): + for filename in filenames: + if filename[-4:] == '.xml': + list_of_files.append(os.path.join(dirpath,filename)) + return list_of_files def findKeys(path): """ @@ -375,6 +396,17 @@ def text_scan(file_list,rex_n): result_list.append([result,x]) return result_list +def text_scan_single(file_name,rex_n): + """ + Given a single files, search content of each file by the regular expression and return a list of matches + """ + result_list=[] + result_list.append([]) + result=read_files(file_name,rex_n) + if len(result)>0: + result_list.append([result,file_name]) + return result_list + def compare(length, req_length, msg, bye): """ Deprecated code @@ -438,18 +470,15 @@ def check_export(tag,output): """ Check if the application has marked the tag as EXPORTED """ + + global protected_broadcasts + report_data = [] private_list=[] exported_list=[] exported_perm_list=[] exported_perm_list.append([]) protected_broad_list=[] - #TODO - Double check this list against : https://android.googlesource.com/platform/frameworks/base/+/master/core/res/AndroidManifest.xml - #This is a list of broadcasts that only system apps should be able to send. If the attacker already has system level access, it's game over... - #TODO For readability, break this into multiple lines using \ - #TODO - This pages lists system-only Intents: http://developer.android.com/reference/android/content/Intent.html, which all seem to be included in the list below, but when we're not lazy, we shoudl verify this and break them out - #TODO - Need to double check that we're checking for protected Intents in all the right places below - protected_broadcasts=['android.intent.action.SCREEN_OFF','android.intent.action.SCREEN_ON','android.intent.action.USER_PRESENT','android.intent.action.TIME_TICK','android.intent.action.TIMEZONE_CHANGED','android.intent.action.BOOT_COMPLETED','android.intent.action.PACKAGE_INSTALL','android.intent.action.PACKAGE_ADDED','android.intent.action.PACKAGE_REPLACED','android.intent.action.MY_PACKAGE_REPLACED','android.intent.action.PACKAGE_REMOVED','android.intent.action.PACKAGE_FULLY_REMOVED','android.intent.action.PACKAGE_CHANGED','android.intent.action.PACKAGE_RESTARTED','android.intent.action.PACKAGE_DATA_CLEARED','android.intent.action.PACKAGE_FIRST_LAUNCH','android.intent.action.PACKAGE_NEEDS_VERIFICATION','android.intent.action.PACKAGE_VERIFIED','android.intent.action.UID_REMOVED','android.intent.action.QUERY_PACKAGE_RESTART','android.intent.action.CONFIGURATION_CHANGED','android.intent.action.LOCALE_CHANGED','android.intent.action.BATTERY_CHANGED','android.intent.action.BATTERY_LOW','android.intent.action.BATTERY_OKAY','android.intent.action.ACTION_POWER_CONNECTED','android.intent.action.ACTION_POWER_DISCONNECTED','android.intent.action.ACTION_SHUTDOWN','android.intent.action.DEVICE_STORAGE_LOW','android.intent.action.DEVICE_STORAGE_OK','android.intent.action.DEVICE_STORAGE_FULL','android.intent.action.DEVICE_STORAGE_NOT_FULL','android.intent.action.NEW_OUTGOING_CALL','android.intent.action.REBOOT','android.intent.action.DOCK_EVENT','android.intent.action.MASTER_CLEAR_NOTIFICATION','android.intent.action.USER_ADDED','android.intent.action.USER_REMOVED','android.intent.action.USER_STOPPED','android.intent.action.USER_BACKGROUND','android.intent.action.USER_FOREGROUND','android.intent.action.USER_SWITCHED','android.app.action.ENTER_CAR_MODE','android.app.action.EXIT_CAR_MODE','android.app.action.ENTER_DESK_MODE','android.app.action.EXIT_DESK_MODE','android.appwidget.action.APPWIDGET_UPDATE_OPTIONS','android.appwidget.action.APPWIDGET_DELETED','android.appwidget.action.APPWIDGET_DISABLED','android.appwidget.action.APPWIDGET_ENABLED','android.backup.intent.RUN','android.backup.intent.CLEAR','android.backup.intent.INIT','android.bluetooth.adapter.action.STATE_CHANGED','android.bluetooth.adapter.action.SCAN_MODE_CHANGED','android.bluetooth.adapter.action.DISCOVERY_STARTED','android.bluetooth.adapter.action.DISCOVERY_FINISHED','android.bluetooth.adapter.action.LOCAL_NAME_CHANGED','android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED','android.bluetooth.device.action.FOUND','android.bluetooth.device.action.DISAPPEARED','android.bluetooth.device.action.CLASS_CHANGED','android.bluetooth.device.action.ACL_CONNECTED','android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED','android.bluetooth.device.action.ACL_DISCONNECTED','android.bluetooth.device.action.NAME_CHANGED','android.bluetooth.device.action.BOND_STATE_CHANGED','android.bluetooth.device.action.NAME_FAILED','android.bluetooth.device.action.PAIRING_REQUEST','android.bluetooth.device.action.PAIRING_CANCEL','android.bluetooth.device.action.CONNECTION_ACCESS_REPLY','android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED','android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED','android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT','android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED','android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED','android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED','android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED','android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED','android.hardware.usb.action.USB_STATE','android.hardware.usb.action.USB_ACCESSORY_ATTACHED','android.hardware.usb.action.USB_ACCESSORY_ATTACHED','android.hardware.usb.action.USB_DEVICE_ATTACHED','android.hardware.usb.action.USB_DEVICE_DETACHED','android.intent.action.HEADSET_PLUG','android.intent.action.ANALOG_AUDIO_DOCK_PLUG','android.intent.action.DIGITAL_AUDIO_DOCK_PLUG','android.intent.action.HDMI_AUDIO_PLUG','android.intent.action.USB_AUDIO_ACCESSORY_PLUG','android.intent.action.USB_AUDIO_DEVICE_PLUG','android.net.conn.CONNECTIVITY_CHANGE','android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE','android.net.conn.DATA_ACTIVITY_CHANGE','android.net.conn.BACKGROUND_DATA_SETTING_CHANGED','android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED','android.nfc.action.LLCP_LINK_STATE_CHANGED','com.android.nfc_extras.action.RF_FIELD_ON_DETECTED','com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED','com.android.nfc_extras.action.AID_SELECTED','android.nfc.action.TRANSACTION_DETECTED','android.intent.action.CLEAR_DNS_CACHE','android.intent.action.PROXY_CHANGE','android.os.UpdateLock.UPDATE_LOCK_CHANGED','android.intent.action.DREAMING_STARTED','android.intent.action.DREAMING_STOPPED','android.intent.action.ANY_DATA_STATE','com.android.server.WifiManager.action.START_SCAN','com.android.server.WifiManager.action.DELAYED_DRIVER_STOP','android.net.wifi.WIFI_STATE_CHANGED','android.net.wifi.WIFI_AP_STATE_CHANGED','android.net.wifi.WIFI_SCAN_AVAILABLE','android.net.wifi.SCAN_RESULTS','android.net.wifi.RSSI_CHANGED','android.net.wifi.STATE_CHANGE','android.net.wifi.LINK_CONFIGURATION_CHANGED','android.net.wifi.CONFIGURED_NETWORKS_CHANGE','android.net.wifi.supplicant.CONNECTION_CHANGE','android.net.wifi.supplicant.STATE_CHANGE','android.net.wifi.p2p.STATE_CHANGED','android.net.wifi.p2p.DISCOVERY_STATE_CHANGE','android.net.wifi.p2p.THIS_DEVICE_CHANGED','android.net.wifi.p2p.PEERS_CHANGED','android.net.wifi.p2p.CONNECTION_STATE_CHANGE','android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED','android.net.conn.TETHER_STATE_CHANGED','android.net.conn.INET_CONDITION_ACTION','android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE','android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE','android.intent.action.AIRPLANE_MODE','android.intent.action.ADVANCED_SETTINGS','android.intent.action.BUGREPORT_FINISHED','android.intent.action.ACTION_IDLE_MAINTENANCE_START','android.intent.action.ACTION_IDLE_MAINTENANCE_END','android.intent.action.SERVICE_STATE','android.intent.action.RADIO_TECHNOLOGY','android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED','android.intent.action.SIG_STR','android.intent.action.ANY_DATA_STATE','android.intent.action.DATA_CONNECTION_FAILED','android.intent.action.SIM_STATE_CHANGED','android.intent.action.NETWORK_SET_TIME','android.intent.action.NETWORK_SET_TIMEZONE','android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS','android.intent.action.ACTION_MDN_STATE_CHANGED','android.provider.Telephony.SPN_STRINGS_UPDATED','android.provider.Telephony.SIM_FULL','com.android.internal.telephony.data-restart-trysetup','com.android.internal.telephony.data-stall'] for node in xmldoc.getElementsByTagName(tag): if 'android:exported' in node.attributes.keys(): @@ -858,6 +887,20 @@ def print_terminal(objectlist): else: logger.debug("Not a valid type of object in terminalPrint extras") +def get_entry_for_component(comp_type): + if comp_type == 'activity': + entry = ['onCreate', 'onStart'] + elif comp_type == 'activity-alias': + entry = ['onCreate', 'onStart'] + elif comp_type == 'receiver': + entry = ['onReceive'] + elif comp_type == 'service': + entry = ['onCreate', 'onBind', 'onStartCommand', 'onHandleIntent'] + #TODO - The provider is a unicorn and needs more work + elif comp_type == 'provider': + entry = ['onReceive'] + return entry + class ReportIssue(): category = "" severity = "" diff --git a/modules/contentProvider.py b/modules/contentProvider.py index a5de7ffe..0b4df81d 100644 --- a/modules/contentProvider.py +++ b/modules/contentProvider.py @@ -76,7 +76,7 @@ def find_content_providers(): tmp_list2=common.dedup(tmp_list2) return tmp_list2 -def contentProviderUriPermissions(): +def content_provider_uri_permissions(): cpName="" #TODO - Need to rectify this with the exported/non-exported providers for node in common.xmldoc.getElementsByTagName('provider'): diff --git a/modules/createSploit.py b/modules/createSploit.py index dff5e07a..9d41e54d 100644 --- a/modules/createSploit.py +++ b/modules/createSploit.py @@ -19,7 +19,7 @@ class exploitType: MANIFEST, ACTIVITY, INTENT, PERMISSION, SERVICE, RECEIVER, BROADCAST_INTENT = range(7) -def copyTemplate(src,dest): +def copy_template(src,dest): """ Given a source and destination, copy all files/folders under source to destination\n Overwrites destination if any files/folders already exists\n @@ -36,17 +36,9 @@ def copyTemplate(src,dest): print('Directory not copied. Error: %s' % e) #TODO - give an option to specify a different dir, if the specified one already exists status='ERROR' - return status - -def addVulnerable(obj,key,value): - """ - Common method to add a new vulnerability\n - Takes common.exploitdata as the object, exploitType enum, string representation of the vulnerable code to be replaced in the exploit template - """ - obj[key].append(value) - + return status -def modifyTemplate(path,filename,temp_text,repl_text): +def modify_template(path,filename,temp_text,repl_text): """ Deprecated code """ @@ -64,7 +56,7 @@ def modifyTemplate(path,filename,temp_text,repl_text): os.rename(tmp2,tmp) return -def modifyTemplate2(filename,placeholder,replacement): +def modify_template_2(filename,placeholder,replacement): """ Takes a filename,placeholder value to be replaced and the actual replacement value\n Uncomments the commented out code from exploit template, replaces the placeholder with actual value and adds this content on the next line to facilitate multiple substitutions @@ -79,34 +71,4 @@ def modifyTemplate2(filename,placeholder,replacement): print line, if flag: print line1.replace(placeholder, replacement), - flag=False - -def createUsing(replacementData): - """ - Core of the exploit generation\n - Takes in a dictionary with (exploittype,replacement value) data, processes them to find all substitutions, and looks up the config.properties to identify all applicable files that require substution - """ - path = common.getConfig("rootDir") + '/build/qark' - data = dict(replacementData) - for key,value in data.iteritems(): - if key==exploitType.BROADCAST_INTENT: - exploit_type="BROADCAST_INTENT" - elif key==exploitType.ACTIVITY: - exploit_type="ACTIVITY" - elif key==exploitType.INTENT: - exploit_type="INTENT" - elif key==exploitType.MANIFEST: - exploit_type="MANIFEST" - elif key==exploitType.PERMISSION: - exploit_type="PERMISSION" - elif key==exploitType.RECEIVER: - exploit_type="RECEIVER" - elif key==exploitType.SERVICE: - exploit_type="SERVICE" - for instance in value: - replacement_keys = dict(common.config.items('exploit')) - for type_key,type_value in replacement_keys.iteritems(): - if exploit_type in str(type_key).upper(): - replacement_files = dict(common.config.items(type_value)) - for file_key,file_value in replacement_files.iteritems(): - modifyTemplate2(path + file_value, type_value, instance) \ No newline at end of file + flag=False \ No newline at end of file diff --git a/modules/cryptoFlaws.py b/modules/cryptoFlaws.py index baff1346..ec0055a3 100644 --- a/modules/cryptoFlaws.py +++ b/modules/cryptoFlaws.py @@ -27,8 +27,8 @@ def main(queue): count = 0 if common.minSdkVersion<19: - weakRngWarning(results) - findKeyFiles(results) + weak_rng_warning(results) + find_key_files(results) for j in common.java_files: count = count + 1 pub.sendMessage('progress', count6=round(count*100/common.java_files.__len__())) @@ -41,11 +41,11 @@ def main(queue): if type(type_decl) is m.ClassDeclaration: for t in type_decl.body: try: - recursiveEcbCheck(t,j,results) + recursive_ecb_check(t,j,results) #fixedSeedCheck(t,j) except Exception as e: - common.logger.debug("Error running recursiveEcbCheck in cryptoFlaws.py: " + str(e)) - report.write("parsingerror-issues-list", "Error running recursiveEcbCheck in cryptoFlaws.py: " + str(e), "strong") + common.logger.debug("Error running recursive_ecb_check in cryptoFlaws.py: " + str(e)) + report.write("parsingerror-issues-list", "Error running recursive_ecb_check in cryptoFlaws.py: " + str(e), "strong") except Exception as e: common.logger.debug("Unable to create tree for " + str(j)) @@ -53,13 +53,13 @@ def main(queue): queue.put(results) return -def weakRngWarning(results): +def weak_rng_warning(results): #TODO - check for any actual use of RNG #common.logger.warning("Key generation, signing, encryption, and random number generation may not receive cryptographically strong values due to improper initialization of the underlying PRNG on Android 4.3 (API level 18) and below. If your application relies on cryptographically secure random number generation you should apply the workaround described in https://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.htm. More information: https://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html") return ''' #TODO - Need to finish this -def fixedSeedCheck(t,filename): +def fixed_seed_check(t,filename): SecureRandom ------------ Summary: Using a fixed seed with SecureRandom @@ -95,7 +95,7 @@ def fixedSeedCheck(t,filename): #raw_input("T: " + str(t)) return ''' -def recursiveEcbCheck(t,filename,results): +def recursive_ecb_check(t,filename,results): #TODO - review this for thoroughness #TODO - need to verify .getInstance is actually being invoked on a Cipher object #TODO - we could whittle down the possibilities by checking the imports as well @@ -139,10 +139,10 @@ def recursiveEcbCheck(t,filename,results): if type(t) is list: for l in t: - recursiveEcbCheck(l,filename, results) + recursive_ecb_check(l,filename, results) elif hasattr(t,'_fields'): for f in t._fields: - recursiveEcbCheck(getattr(t,f),filename,results) + recursive_ecb_check(getattr(t,f),filename,results) ''' GetInstance @@ -159,7 +159,7 @@ def recursiveEcbCheck(t,filename,results): return -def findKeyFiles(results): +def find_key_files(results): ''' PackagedPrivateKey ------------------ Summary: Packaged private key diff --git a/modules/exportedPreferenceActivity.py b/modules/exportedPreferenceActivity.py index 7a773753..7b7219d5 100644 --- a/modules/exportedPreferenceActivity.py +++ b/modules/exportedPreferenceActivity.py @@ -22,19 +22,19 @@ def main(): #Do I need to add a minSdkVersion check here? if ((len(act_exp_list)>0) or (len(act_exp_perm_list>1)) or (len(act_prot_broad_list>0))): - findPreferenceActivity() + find_preference_activity() if len(act_exp_list)>0: - if lookForFile(act_exp_list): + if look_for_file(act_exp_list): common.logger.error("This application is vulnerable to a potentially serious type of reflection issue, detailed here: http://securityintelligence.com/new-vulnerability-android-framework-fragment-injection. Unfortunately, we are still working on an automated exploit for this.") if len(act_exp_perm_list)>1: - if lookForFile(act_exp_perm_list): + if look_for_file(act_exp_perm_list): common.logger.error("This application is vulnerable to a potentially serious type of reflection issue, detailed here: http://securityintelligence.com/new-vulnerability-android-framework-fragment-injection. Unfortunately, we are still working on an automated exploit for this.") if len(act_prot_broad_list)>0: - if lookForFile(act_prot_broad_list): + if look_for_file(act_prot_broad_list): common.logger.error("This application is vulnerable to a potentially serious type of reflection issue, detailed here: http://securityintelligence.com/new-vulnerability-android-framework-fragment-injection. Unfortunately, we are still working on an automated exploit for this.") return -def lookForFile(act_list): +def look_for_file(act_list): global preferenceClasses vuln=False @@ -44,7 +44,7 @@ def lookForFile(act_list): vuln=True return vuln -def findPreferenceActivity(): +def find_preference_activity(): global parser global preferenceClasses @@ -67,6 +67,6 @@ def findPreferenceActivity(): preferenceClasses.append(str(type_decl.name)) #Trying to be recursive here, so extensions of extensions, etc are found, might require more refinement if len(preferenceClasses)>init_len_pc: - findPreferenceActivity() + find_preference_activity() return \ No newline at end of file diff --git a/modules/externalMethodDeclarations.py b/modules/externalMethodDeclarations.py index a27d61bd..2e51074c 100644 --- a/modules/externalMethodDeclarations.py +++ b/modules/externalMethodDeclarations.py @@ -61,21 +61,21 @@ def main(token,tree,current_file): if type(type_decl) is m.ClassDeclaration: for t in type_decl.body: try: - recursiveMethodFinder(t,token) + recursive_method_finder(t,token) except Exception as e: - common.logger.error("Problem running recursiveMethodFinder for m.ClassDeclaration in externalMethodDeclarations.py: " + str(e)) + common.logger.error("Problem running recursive_method_finder for m.ClassDeclaration in externalMethodDeclarations.py: " + str(e)) elif type(type_decl) is list: for y in t: try: - recursiveMethodFinder(y,token) + recursive_method_finder(y,token) except Exception as e: - common.logger.error("Problem running recursiveMethodFinder for lists in externalMethodDeclarations.py: " + str(e)) + common.logger.error("Problem running recursive_method_finder for lists in externalMethodDeclarations.py: " + str(e)) elif hasattr(t,'_fields'): for f in t._fields: try: - recursiveMethodFinder(getattr(t,f),token) + recursive_method_finder(getattr(t,f),token) except Exception as e: - common.logger.error("Problem running recursiveMethodFinder for _fields in externalMethodDeclarations.py: " + str(e)) + common.logger.error("Problem running recursive_method_finder for _fields in externalMethodDeclarations.py: " + str(e)) else: common.logger.error("There was a problem reading the imported class: " + str(classFile) + ". Results may be negatively impacted if the class contains security relevant methods. This may be due to a de-compilation error.") continue @@ -95,7 +95,7 @@ def main(token,tree,current_file): else: break if numMatches>0: - processMatches(token,tree) + process_matches(token,tree) else: if common.source_or_apk==1: common.parsingerrors.add(str(current_file)) @@ -105,7 +105,7 @@ def main(token,tree,current_file): common.logger.debug("Unable to locate the definition of the " + str(token.name)+" method from the imports in "+str(current_file)+". This will negatively impact results if this is not part of the standard Java/Android libraries and is a security relevant method. We are still working on ignoring safe standard methods. Please check back for updates or contribute your own code.") return -def recursiveMethodFinder(t,token): +def recursive_method_finder(t,token): ''' Looks for any locally declared methods. All entry points should be captured in this list ''' @@ -130,54 +130,54 @@ def recursiveMethodFinder(t,token): thorough=False numMatches+=1 except Exception as e: - common.logger.error("Problem during parameter type matching in externalMethodDeclaration.py's recursiveMethodFinder method: " + str(e)) + common.logger.error("Problem during parameter type matching in externalMethodDeclaration.py's recursive_method_finder method: " + str(e)) except Exception as e: - common.logger.error("Problem in recursiveMethodFinder, trying to traverse m.MethodDeclaration: " + str(e)) + common.logger.error("Problem in recursive_method_finder, trying to traverse m.MethodDeclaration: " + str(e)) elif type(t) is list: try: for i in t: if type(i) is m.MethodDeclaration: - recursiveMethodFinder(i,token) + recursive_method_finder(i,token) elif type(i) is list: for y in i: - recursiveMethodFinder(i,token) + recursive_method_finder(i,token) elif hasattr(i,'_fields'): try: for z in i._fields: - recursiveMethodFinder(getattr(i,z),token) + recursive_method_finder(getattr(i,z),token) except Exception as e: - common.logger.error("Problem in recursiveMethodFinder, trying to iterate fields on list branch: " + str(e)) + common.logger.error("Problem in recursive_method_finder, trying to iterate fields on list branch: " + str(e)) except Exception as e: - common.logger.error("Problem in recursiveMethodFinder, trying to traverse list: " + str(e)) + common.logger.error("Problem in recursive_method_finder, trying to traverse list: " + str(e)) elif hasattr(t,'_fields'): try: for f in t._fields: - recursiveMethodFinder(getattr(t,f),token) + recursive_method_finder(getattr(t,f),token) except Exception as e: - common.logger.error("Problem in recursiveMethodFinder, trying to iterate over fields: " + str(e)) + common.logger.error("Problem in recursive_method_finder, trying to iterate over fields: " + str(e)) return -def processMatches(token,tree): +def process_matches(token,tree): global numMatches global thorough try: if thorough: common.logger.debug("Located method declaration for: " + str(token.name)) - sinksEncountered(token,tree) + sinks_encountered(token,tree) elif numMatches==1: common.logger.info("Only one match was found for this method: " + str(token.name)+",but cannot be confirmed 100% accurate.") - sinksEncountered(token,tree) + sinks_encountered(token,tree) else: common.logger.warning("A number of potentially matching method declarations were found for : " + str(token.name)+". QARK cannot currently provide a 100% positive match, so false positives could arise from this.") - sinksEncountered(token,tree) + sinks_encountered(token,tree) except Exception as e: - common.logger.error("Problem running sinksEncountered in externalMethodDeclarations.py: " + str(e)) + common.logger.error("Problem running sinks_encountered in externalMethodDeclarations.py: " + str(e)) numMatches=0 thorough=False return -def sinksEncountered(token,tree): +def sinks_encountered(token,tree): found=False for type_decl in tree.type_declarations: if type(type_decl) is m.ClassDeclaration: @@ -188,10 +188,10 @@ def sinksEncountered(token,tree): found=common.sink_list_check(token,tree) elif type(type_decl) is list: for l in type_decl: - sinksEncountered(type_decl,tree) + sinks_encountered(type_decl,tree) elif hasattr(type_decl,'_fields'): for f in type_decl._fields: - sinksEncountered(getattr(type_decl,f),tree) + sinks_encountered(getattr(type_decl,f),tree) if found: common.logger.log(common.VULNERABILITY_LEVEL,"It appears a vulnerablity was found here, but unfortunately we haven't completed this branch yet.") # raw_input() diff --git a/modules/findBoundServices.py b/modules/findBoundServices.py index 93b6e666..fbabc656 100644 --- a/modules/findBoundServices.py +++ b/modules/findBoundServices.py @@ -25,7 +25,7 @@ def main(t,tree): targetName=b.result.target.value print "B Target: " + str(b.result.target) raw_input() - whatIsThis(targetName,tree) + what_is_this(targetName,tree) elif type(b.result) is list: for l in b.result: if type(l) is m.MethodInvocation: @@ -37,7 +37,7 @@ def main(t,tree): targetName=l.result.target.value print "L Target: " + str(l.result.target) raw_input() - whatIsThis(targetName,tree) + what_is_this(targetName,tree) elif hasattr(b.result,'_fields'): for f in b.result._fields: if type(f) is m.MethodInvocation: @@ -49,11 +49,11 @@ def main(t,tree): print "F Target: " + str(f.result.target) if hasattr(f.result.target,'value'): targetName=f.result.target.value - whatIsThis(targetName,tree) + what_is_this(targetName,tree) raw_input() return -def whatIsThis(targetName,tree): +def what_is_this(targetName,tree): for x in tree.body: if type(x) is m.VariableDeclaration: print "X: " + str(x) diff --git a/modules/findBroadcasts.py b/modules/findBroadcasts.py index 408edaf4..2510b646 100644 --- a/modules/findBroadcasts.py +++ b/modules/findBroadcasts.py @@ -45,16 +45,16 @@ def main(queue): if type(type_decl) is m.ClassDeclaration: for t in type_decl.body: try: - recursiveBroadcastFinder(t,results) + recursive_broadcast_finder(t,results) except Exception as e: common.parsingerrors.add(str(j)) - common.logger.debug("Unable to process recursiveBroadcastFinder in findBroadcasts.py: " + str(e)) + common.logger.debug("Unable to process recursive_broadcast_finder in findBroadcasts.py: " + str(e)) elif type(type_decl) is list: for y in type_decl: - recursiveBroadcastFinder(y,results) + recursive_broadcast_finder(y,results) elif hasattr(type_decl,'_fields'): for d in type_decl._fields: - recursiveBroadcastFinder(getattr(type_decl,d),results) + recursive_broadcast_finder(getattr(type_decl,d),results) else: common.logger.debug("Unable to create tree for " + str(j)) except Exception as e: @@ -63,7 +63,7 @@ def main(queue): queue.put(results) return -def localBroadcastManagerImported(): +def local_broadcast_manager_imported(): ''' Need to ensure sendBroadcast is not the method from LocalBroadcastManager, which is not insecure ''' @@ -87,7 +87,7 @@ def localBroadcastManagerImported(): return importFound -def recursiveBroadcastFinder(t,results): +def recursive_broadcast_finder(t,results): if type(t) is m.MethodDeclaration: if str(t.name) == 'sendBroadcast': @@ -111,7 +111,7 @@ def recursiveBroadcastFinder(t,results): if len(t.arguments)==1: #We need to ensure this isn't a local broadcast #TODO - There is a lot more we need to do to fully qualify this, but should be good enough for now - if localBroadcastManagerImported()==True: + if local_broadcast_manager_imported()==True: common.logger.debug(tree) else: report.write_badger("manifest-issues", modules.common.Severity.INFO, "NO IMPORT") @@ -293,12 +293,12 @@ def recursiveBroadcastFinder(t,results): results.append(issue) elif hasattr(t,'_fields'): for g in t._fields: - recursiveBroadcastFinder(getattr(t,g),results) + recursive_broadcast_finder(getattr(t,g),results) elif type(t) is list: for l in t: - recursiveBroadcastFinder(l,results) + recursive_broadcast_finder(l,results) elif hasattr(t,'_fields'): for f in t._fields: if type(getattr(t,f)) is not str: - recursiveBroadcastFinder(getattr(t,f),results) + recursive_broadcast_finder(getattr(t,f),results) return diff --git a/modules/findMethods.py b/modules/findMethods.py index b25952b8..c84742e2 100644 --- a/modules/findMethods.py +++ b/modules/findMethods.py @@ -9,6 +9,7 @@ from modules import common from modules import filters from modules import findBoundServices +from modules import findExtras import lib.plyj.model as m import re, sys import logging @@ -16,6 +17,7 @@ from modules.common import ReportIssue, Severity from modules.createExploit import ExploitType from modules import report +from modules import findSupers parser = plyj.Parser() tracker = [] @@ -80,7 +82,7 @@ def tree_parser(j, comp_type): else: common.logger.info("Checking this file for vulns: " + str(j)) try: - findLocalMethodDeclarations(tree) + find_local_method_declarations(tree) find_entry(tree, comp_type) except Exception as e: if common.source_or_apk == 2: @@ -90,42 +92,42 @@ def tree_parser(j, comp_type): return -def findLocalMethodDeclarations(tree): +def find_local_method_declarations(tree): ''' - Iterates over tree passing each object to recursiveMethodFinder + Iterates over tree passing each object to recursive_method_finder ''' global component_type if tree is None: - common.logger.error("Tree type is None for findLocalMethodDeclarations in findMethods.py") + common.logger.error("Tree type is None for find_local_method_declarations in findMethods.py") else: try: #TODO - verify the other branches are needed here, is m.ClassDeclaration check enough? for type_decl in tree.type_declarations: if type(type_decl) is m.ClassDeclaration: for t in type_decl.body: - recursiveMethodFinder(t) + recursive_method_finder(t) #possibly redundant if str(component_type) == 'activity': - findSetResult(t) + find_set_result(t) elif type(type_decl) is list: for y in t: - recursiveMethodFinder(y) + recursive_method_finder(y) #possibly redundant if str(component_type) == 'activity': - findSetResult(y) + find_set_result(y) elif hasattr(t, '_fields'): for f in t._fields: - recursiveMethodFinder(getattr(t, f)) + recursive_method_finder(getattr(t, f)) #possibly redundant if str(component_type) == 'activity': - findSetResult(f) + find_set_result(f) except Exception as e: - common.logger.error("Problem with findLocalMethodDeclarations in findMethods.py: " + str(e)) + common.logger.error("Problem with find_local_method_declarations in findMethods.py: " + str(e)) return -def recursiveMethodFinder(t): +def recursive_method_finder(t): ''' Looks for any locally declared methods. All entry points should be captured in this list ''' @@ -145,10 +147,10 @@ def recursiveMethodFinder(t): local_meth_decls.append(i.name) elif type(i) is list: for y in i: - recursiveMethodFinder(i) + recursive_method_finder(i) elif hasattr(t, '_fields'): for f in t._fields: - recursiveMethodFinder(getattr(t, f)) + recursive_method_finder(getattr(t, f)) return @@ -161,10 +163,11 @@ def find_entry(tree, comp_type): try: #Create list of entry points, based on component type + ''' if comp_type == 'activity': - entry = ['onCreate', 'onResume', 'onStart'] + entry = ['onCreate', 'onStart'] elif comp_type == 'activity-alias': - entry = ['onCreate', 'onResume', 'onStart'] + entry = ['onCreate', 'onStart'] elif comp_type == 'receiver': entry = ['onReceive'] elif comp_type == 'service': @@ -172,6 +175,8 @@ def find_entry(tree, comp_type): #TODO - The provider is a unicorn and needs more work elif comp_type == 'provider': entry = ['onReceive'] + ''' + entry=common.get_entry_for_component(comp_type) #Search the tree to see if there is a matching entry point if tree is not None: for type_decl in tree.type_declarations: @@ -185,11 +190,13 @@ def find_entry(tree, comp_type): if str(t.name) == str(e): common.logger.debug("--Found entry point: " + str(t.name)) entries.append(str(e)) - '''try: + ''' + try: if str(t.name)=='onBind': findBoundServices.main(t,tree) except Exception as e: - common.logger.error("Error in findMethods.py trying to trace bound service: " + str(e))''' + common.logger.error("Error in findMethods.py trying to trace bound service: " + str(e)) + ''' if hasattr(t, 'parameters'): for p in t.parameters: if hasattr(p, 'type'): @@ -200,6 +207,7 @@ def find_entry(tree, comp_type): print "entries: " for q in entries: print str(q) + findExtras.find_extras(current_file,q) if len(entries) < 1: if ((comp_type == 'activity') or (comp_type == 'activity-alias')): common.logger.debug("This may be a fragment") @@ -234,6 +242,7 @@ def walk_the_class_from_entry(tree, entries, comp_type): if t.name == str(e): track(None, True) if type(t.body) is list: + #print "T.BODY: " + str(t.body) for b in t.body: token_mapper(b) else: @@ -241,7 +250,7 @@ def walk_the_class_from_entry(tree, entries, comp_type): return -def findSetResult(t): +def find_set_result(t): global component_type #This is used to find if the incoming triggering this Activity is going to cause data to be returned #TODO - it would be nicer if we actually tracked the flow, but since the exploit APK already parses returned data, it really doesn't matter @@ -252,21 +261,21 @@ def findSetResult(t): return True elif hasattr(t, '_fields'): for y in t._fields: - findSetResult(getattr(t, y)) + find_set_result(getattr(t, y)) elif type(t) is list: for i in t: if type(i) is m.MethodInvocation: - findSetResult(i) + find_set_result(i) elif type(i) is list: for j in i: - findSetResult(j) + find_set_result(j) elif hasattr(i, '_fields'): for k in i._fields: - findSetResult(getattr(i, k)) + find_set_result(getattr(i, k)) #Need to add has fields elif hasattr(t, '_fields'): for x in t._fields: - findSetResult(getattr(t, x)) + find_set_result(getattr(t, x)) else: return False @@ -277,103 +286,247 @@ def token_mapper(token): """ try: if type(token) is m.FieldDeclaration: - parseFieldDeclaration(token) + try: + parse_field_declaration(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.MethodInvocation: - parseMethodInvocation(token) + try: + parse_method_invocation(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.VariableDeclaration: - parseVariableDeclaration(token) + try: + parse_variable_declaration(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.VariableDeclarator: - parseVariableDeclarator(token) + try: + parse_variable_declarator(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.MethodDeclaration: - parseMethodDeclaration(token) + try: + parse_method_declaration(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.ClassInitializer: - parseClassInitializer(token) + try: + parse_class_initializer(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.ConstructorDeclaration: - parseConstructorDeclaration(token) + try: + parse_constructor_declaration(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.EnumDeclaration: - parseEnumDeclaration(token) + try: + parse_enum_declaration(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.InterfaceDeclaration: - parseInterfaceDeclaration(token) + try: + parse_interface_declaration(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.ExpressionStatement: - parseExpressionStatement(token) + try: + parse_expression_statement(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.IfThenElse: - parseIfThenElse(token) + try: + parse_if_then_else(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Return: - parseReturn(token) + try: + parse_return(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Try: - parseTry(token) + try: + parse_try(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Catch: - parseCatch(token) + try: + parse_catch(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.ForEach: - parseForEach(token) + try: + parse_for_each(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.For: - parseFor(token) + try: + parse_for(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Switch: - parseSwitch(token) + try: + parse_switch(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.SwitchCase: - parseSwitchCase(token) + try: + parse_switch_case(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Block: - parseBlock(token) + try: + parse_block(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Synchronized: - parseSynchronized(token) + try: + parse_synchronized(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Variable: - parseVariable(token) + try: + parse_variable(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.EmptyDeclaration: common.logger.debug("OOPS - EmptyDeclaration: " + str(type(token))) elif type(token) is type(None): - parseNone() + try: + parse_none() + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.ClassDeclaration: - parseClassDeclaration(token) + try: + parse_class_declaration(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Assignment: - parseAssignment(token) + try: + parse_assignment(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Literal: - parseLiteral(token) + try: + parse_literal(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.ClassLiteral: - parseClassLiteral(token) + try: + parse_class_literal(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.InstanceCreation: - parseInstanceCreation(token) + try: + parse_instance_creation(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Cast: - parseCast(token) + try: + parse_cast(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Unary: - parseUnary(token) + try: + parse_unary(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Additive: - parseAdditive(token) + try: + parse_additive(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Type: - parseType(token) + try: + parse_type(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Equality: - parseEquality(token) + try: + parse_equality(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.ConditionalAnd: - parseConditionalAnd(token) + try: + parse_conditional_and(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Conditional: - parseConditional(token) + try: + parse_conditional(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.ArrayCreation: - parseArrayCreation(token) + try: + parse_array_creation(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.While: - parseWhile(token) + try: + parse_while(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is bool: - parseBool(token) + try: + parse_bool(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Break: - parseBreak(token) + try: + parse_break(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.ArrayInitializer: - parseArrayInitializer(token) + try: + parse_array_initializer(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Annotation: - parseAnnotation(token) + try: + parse_annotation(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.FormalParameter: - parseFormalParameter(token) + try: + parse_formal_parameter(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.ConditionalOr: - parseConditionalOr(token) + try: + parse_conditional_or(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Wildcard: - parseWildcard(token) + try: + parse_wildcard(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is str: - parseString(token) + try: + parse_string(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is int: - parseInt(token) + try: + parse_int(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Relational: - parseRelational(token) + try: + parse_relational(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.Name: - parseName(token) + try: + parse_name(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) elif type(token) is m.FieldAccess: - parseFieldAccess(token) + try: + parse_field_access(token) + except Exception as e: + common.logger.error("Problem in findMethods.py parsing token type: " + str(type(token)) + ". " +str(e)) else: common.logger.debug("NOT COVERED IN TOKEN MAPPER: ") common.logger.debug(type(token)) @@ -422,7 +575,7 @@ def wtf_is(token): return token_type -def isGlobal(token): +def is_global(token): """ Checks if a given token is global in context """ @@ -438,24 +591,27 @@ def isGlobal(token): return foundglobal -def genericTainted(token, tainted): +def generic_tainted(token, tainted): + ''' + Finds whether any generic object is tainted + ''' global taint_list if hasattr(token, '_fields'): for f in token._fields: try: - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): tainted = True if str(token) not in taint_list: common.logger.debug("TAINTED " + str(type(token)) + ": " + str(token)) except Exception as e: - common.logger.error("Problem calling isTainted, from genericTainted in findMethods.py: " + str(e)) + common.logger.error("Problem calling is_tainted, from generic_tainted in findMethods.py: " + str(e)) return tainted -def isTainted(token): +def is_tainted(token): """ - Identifies if a given token is tainted or now + Identifies if a given token is tainted or not """ tainted = False global taint_list @@ -464,7 +620,7 @@ def isTainted(token): if hasattr(token, '_fields'): for f in token._fields: if hasattr(token, str(f)): - if isTainted(getattr(token, str(f))): + if is_tainted(getattr(token, str(f))): tainted = True if str(token) not in taint_list: if type(token.lhs) is m.FieldAccess: @@ -475,12 +631,12 @@ def isTainted(token): elif type(token.lhs.value) is str: if str(token.lhs.value) not in taint_list: taint_list.append(str(token.lhs.value)) - isGlobal(token.lhs.value) + is_global(token.lhs.value) else: common.logger.debug("Token already in taint_list : " + str(token)) elif type(token) is m.MethodInvocation: for f in token._fields: - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): tainted = True if str(f) == 'arguments': if hasattr(token.target, 'value'): @@ -488,7 +644,7 @@ def isTainted(token): #TODO - Verify the class for the package found actually is imported by this class elif type(token) is m.VariableDeclaration: for f in token._fields: - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): tainted = True if str(token) not in taint_list: for v in token.variable_declarators: @@ -500,7 +656,7 @@ def isTainted(token): elif type(token) is type(None): #no-op - parseNone() + parse_none() elif type(token) is str: for t in taint_list: @@ -511,19 +667,19 @@ def isTainted(token): track(None, True) elif type(token) is int: - parseInt(token) + parse_int(token) elif type(token) is list: for x in token: - tainted = genericTainted(x, tainted) + tainted = generic_tainted(x, tainted) elif type(token) is bool: - parseBool(token) + parse_bool(token) else: - tainted = genericTainted(token, tainted) + tainted = generic_tainted(token, tainted) except Exception as e: - common.logger.error("Problem with isTainted method in findMethods.py: " + str(e)) + common.logger.error("Problem with is_tainted method in findMethods.py: " + str(e)) return tainted def tainted_sink_processor(sink, token): @@ -672,6 +828,11 @@ def tainted_sink_processor(sink, token): #final_sink.append(['android.content.ContentResolver','android.database.Cursor','query',['android.net.Uri','java.lang.String[]'','java.lang.String','java.lang.String[]'','java.lang.String','android.os.CancellationSignal']]) #final_sink.append(['java.lang.ProcessBuilder','java.lang.Process','start',[]'] final_sink.append(['android.app.NotificationManager', 'void', 'notify', ['int', 'android.app.Notification']]) + #Not in SOOT SINK LIST + final_sink.append(['android.webkit.WebView','void','loadUrl',['java.lang.String']]) + #The second param is java.util.Map + final_sink.append(['android.webkit.WebView','void','loadUrl',['java.lang.String','java.util.Map']]) + #STUFF THAT GETS TAINTED intermediate_sink = [] @@ -913,7 +1074,7 @@ def import_checker(imp, token, method, argslength): #Need to figure out what the type of the tainting object is, so that we can see what parameters are passed in token_type = wtf_is(a.target.value) - extras = extras_for_attack(token_type, a) + extras = findExtras.extras_for_attack(token_type, a) common.logger.log(common.VULNERABILITY_LEVEL, "To exploit, you will need to send an intent with the key: " + str( extras[1]) + " of type: " + str(re.sub(r'get', '', extras[0]))) @@ -934,84 +1095,6 @@ def import_checker(imp, token, method, argslength): common.logger.warning("Uncategorized Vulnerability: " + str(token)) return confirmed - -def extras_for_attack(token_type, method): - """ - Identifies any extras to be included in the exploit app - """ - bundle_extras = [] - bundle_extras.append("get") - bundle_extras.append("getBoolean") - bundle_extras.append("getBooleanArray") - bundle_extras.append("getDouble") - bundle_extras.append("getDoubleArray") - #TODO - more than one - bundle_extras.append("getInt") - bundle_extras.append("getIntArray") - bundle_extras.append("getLong") - bundle_extras.append("getLongArray") - #TODO - more than one - bundle_extras.append("getString") - bundle_extras.append("getStringArray") - bundle_extras.append("getIntArray") - - intent_extras = [] - intent_extras.append("getBooleanArrayExtra") - intent_extras.append("getBundleExtra") - intent_extras.append("getByteArrayExtra") - intent_extras.append("getByteExtra") - intent_extras.append("getCharArrayExtra") - intent_extras.append("getCharExtra") - intent_extras.append("getCharSequenceArrayExtra") - intent_extras.append("getCharSequenceArrayListExtra") - intent_extras.append("getCharSequenceExtra") - intent_extras.append("getDoubleArrayExtra") - intent_extras.append("getDoubleExtra") - intent_extras.append("getExtras") - intent_extras.append("getFloatArrayExtra") - intent_extras.append("getFloatExtra") - intent_extras.append("getIntArrayExtra") - intent_extras.append("getIntExtra") - intent_extras.append("getIntegerArrayListExtra") - intent_extras.append("getLongArrayExtra") - intent_extras.append("getLongExtra") - intent_extras.append("getParcelableArrayExtra") - intent_extras.append("getParcelableArrayListExtra") - intent_extras.append("getParcelableExtra") - intent_extras.append("getSerializableExtra") - intent_extras.append("getShortArrayExtra") - intent_extras.append("getShortExtra") - intent_extras.append("getStringArrayExtra") - intent_extras.append("getStringArrayListExtra") - intent_extras.append("getStringExtra") - - #TODO - Need to deal with non-Extra data pulled from intents - - extra = [] - - if str(token_type) == "Bundle": - for b in bundle_extras: - if str(b) == str(method.name): - if str(b) not in extra: - extra.append(str(b)) - for a in method.arguments: - if type(a) is m.Literal: - if str(a.value) not in extra: - extra.append(a.value) - elif str(token_type) == "Intent": - for i in intent_extras: - if str(i) == str(method.name): - if str(i) not in extra: - extra.append(str(i)) - for a in method.arguments: - if type(a) is m.Literal: - if str(a.value) not in extra: - extra.append(a.value) - else: - pass - return extra - - def obj_instance_of(token): """ Identifies the class of token @@ -1069,7 +1152,7 @@ def list_checker(token, q): common.logger.error("Problem with list parsing in list_checker method of findMethods.py: " + str(e)) else: try: - if isTainted(token): + if is_tainted(token): tainted = True try: check = getattr(token, str(q)) @@ -1078,7 +1161,7 @@ def list_checker(token, q): if type(check) is list: tainted = list_checker(token, check) else: - if isTainted(check): + if is_tainted(check): tainted = True token_mapper(check) except Exception as e: @@ -1089,9 +1172,9 @@ def list_checker(token, q): return tainted -def parseExpressionStatement(token): +def parse_expression_statement(token): """ - Parse toke type - statement + Parse token type - statement """ try: track(token.expression, False) @@ -1099,57 +1182,57 @@ def parseExpressionStatement(token): for t in token._fields: list_checker(token, t) except Exception as e: - common.logger.error("Problem with parseExpressionStatement in findMethods.py: " + str(e)) + common.logger.error("Problem with parse_expression_statement in findMethods.py: " + str(e)) return -def parseClassLiteral(token): +def parse_class_literal(token): """ - Parse toke type - literal + Parse token type - literal """ try: track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): common.logger.debug("TAINTED: " + str(token)) except Exception as e: - common.logger.error("Problem with parseClassLiteral in findMethods.py: " + str(e)) + common.logger.error("Problem with parse_class_literal in findMethods.py: " + str(e)) return -def parseRelational(token): +def parse_relational(token): """ - Parse toke type - relational + Parse token type - relational """ try: track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): common.logger.debug("TAINTED: " + str(token)) except Exception as e: - common.logger.error("Problem with parseRelational in findMethods.py: " + str(e)) + common.logger.error("Problem with parse_relational in findMethods.py: " + str(e)) return -def parseWhile(token): +def parse_while(token): """ - Parse toke type - While + Parse token type - While """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1157,15 +1240,15 @@ def parseWhile(token): return -def parseArrayInitializer(token): +def parse_array_initializer(token): """ - Parse toke type - ArrayInitializer + Parse token type - ArrayInitializer """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1173,15 +1256,15 @@ def parseArrayInitializer(token): return -def parseWildcard(token): +def parse_wildcard(token): """ - Parse toke type - Wildcard + Parse token type - Wildcard """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1189,29 +1272,29 @@ def parseWildcard(token): return -def parseInt(token): +def parse_int(token): """ - Parse toke type - Integer + Parse token type - Integer """ return -def parseBool(token): +def parse_bool(token): """ - Parse toke type - Boolean + Parse token type - Boolean """ return -def parseFormalParameter(token): +def parse_formal_parameter(token): """ - Parse toke type - formal parameter + Parse token type - formal parameter """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1219,15 +1302,15 @@ def parseFormalParameter(token): return -def parseEquality(token): +def parse_equality(token): """ - Parse toke type - equality + Parse token type - equality """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1235,23 +1318,23 @@ def parseEquality(token): return -def parseUnary(token): +def parse_unary(token): """ - Parse toke type - unary + Parse token type - unary """ return -def parseNone(): +def parse_none(): """ - Parse toke type - None + Parse token type - None """ return -def parseFieldAccess(token): +def parse_field_access(token): """ - Parse toke type - FieldAccess + Parse token type - FieldAccess """ track(token, False) if hasattr(token, '_fields'): @@ -1260,15 +1343,15 @@ def parseFieldAccess(token): return -def parseArrayCreation(token): +def parse_array_creation(token): """ - Parse toke type - ArrayCreation + Parse token type - ArrayCreation """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1276,15 +1359,15 @@ def parseArrayCreation(token): return -def parseConditionalAnd(token): +def parse_conditional_and(token): """ - Parse toke type - Conditional AND + Parse token type - Conditional AND """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1292,15 +1375,15 @@ def parseConditionalAnd(token): return -def parseConditional(token): +def parse_conditional(token): """ - Parse toke type - Conditional + Parse token type - Conditional """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1308,15 +1391,15 @@ def parseConditional(token): return -def parseType(token): +def parse_type(token): """ - Parse toke type - Type + Parse token type - Type """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1324,12 +1407,12 @@ def parseType(token): return -def parseString(token): +def parse_string(token): """ - Parse toke type - String + Parse token type - String """ track(token, False) - if isTainted(token): + if is_tainted(token): common.logger.debug("TAINTED STRING: " + str(tracker[len(tracker) - 2])) #BUG - This may be causing me to miss a second getIntent in the path #It might make sense to traverse the tree backwards until is not longer tainted, but then how to move forward @@ -1337,15 +1420,15 @@ def parseString(token): return -def parseAdditive(token): +def parse_additive(token): """ - Parse toke type - Additive + Parse token type - Additive """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1353,15 +1436,15 @@ def parseAdditive(token): return -def parseAssignment(token): +def parse_assignment(token): """ - Parse toke type - assignment + Parse token type - assignment """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1369,78 +1452,107 @@ def parseAssignment(token): return +def is_super(token): + match=False + if hasattr(token,'target'): + if token.target =='super': + match=True + return match -def parseMethodInvocation(token): + +def parse_method_invocation(token): """ - Parse toke type - Method invocation + Parse token type - Method invocation """ global tree global local_meth_decls global entries global component_type + global current_file - #TODO - This call may now be redundant - if str(component_type) == 'activity': - findSetResult(token) - if hasattr(token, 'name'): - if token.name not in local_meth_decls: - #BUG - Problem with this logic is it assumes the entire class has already been parsed - #To avoid this, we use an ugly hack that should cause the whole class to be parsed - recursiveMethodFinder(tree) - #Yes this could be re-ordered, but seems more efficient, since it saves the recursion time - if token.name not in entries: - if type(tree) is not None: - closeEnough=False - #From here we need to create the call tree in the local file + if is_super(token): + #Returns a bool of whether a sensitive method was encountered + try: + if findSupers.find_extensions(tree,token): + #Need filename and current entry point + try: + findExtras.find_extras(current_file,current_entry) + except Exception as e: + common.logger.error("Problem with findExtras in parse_method_invocation for supers: " +str(e)) + #Need to deliver the results from the two calls above to the exploit and report + if component_type == 'activity': + try: + find_set_result(token) + except Exception as e: + common.logger.error("Problem calling find_set_result in parse_method_invocation for supers: " +str(e)) + except Exception as e: + common.logger.error("Problem parsing supers in parse_method_invocation: " +str(e)) + else: + #TODO - This call may now be redundant + if str(component_type) == 'activity': try: - common.logger.debug("Parsing local method declarations") - closeEnough=localMethodDeclarations.main(token, tree, current_file) + find_set_result(token) except Exception as e: - common.logger.error("Problem trying to look for locally declared methods in findMethods.py: " + str(e)) - if not closeEnough: + common.logger.error("Problem calling find_set_result in parse_method_invocation: " +str(e)) + if hasattr(token, 'name'): + if token.name not in local_meth_decls: + #BUG - Problem with this logic is it assumes the entire class has already been parsed + #To avoid this, we use an ugly hack that should cause the whole class to be parsed + recursive_method_finder(tree) + #Yes this could be re-ordered, but seems more efficient, since it saves the recursion time + if token.name not in entries: + if type(tree) is not None: + closeEnough=False + #From here we need to create the call tree in the local file try: - common.logger.debug("Parsing external method declarations") - externalMethodDeclarations.main(token, tree, current_file) + common.logger.debug("Parsing local method declarations") + closeEnough=localMethodDeclarations.main(token, tree, current_file) except Exception as e: - common.logger.error('Problem running externalMethodDeclarations module from findMethods.py: ' + str(e)) - else: - common.logger.error("Tried to pass None type tree to externalMethodDeclarations in findMethods.py") - - try: - track(token, False) - if hasattr(token, '_fields'): - for f in token._fields: - if type(f) is m.MethodInvocation: - #TODO possibly redundant - if str(component_type) == 'activity': - findSetResult(f) - track(f, False) - if isTainted(getattr(token, f)): - common.logger.debug("TAINTED: " + str(token)) + common.logger.error("Problem trying to look for locally declared methods in findMethods.py: " + str(e)) + if not closeEnough: try: - sink = common.sink_list_check(token,tree) + common.logger.debug("Parsing external method declarations") + externalMethodDeclarations.main(token, tree, current_file) except Exception as e: - common.logger.error("Problem trying to find sink: " + str(e)) - if sink != None: - if tainted_sink_processor(sink, token): - break - elif list_checker(token, f): - common.logger.debug("TAINTED: " + str(token)) - except Exception as e: - common.parsingerrors.add(str(current_file)) - common.logger.error("Problem in parseMethodInvocation of findMethods.py, when trying to match sinks: " + str(e)) + common.logger.error('Problem running externalMethodDeclarations module from findMethods.py: ' + str(e)) + else: + common.logger.error("Tried to pass None type tree to externalMethodDeclarations in findMethods.py") + + try: + track(token, False) + if hasattr(token, '_fields'): + for f in token._fields: + if type(f) is m.MethodInvocation: + #TODO possibly redundant + if str(component_type) == 'activity': + find_set_result(f) + track(f, False) + if is_tainted(getattr(token, f)): + common.logger.debug("TAINTED: " + str(token)) + try: + sink = common.sink_list_check(token,tree) + except Exception as e: + common.logger.error("Problem trying to find sink: " + str(e)) + if sink != None: + if tainted_sink_processor(sink, token): + break + elif list_checker(token, f): + common.logger.debug("TAINTED: " + str(token)) + except Exception as e: + common.parsingerrors.add(str(current_file)) + common.logger.error("Problem in parse_method_invocation of findMethods.py, when trying to match sinks: " + str(e)) return -def parseConditionalOr(token): +def parse_conditional_or(token): """ - Parse toke type - Conditional OR + Parse token type - Conditional OR """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1448,15 +1560,15 @@ def parseConditionalOr(token): return -def parseFieldDeclaration(token): +def parse_field_declaration(token): """ - Parse toke type - Field Declaration + Parse token type - Field Declaration """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1464,15 +1576,15 @@ def parseFieldDeclaration(token): return -def parseName(token): +def parse_name(token): """ - Parse toke type - Name + Parse token type - Name """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1480,15 +1592,15 @@ def parseName(token): return -def parseCast(token): +def parse_cast(token): """ - Parse toke type - Cast + Parse token type - Cast """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1496,15 +1608,15 @@ def parseCast(token): return -def parseVariableDeclaration(token): +def parse_variable_declaration(token): """ - Parse toke type - variable declaration + Parse token type - variable declaration """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1512,15 +1624,15 @@ def parseVariableDeclaration(token): return -def parseCatch(token): +def parse_catch(token): """ - Parse toke type - Catch + Parse token type - Catch """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1528,15 +1640,15 @@ def parseCatch(token): return -def parseSwitch(token): +def parse_switch(token): """ - Parse toke type - switch + Parse token type - switch """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1544,15 +1656,15 @@ def parseSwitch(token): return -def parseSwitchCase(token): +def parse_switch_case(token): """ - Parse toke type - switchCase + Parse token type - switchCase """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1560,15 +1672,15 @@ def parseSwitchCase(token): return -def parseVariableDeclarator(token): +def parse_variable_declarator(token): """ - Parse toke type - variable declaration + Parse token type - variable declaration """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1576,7 +1688,7 @@ def parseVariableDeclarator(token): return -def parseMethodDeclaration(token): +def parse_method_declaration(token): """ Parse token type - method declaration """ @@ -1584,7 +1696,7 @@ def parseMethodDeclaration(token): if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1592,15 +1704,15 @@ def parseMethodDeclaration(token): return -def parseClassInitializer(token): +def parse_class_initializer(token): """ - Parse toke type - Class Initializer + Parse token type - Class Initializer """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1608,15 +1720,15 @@ def parseClassInitializer(token): return -def parseConstructorDeclaration(token): +def parse_constructor_declaration(token): """ - Parse toke type - constructor declaration + Parse token type - constructor declaration """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1624,15 +1736,15 @@ def parseConstructorDeclaration(token): return -def parseEnumDeclaration(token): +def parse_enum_declaration(token): """ - Parse toke type - enum declaration + Parse token type - enum declaration """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1640,15 +1752,15 @@ def parseEnumDeclaration(token): return -def parseInterfaceDeclaration(token): +def parse_interface_declaration(token): """ - Parse toke type - interface declaration + Parse token type - interface declaration """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1656,15 +1768,15 @@ def parseInterfaceDeclaration(token): return -def parseIfThenElse(token): +def parse_if_then_else(token): """ - Parse toke type - IfThenElse + Parse token type - IfThenElse """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1672,15 +1784,15 @@ def parseIfThenElse(token): return -def parseReturn(token): +def parse_return(token): """ - Parse toke type - return + Parse token type - return """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1688,15 +1800,15 @@ def parseReturn(token): return -def parseTry(token): +def parse_try(token): """ - Parse toke type - try + Parse token type - try """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1704,15 +1816,15 @@ def parseTry(token): return -def parseForEach(token): +def parse_for_each(token): """ - Parse toke type - For each + Parse token type - For each """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1720,15 +1832,15 @@ def parseForEach(token): return -def parseFor(token): +def parse_for(token): """ - Parse toke type - For + Parse token type - For """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1736,15 +1848,15 @@ def parseFor(token): return -def parseBlock(token): +def parse_block(token): """ - Parse toke type - Block + Parse token type - Block """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1752,15 +1864,15 @@ def parseBlock(token): return -def parseSynchronized(token): +def parse_synchronized(token): """ - Parse toke type - Synchronized + Parse token type - Synchronized """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1768,15 +1880,15 @@ def parseSynchronized(token): return -def parseVariable(token): +def parse_variable(token): """ - Parse toke type - Variable + Parse token type - Variable """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1784,15 +1896,15 @@ def parseVariable(token): return -def parseClassDeclaration(token): +def parse_class_declaration(token): """ - Parse toke type - Class declaration + Parse token type - Class declaration """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1800,15 +1912,15 @@ def parseClassDeclaration(token): return -def parseAnnotation(token): +def parse_annotation(token): """ - Parse toke type - annotation + Parse token type - annotation """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1816,15 +1928,15 @@ def parseAnnotation(token): return -def parseLiteral(token): +def parse_literal(token): """ - Parse toke type - Literal + Parse token type - Literal """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1832,15 +1944,15 @@ def parseLiteral(token): return -def parseBreak(token): +def parse_break(token): """ - Parse toke type - break + Parse token type - break """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): @@ -1848,15 +1960,15 @@ def parseBreak(token): return -def parseInstanceCreation(token): +def parse_instance_creation(token): """ - Parse toke type - Instance creation + Parse token type - Instance creation """ track(token, False) if hasattr(token, '_fields'): for f in token._fields: track(f, False) - if isTainted(getattr(token, f)): + if is_tainted(getattr(token, f)): common.logger.debug("TAINTED: " + str(token)) else: if list_checker(token, f): diff --git a/modules/findPending.py b/modules/findPending.py index 630119b6..e9c4fc9f 100644 --- a/modules/findPending.py +++ b/modules/findPending.py @@ -92,10 +92,10 @@ def recurse(f,t,results): #TODO - the interesting ones seem to be of type Name only #The intent is always the third parameter, for getActivities it is an array try: - parseArgs(current.arguments[2],results) + parse_args(current.arguments[2],results) except Exception as e: report.write("parsingerror-issues-list", str(current_file), "strong") - common.logger.debug("Problem in parseArgs function of findPending.py: " + str(e)) + common.logger.debug("Problem in parse_args function of findPending.py: " + str(e)) elif l is None: pass else: @@ -122,7 +122,7 @@ def recurse(f,t,results): #TODO - the interesting ones seem to be of type Name only #The intent is always the third parameter, for getActivities it is an array try: - parseArgs(current.arguments[2],results) + parse_args(current.arguments[2],results) except Exception as e: report.write("parsingerror-issues-list", str(current_file), "strong") common.logger.debug("Problem in recurse function of findPending.py: " + str(e)) @@ -147,7 +147,7 @@ def recurse(f,t,results): common.logger.debug("Problem in recurse function of findPending.py: " + str(e)) return -def parseArgs(arg,results): +def parse_args(arg,results): """ Checking to see whether the setClass method is called on the arguments of a pending intent, if it is a new instance of an Intent """ @@ -160,14 +160,14 @@ def parseArgs(arg,results): #If the argument is not a name, what is it? if hasattr(arg.target.arguments[1],'value'): try: - if findClass(arg.target.arguments[1].value,results): + if find_class(arg.target.arguments[1].value,results): return else: report.write("parsingerror-issues-list", str(current_file), "strong") - common.logger.debug("ERROR: CAN'T FIND THE CLASS in parseArgs") + common.logger.debug("ERROR: CAN'T FIND THE CLASS in parse_args") except Exception as e: report.write("parsingerror-issues-list", str(current_file), "strong") - common.logger.debug("Problem in findClass function of findPending.py: " + str(e)) + common.logger.debug("Problem in find_class function of findPending.py: " + str(e)) else: report.write("parsingerror-issues-list", str(current_file), "strong") common.logger.debug("ERROR: UNEXPECTED Type " + str(type(arg.target.arguments[1]))) @@ -192,10 +192,10 @@ def parseArgs(arg,results): elif type(arg) is m.Name: if hasattr(arg,'value'): try: - findIntent(arg.value,results) + find_intent(arg.value,results) except Exception as e: report.write("parsingerror-issues-list", str(current_file), "strong") - common.logger.debug("Problem in findIntent function of findPending.py: " + str(e)) + common.logger.debug("Problem in find_intent function of findPending.py: " + str(e)) else: #TODO - Remove this (never seems to be hit) report.write("parsingerror-issues-list", str(current_file), "strong") @@ -203,7 +203,7 @@ def parseArgs(arg,results): common.logger.debug("ERROR: INCOMPLETE CODE BRANCH REACHED findPending.py #5 - Press any key to continue (results may be incomplete)") return -def findClass(classname,results): +def find_class(classname,results): found=False """ Find the class name @@ -216,7 +216,7 @@ def findClass(classname,results): found=True return found else: - if recurseClass(classname,type_decl,results): + if recurse_class(classname,type_decl,results): return True elif type(type_decl) is m.VariableDeclaration: if hasattr(type_decl,'type'): @@ -225,11 +225,11 @@ def findClass(classname,results): if str(type_decl.type.name.value) == str(classname): return True else: - if recurseClass(classname,type_decl,results): + if recurse_class(classname,type_decl,results): return True return found -def recurseClass(classname,treeObject,results): +def recurse_class(classname,treeObject,results): found=False if hasattr(treeObject,'_fields'): for x in treeObject._fields: @@ -249,14 +249,14 @@ def recurseClass(classname,treeObject,results): found=True return found else: - if recurseClass(classname,y,results): + if recurse_class(classname,y,results): return True elif type(getattr(treeObject,x)) is m.ClassDeclaration: if x.name == str(classname): found=True return found else: - if recurseClass(classname,x,results): + if recurse_class(classname,x,results): return True elif type(getattr(treeObject,x)) is m.VariableDeclaration: @@ -269,15 +269,15 @@ def recurseClass(classname,treeObject,results): elif hasattr(getattr(treeObject,x),'_fields'): for z in getattr(treeObject,x)._fields: - if recurseClass(classname,getattr(getattr(treeObject,x),z),results): + if recurse_class(classname,getattr(getattr(treeObject,x),z),results): return True elif type(treeObject) is list: for a in treeObject: - if recurseClass(classname,a,results): + if recurse_class(classname,a,results): return True return found -def findIntent(intent,results): +def find_intent(intent,results): """ Find Intent """ @@ -342,9 +342,9 @@ def findIntent(intent,results): else: common.logger.debug("Something went wrong in findPending, when determining if the Intent was explicit") elif type(x) is list: - common.logger.debug("ERROR: UNEXPECTED CODE PATH in findIntent - 1") + common.logger.debug("ERROR: UNEXPECTED CODE PATH in find_intent - 1") elif type(getattr(t,f)) is m.MethodInvocation: - common.logger.debug("ERROR: UNEXPECTED CODE PATH in findIntent - 2") + common.logger.debug("ERROR: UNEXPECTED CODE PATH in find_intent - 2") else: for f in t._fields: if type(getattr(t,f)) is list: diff --git a/modules/findTapJacking.py b/modules/findTapJacking.py index 2d6c15a5..cfd0a306 100644 --- a/modules/findTapJacking.py +++ b/modules/findTapJacking.py @@ -20,7 +20,7 @@ def start(path): return -def findLayout(path): +def find_layout(path): foundButtons=[] foundButtons.append([]) for (dirpath, dirnames, filenames) in os.walk(path): @@ -78,7 +78,7 @@ def findLayout(path): print "No buttons found in xml layouts" return -def findJavaButtons(xmlFile,buttonId): +def find_java_buttons(xmlFile,buttonId): # Need find all the Buttons declared in the Java classes global tree global currentFile diff --git a/modules/localMethodDeclarations.py b/modules/localMethodDeclarations.py index eae2fb23..92b4323a 100644 --- a/modules/localMethodDeclarations.py +++ b/modules/localMethodDeclarations.py @@ -27,28 +27,28 @@ def main(token,tree,current_file): for type_decl in tree.type_declarations: if type(type_decl) is m.ClassDeclaration: for t in type_decl.body: - recursiveMethodFinder(t,token) + recursive_method_finder(t,token) return closeEnough -def recursiveMethodFinder(t,token): +def recursive_method_finder(t,token): global closeEnough if type(t) is m.MethodDeclaration: if str(t.name)==str(token.name): if len(t.parameters)==len(token.arguments): closeEnough=True - if sinksEncountered(t): + if sinks_encountered(t): common.logger.log(common.VULNERABILITY_LEVEL,"It appears a vulnerability was found here, but unfortunately we haven't completed this branch yet.") elif type(t) is list: for l in t: - recursiveMethodFinder(l,token) + recursive_method_finder(l,token) elif hasattr(t,'_fields'): for f in t._fields: - recursiveMethodFinder(getattr(t,f),token) + recursive_method_finder(getattr(t,f),token) return -def sinksEncountered(t): +def sinks_encountered(t): global localTree global found @@ -60,8 +60,8 @@ def sinksEncountered(t): common.logger.error("Problem in call to common.sink_list_check from localMethodDeclarations.py: " + str(e)) elif type(t) is list: for l in t: - sinksEncountered(l) + sinks_encountered(l) elif hasattr(t,'_fields'): for f in t._fields: - sinksEncountered(f) + sinks_encountered(f) return found \ No newline at end of file diff --git a/modules/sdkManager.py b/modules/sdkManager.py index aa3bb1d0..216ef71d 100755 --- a/modules/sdkManager.py +++ b/modules/sdkManager.py @@ -7,7 +7,7 @@ from modules import common -import os +import os, platform import urllib2 import sys import zipfile @@ -16,12 +16,12 @@ import shlex import stat from subprocess import Popen, PIPE, STDOUT -import re,shutil +import re,shutil, tarfile common.logger = logging.getLogger() logger = logging.getLogger(__name__) -def isAndroidSDKInstalled(): +def is_android_sdk_installed(): """ Verify if Android SDK is installed and available for use by QARK """ @@ -32,7 +32,7 @@ def isAndroidSDKInstalled(): else: return False -def getAndroidSDKManager(): +def get_android_sdk_manager(): """ Gets the location of SDK manager through CLI while in interactive mode, or via settings.properties if running headlessly """ @@ -40,23 +40,44 @@ def getAndroidSDKManager(): print common.term.cyan choice=raw_input(common.config.get('qarkhelper','GET_ANDROID_SDK_MANAGER_PROMPT')) if str(choice).lower()=='y': - downloadSDK() + download_sdk() else: AndroidSDKPath=raw_input(common.config.get('qarkhelper','ANDROID_SDK_MANAGER_PATH_PROMPT')) - common.writeKey('AndroidSDKPath', AndroidSDKPath) - while not (os.path.exists(common.getConfig('AndroidSDKPath') + "/tools")): + if not str(AndroidSDKPath).endswith("/"): + AndroidSDKPath = str(AndroidSDKPath).strip() + "/" + #common.writeKey('AndroidSDKPath', AndroidSDKPath) + while not (os.path.exists(AndroidSDKPath + "tools")): logger.error(str(common.config.get('qarkhelper','ANDROID_SDK_MANAGER_PATH_PROMPT_AGAIN')).decode('string-escape')) print common.term.cyan AndroidSDKPath=raw_input(common.config.get('qarkhelper','ANDROID_SDK_MANAGER_PATH_PROMPT')) - common.writeKey('AndroidSDKPath', AndroidSDKPath) + if not str(AndroidSDKPath).endswith("/"): + AndroidSDKPath = str(AndroidSDKPath).strip() + "/" + common.writeKey('AndroidSDKPath', AndroidSDKPath) + common.AndroidSDKPath = AndroidSDKPath common.logger.debug("Located SDK") - -def downloadSDK(): + +def extract(tar_url, extract_path): + print tar_url + tar = tarfile.open(tar_url, 'r') + for item in tar: + tar.extract(item, extract_path) + if item.name.find(".tgz") != -1 or item.name.find(".tar") != -1: + extract(item.name, "./" + item.name[:item.name.rfind('/')]) + +def download_sdk(): """ Download the SDK from Google """ - url = " https://dl.google.com/android/android-sdk_r24.0.2-macosx.zip" - + + url = "" + url_macosx = "https://dl.google.com/android/android-sdk_r24.0.2-macosx.zip" + url_linux = "https://dl.google.com/android/android-sdk_r24.3.4-linux.tgz" + + if sys.platform == "linux2": + url = url_linux + else: + url = url_macosx + file_name = url.split('/')[-1] u = urllib2.urlopen(url) f = open(common.getConfig("rootDir") + "/" + file_name, 'wb') @@ -81,22 +102,31 @@ def downloadSDK(): androidSDKZIP = f.name print common.term.cyan + str(common.config.get('qarkhelper','FILE_DOWNLOADED_TO')) + androidSDKZIP.decode('string-escape').format(t=common.term) print common.term.cyan + str(common.config.get('qarkhelper','UNPACKING')) + androidSDKZIP.decode('string-escape').format(t=common.term) - zf = zipfile.ZipFile(androidSDKZIP) - for filename in [ zf.namelist()]: + if sys.platform == "linux2": try: if not os.path.exists(androidSDKZIP.rsplit(".",1)[0]): os.makedirs(androidSDKZIP.rsplit(".",1)[0]) - zf.extractall(androidSDKZIP.rsplit(".",1)[0] + "/", zf.namelist(), ) - except KeyError: - logger.error('Oops!! %s doesnt look like a valid APK', filename) - else: - logger.info('Done') + extract(androidSDKZIP, androidSDKZIP.rsplit(".",1)[0]) + except Exception as e: + logger.error(e.message) + common.writeKey('AndroidSDKPath', androidSDKZIP.rsplit(".",1)[0] + "/android-sdk-linux/") + else: + zf = zipfile.ZipFile(androidSDKZIP) + for filename in [ zf.namelist()]: + try: + if not os.path.exists(androidSDKZIP.rsplit(".",1)[0]): + os.makedirs(androidSDKZIP.rsplit(".",1)[0]) + zf.extractall(androidSDKZIP.rsplit(".",1)[0] + "/", zf.namelist(), ) + except Exception as e: + logger.error(e.message) + else: + logger.info('Done') + common.writeKey('AndroidSDKPath', androidSDKZIP.rsplit(".",1)[0] + "/android-sdk-macosx/") #We dont need the ZIP file anymore os.remove(androidSDKZIP) - common.writeKey('AndroidSDKPath', androidSDKZIP.rsplit(".",1)[0] + "/android-sdk-macosx/") - runSDKManager() + run_sdk_manager() -def runSDKManager(): +def run_sdk_manager(): """ Runs the SDK manager """ @@ -140,8 +170,8 @@ def runSDKManager(): -#buildAPK takes in all paths relative to the '/build/' folder in QARK -def buildAPK(path): +#build_apk takes in all paths relative to the '/build/' folder in QARK +def build_apk(path): """ Builds the APK when path the the source is available """ diff --git a/modules/unpackAPK.py b/modules/unpackAPK.py index 41173ebb..88dcc8be 100644 --- a/modules/unpackAPK.py +++ b/modules/unpackAPK.py @@ -84,7 +84,7 @@ def get_apk_info(pathToAPK): package['application-permissions'].append(line.split("'")[1]) return package -def findManifestInUnpackedAPK(path, name): +def find_manifest_in_unpacked_apk(path, name): """ Finds manifest.xml from the unpacked APK """ @@ -98,7 +98,7 @@ def findManifestInUnpackedAPK(path, name): logger.info('%s found', name) return os.path.join(root, name) -def grep1(path, regex): +def grep_1(path, regex): """ wrapper around grep functionality """ @@ -174,9 +174,9 @@ def decompile(path): with common.term.location(0,common.term.height): print "" - g1 = grep1(dirname, "// Byte code:") - g2 = grep1(dirname+"1", "// This method has failed to decompile.") - g3 = grep1(dirname+"2", "// This method could not be decompiled.") + g1 = grep_1(dirname, "// Byte code:") + g2 = grep_1(dirname+"1", "// This method has failed to decompile.") + g3 = grep_1(dirname+"2", "// This method could not be decompiled.") #print list(set(g1) - set(g2)) logger.info("Trying to improve accuracy of the decompiled files") diff --git a/modules/useCheckPermission.py b/modules/useCheckPermission.py index 7f7747c6..4995c7a9 100644 --- a/modules/useCheckPermission.py +++ b/modules/useCheckPermission.py @@ -7,8 +7,8 @@ from modules import common -def useCheckPermission(): - common.logger.info("Sorry, we haven't completed the check for useCheckPermission yet. Check for updates soon.") +def use_check_permission(): + common.logger.info("Sorry, we haven't completed the check for use_check_permission yet. Check for updates soon.") ''' From Android Lint: diff --git a/modules/writeExploit.py b/modules/writeExploit.py index 6b0de461..608bfed4 100644 --- a/modules/writeExploit.py +++ b/modules/writeExploit.py @@ -14,43 +14,43 @@ from modules import filters def write(obj): - if not PackageNameInStrings(): - modifyStrings("packageName", filters.find_package()) + if not package_name_in_strings(): + modify_strings("packageName", filters.find_package()) if hasattr(obj, "getType"): intentType = obj.getType() if intentType==exploitService.type: - newId = modifyIntentID(exploitService.id) - modifyStrings(newId, obj.getIntent()) + newId = modify_intent_id(exploitService.id) + modify_strings(newId, obj.getIntent()) elif intentType in [exploitBroadcast.type]: - newId = modifyIntentID(exploitBroadcast.id) + newId = modify_intent_id(exploitBroadcast.id) keys = exploitBroadcast(obj).getExtra() for key in keys: - modifyExtraKeys(newId, key) - modifyStrings(newId, obj.getIntent()) + modify_extra_keys(newId, key) + modify_strings(newId, obj.getIntent()) elif intentType in [exploitActivity.type]: - newId = modifyIntentID(exploitActivity.id) + newId = modify_intent_id(exploitActivity.id) keys = exploitActivity(obj).getExtra() for key in keys: - modifyExtraKeys(newId, key) - modifyStrings(newId, obj.getExportedActivity()) + modify_extra_keys(newId, key) + modify_strings(newId, obj.getExportedActivity()) elif intentType in [exploitContentProvider.type]: - newId = modifyIntentID(exploitContentProvider.id) + newId = modify_intent_id(exploitContentProvider.id) keys = exploitContentProvider(obj).getExtra() for key in keys: - modifyExtraKeys(newId, key) - modifyStrings(newId, obj.getIntent()) + modify_extra_keys(newId, key) + modify_strings(newId, obj.getIntent()) elif intentType in [exploitReceiver.type]: - newId = modifyIntentID(exploitReceiver.id) + newId = modify_intent_id(exploitReceiver.id) keys = exploitReceiver(obj).getExtra() for key in keys: - modifyExtraKeys(newId, key) - modifyStrings(newId, obj.getIntent()) + modify_extra_keys(newId, key) + modify_strings(newId, obj.getIntent()) -def modifyIntentID(intentId): +def modify_intent_id(intentId): filename = common.exploitLocation + "/app/src/main/res/values/intentID.xml" insert_position = 0 intentType = "" @@ -88,7 +88,7 @@ def modifyIntentID(intentId): document.write(filename) return new_node.text -def modifyExtraKeys(intentName, key): +def modify_extra_keys(intentName, key): filename = common.exploitLocation + "/app/src/main/res/values/extraKeys.xml" insert_position = 0 flag = False @@ -111,7 +111,7 @@ def modifyExtraKeys(intentName, key): root.append(new_node) document.write(filename) -def modifyStrings(intentName, value): +def modify_strings(intentName, value): print "adding value to string: " + value filename = common.exploitLocation + "/app/src/main/res/values/strings.xml" document = ElementTree.parse(filename, None) @@ -125,7 +125,7 @@ def modifyStrings(intentName, value): return document.write(filename) -def PackageNameInStrings(): +def package_name_in_strings(): filename = common.exploitLocation + "/app/src/main/res/values/strings.xml" document = ElementTree.parse(filename, None) for string_array in document.findall("string"): diff --git a/poc/BURL_WARNING.html b/poc/BURL_WARNING.html old mode 100755 new mode 100644 diff --git a/poc/FILE_SYS_WARN.html b/poc/FILE_SYS_WARN.html old mode 100755 new mode 100644 diff --git a/poc/JS_WARNING.html b/poc/JS_WARNING.html old mode 100755 new mode 100644 diff --git a/qark.py b/qark.py index e70e0fe0..df0b52ab 100644 --- a/qark.py +++ b/qark.py @@ -21,9 +21,9 @@ import lib.axmlparserpy.axmlprinter as axmlprinter from modules.IssueType import IssueType, IssueSeverity import traceback -from modules import common,intents,webviews, report, unpackAPK +from modules import common,findExtras,webviews, report, unpackAPK -from modules.DetermineMinSDK import determineMinSDK +from modules.DetermineMinSDK import determine_min_sdk from modules import sdkManager from modules import createSploit from modules import createExploit @@ -35,7 +35,7 @@ from modules import findTapJacking from modules import filePermissions from modules import exportedPreferenceActivity -from modules.useCheckPermission import useCheckPermission +from modules import useCheckPermission from modules import cryptoFlaws import logging import time @@ -67,7 +67,7 @@ def exit(): """ sys.exit() -def clearlines(n): +def clear_lines(n): """ Clear the space before using it """ @@ -115,42 +115,42 @@ def version(): print "Version 0.8" sys.exit() -def showExports(compList,compType): +def show_exports(compList,compType): try: if len(compList)>0: if compType=='activity': print "==>EXPORTED ACTIVITIES: " - for component in enumerate(compList): - print str(str(component[0]+1)+str(component[1])) + for index,component in enumerate(compList): + print str(index)+": "+str(component) try: - adb.showAdbCommands(str(component[1]),compType,package_name) + adb.show_adb_commands(str(component),compType,package_name) except Exception as e: - common.logger.error("Problem running adb.showAdbCommands, for Activities, in qark.py: " + str(e)) + common.logger.error("Problem running adb.show_adb_commands, for Activities, in qark.py: " + str(e)) '''elif compType=='alias': print "==>EXPORTED ACTIVITY ALIASES: " - adb.showAdbCommands(component[1],compType,package_name)''' + adb.show_adb_commands(component[1],compType,package_name)''' elif compType=='service': print "==>EXPORTED SERVICES: " - for component in enumerate(compList): - print str(component[0]+1)+str(component[1]) + for index,component in enumerate(compList): + print str(index)+": "+str(component) try: - adb.showAdbCommands(str(component[1]),compType,package_name) + adb.show_adb_commands(str(component),compType,package_name) except Exception as e: - common.logger.error("Problem running adb.showAdbCommands, for Services, in qark.py: " + str(e)) + common.logger.error("Problem running adb.show_adb_commands, for Services, in qark.py: " + str(e)) '''if compType=='provider': print "==>EXPORTED PROVIDERS: " - adb.showAdbCommands(component[1],compType,package_name)''' + adb.show_adb_commands(component[1],compType,package_name)''' elif compType=='receiver': print "==>EXPORTED RECEIVERS: " - for component in enumerate(compList): - print str(component[0]+1)+str(component[1]) - try: - adb.showAdbCommands(str(component[1]),compType,package_name) - except Exception as e: - common.logger.error("Problem running adb.showAdbCommands in qark.py: " + str(e)) + for index,component in enumerate(compList): + print str(index)+": "+str(component) + try: + adb.show_adb_commands(str(component),compType,package_name) + except Exception as e: + common.logger.error("Problem running adb.show_adb_commands, for Receivers, in qark.py: " + str(e)) except Exception as e: - common.logger.error("Problem running adb.showAdbCommands in qark.py: " + str(e)) + common.logger.error("Problem running show_exports in qark.py: " + str(e)) return @@ -203,7 +203,6 @@ def showExports(compList,compType): if len(sys.argv) > 1: common.interactive_mode = False - ####################################### #Command line argument sanity checks if not common.interactive_mode: @@ -232,6 +231,7 @@ def showExports(compList,compType): if common.args.install is None: common.logger.error("--install flag missing. Possible values 0/1") exit() + if common.args.debuglevel is not None: if int(common.args.debuglevel) in range(10,60): common.logger.setLevel(int(common.args.debuglevel)) @@ -245,25 +245,21 @@ def showExports(compList,compType): if common.args.basesdk is not None: common.writeKey('AndroidSDKPath', str(common.args.basesdk).strip()) + ####################################### #Reset any old report - report.reset() common.set_environment_variables() - #Copy the exploit code into a separate temp directory if not os.path.exists(common.getConfig("rootDir") + "/build"): shutil.copytree(common.getConfig("rootDir") + "/exploitAPKs", common.getConfig("rootDir") + "/build") - common.logger.info(common.config.get('qarkhelper', 'STARTUP')) - -if not sdkManager.isAndroidSDKInstalled(): - sdkManager.getAndroidSDKManager() +if not sdkManager.is_android_sdk_installed(): + sdkManager.get_android_sdk_manager() else: common.logger.info( common.config.get('qarkhelper', 'SDK_INSTALLATION_IDENTIFIED')) -#sdkManager.buildAPK() common.minSdkVersion=1 @@ -291,7 +287,7 @@ def read_files(filename,rex): common.logger.info('Initializing QARK\n') common.checkJavaVersion() -def processManifest(manifest): +def process_manifest(manifest): try: common.manifest = os.path.abspath(str(manifest).strip()) @@ -377,15 +373,7 @@ def pull_apk(pathOnDevice): print line, return 'temp/'+str(pathOnDevice).split('/')[-1] -def setAPKSourceDir(): - #Converting dex files to jar - unpackAPK.decompile(common.pathToDEX) - if common.pathToUnpackedAPK != "": - common.logger.info('Decompiled code found at:%s', common.pathToUnpackedAPK) - common.sourceDirectory = common.pathToUnpackedAPK - return - -def findManifestInSource(): +def find_manifest_in_source(): common.logger.info('Finding AndroidManifest.xml') listOfFiles = [] manifestPath='' @@ -402,7 +390,7 @@ def findManifestInSource(): if os.path.isdir(common.sourceDirectory): if not common.sourceDirectory.endswith('/'): common.sourceDirectory+='/' - manifestPath=findManifestInSource() + manifestPath=find_manifest_in_source() common.manifest=manifestPath break else: @@ -427,7 +415,7 @@ def findManifestInSource(): exit() return manifestPath -def reportBadger(identity, objectlist): +def report_badger(identity, objectlist): for item in objectlist: if isinstance(item, ReportIssue): @@ -500,7 +488,7 @@ def reportBadger(identity, objectlist): try: package = defaultdict(list) - mf = unpackAPK.findManifestInUnpackedAPK(common.apkPath, common.manifestName) + mf = unpackAPK.find_manifest_in_unpacked_apk(common.apkPath, common.manifestName) ap = axmlprinter.AXMLPrinter(open(mf, 'rb').read()) manifestInXML = minidom.parseString(ap.getBuff()).toxml() if common.interactive_mode: @@ -531,7 +519,7 @@ def reportBadger(identity, objectlist): if os.path.isdir(common.sourceDirectory): if not common.sourceDirectory.endswith('/'): common.sourceDirectory+='/' - processManifest(findManifestInSource()) + process_manifest(find_manifest_in_source()) break else: common.logger.error("Not a directory. Please try again") @@ -546,20 +534,20 @@ def reportBadger(identity, objectlist): common.logger.info("You only had 2 options and you still messed up. Let me choose option 2 for you") #Only application and manifest elements are required: http://developer.android.com/guide/topics/manifest/manifest-intro.html try: - determineMinSDK() + determine_min_sdk() common.print_terminal_header("APP COMPONENT ATTACK SURFACE") app = common.xmldoc.getElementsByTagName("application") common.compare(app.length,1,common.config.get('qarkhelper', 'APP_ELEM_ISSUE'), 'true') - GeneralIssues.verifyAllowBackup(app) - GeneralIssues.verifyCustomPermissions() - GeneralIssues.verifyDebuggable(app) + GeneralIssues.verify_allow_backup(app) + GeneralIssues.verify_custom_permissions() + GeneralIssues.verify_debuggable(app) common.logger.info("Checking provider") prov_priv_list, prov_exp_list, prov_exp_perm_list, prov_prot_broad_list, report_data, results =common.check_export('provider',True) - reportBadger("appcomponents", results) + report_badger("appcomponents", results) common.print_terminal(report_data) common.logger.info("Checking activity") @@ -572,26 +560,26 @@ def reportBadger(identity, objectlist): act_exp_perm_list=common.normalizeActivityNames(act_exp_perm_list,package_name) act_prot_broad_list=common.normalizeActivityNames(act_prot_broad_list,package_name) - reportBadger("appcomponents", results) + report_badger("appcomponents", results) common.print_terminal(report_data) common.logger.info("Checking activity-alias") #TODO - Normalize activity alias names? actalias_priv_list, actalias_exp_list, actalias_exp_perm_list,actalias_prot_broad_list=[],[],[],[] actalias_priv_list, actalias_exp_list, actalias_exp_perm_list,actalias_prot_broad_list, report_data, results=common.check_export('activity-alias',True) - reportBadger("appcomponents", results) + report_badger("appcomponents", results) common.print_terminal(report_data) common.logger.info("Checking services") serv_priv_list, serv_exp_list, serv_exp_perm_list,serv_prot_broad_list=[],[],[],[] serv_priv_list, serv_exp_list, serv_exp_perm_list,serv_prot_broad_list, report_data, results=common.check_export('service',True) - reportBadger("appcomponents", results) + report_badger("appcomponents", results) common.print_terminal(report_data) common.logger.info("Checking receivers") rec_priv_list, rec_exp_list, rec_exp_perm_list,rec_prot_broad_list=[],[],[],[] rec_priv_list, rec_exp_list, rec_exp_perm_list,rec_prot_broad_list, report_data, results=common.check_export('receiver',True) - reportBadger("appcomponents", results) + report_badger("appcomponents", results) common.print_terminal(report_data) except Exception as e: @@ -630,6 +618,9 @@ def reportBadger(identity, objectlist): #find all java files common.java_files=common.find_java(common.sourceDirectory) +#find all R.java files +common.xml_files=common.find_xml(common.sourceDirectory) + if common.interactive_mode: stop_point = raw_input("Press ENTER key to begin Static Code Analysis") #Regex to look for collection of deviceID @@ -660,12 +651,12 @@ def reportBadger(identity, objectlist): ''' #Look for improper use of checkCallingPermission, rather than enforceCallingPermission try: - useCheckPermission() + use_check_permission() except Exception as e: common.logger.error("Unable to run checks for improper use of checkCallingPermission: " + str(e)) ''' -clearlines(14) +clear_lines(14) height = common.term.height try: @@ -705,8 +696,7 @@ def reportBadger(identity, objectlist): thread4.join() thread5.join() - clearlines(5) - + clear_lines(5) try: #Start looking for stuff potentially vulnerable to malicious apps if len(prov_exp_list)>0: @@ -863,7 +853,7 @@ def reportBadger(identity, objectlist): common.logger.debug("Beginning TapJacking testing") findTapJacking.start(common.sourceDirectory) else: - common.logger.error("Since the minSdkVersion is less that 9, it is likely this application is vulnerable to TapJacking. QARK made no attempt to confirm, as the protection would have to be custom code, which is difficult for QARK to examine and understand properly. This vulnerability allows a malicious application to lay on top of this app, while letting the key strokes pass through to the application below. This can cause users to take unwanted actions, within the victim application, similar to Clickjacking on websites. Please select the appropriate options in the exploitation menus to verify manually using QARK's exploit APK. Note: The QARK proof-of-concept is transparent, but in real-world attacks, it would likely not be. This is done solely to aid in testing. For more information: https://media.blackhat.com/ad-12/Niemietz/bh-ad-12-androidmarcus_niemietz-WP.pdf") + common.logger.log(common.VULNERABILITY_LEVEL,"Since the minSdkVersion is less that 9, it is likely this application is vulnerable to TapJacking. QARK made no attempt to confirm, as the protection would have to be custom code, which is difficult for QARK to examine and understand properly. This vulnerability allows a malicious application to lay on top of this app, while letting the key strokes pass through to the application below. This can cause users to take unwanted actions, within the victim application, similar to Clickjacking on websites. Please select the appropriate options in the exploitation menus to verify manually using QARK's exploit APK. Note: The QARK proof-of-concept is transparent, but in real-world attacks, it would likely not be. This is done solely to aid in testing. For more information: https://media.blackhat.com/ad-12/Niemietz/bh-ad-12-androidmarcus_niemietz-WP.pdf") ########### @@ -896,7 +886,7 @@ def reportBadger(identity, objectlist): common.logger.info("The Content Providers above should be manually inspected for injection vulnerabilities.") try: #TODO - This is a pain in the ass and incomplete - contentProviderUriPermissions() + content_provider_uri_permissions() except Exception as e: common.logger.error("Unable to parse Content Provider permissions. Error: " + str(e)) @@ -920,11 +910,11 @@ def reportBadger(identity, objectlist): common.logger.info("Until we perfect this, for manually testing, run the following command to see all the options and their meanings: adb shell am. Make sure to update qark frequently to get all the enhancements! You'll also find some good examples here: http://xgouchet.fr/android/index.php?article42/launch-intents-using-adb") try: - showExports(prov_exp_list,'provider') - showExports(act_exp_list,'activity') - showExports(actalias_exp_list,'alias') - showExports(serv_exp_list,'service') - showExports(rec_exp_list,'receiver') + show_exports(prov_exp_list,'provider') + show_exports(act_exp_list,'activity') + show_exports(actalias_exp_list,'alias') + show_exports(serv_exp_list,'service') + show_exports(rec_exp_list,'receiver') print "\nTo view any sticky broadcasts on the device:" print "adb shell dumpsys activity| grep sticky\n" @@ -932,7 +922,7 @@ def reportBadger(identity, objectlist): common.logger.info("Support for other component types and dynamically adding extras is in the works, please check for updates") except Exception as e: - common.logger.error("Problem running showExports in qark.py: " + str(e)) + common.logger.error("Problem running show_exports in qark.py: " + str(e)) else: print "Sorry, nothing exploitable via ADB" except Exception as e: @@ -964,11 +954,12 @@ def reportBadger(identity, objectlist): if exploit_choice==1: # Exploit all vulnerabilities print "Generating exploit payloads for all vulnerabilities" + type_list=['String','StringArray','StringArrayList','Boolean','BooleanArray','Int','Float','Long','LongArray','[]','','IntArray','IntegerArrayList','FloatArray','Double','Char','CharArray','CharSequence','CharSequenceArray','CharSequenceArrayList','Byte','ByteArray', 'Bundle','Short','ShortArray','Serializable','Parcelable','ParcelableArrayList','ParcelableArray','unknownType'] shutil.rmtree(common.getConfig("rootDir") +'/build') - if str(createSploit.copyTemplate(common.getConfig("rootDir") + '/exploitAPKs/qark/',common.getConfig("rootDir") + '/build/qark')) is not 'ERROR': + if str(createSploit.copy_template(common.getConfig("rootDir") + '/exploitAPKs/qark/',common.getConfig("rootDir") + '/build/qark')) is not 'ERROR': common.exploitLocation = common.getConfig("rootDir") + '/build/qark' if len(prov_exp_list)>0: - print "ok" + common.logger.info("Sorry, we're still working on the providers") if len(act_exp_list)>0: common.normalizeActivityNames(act_exp_list,filters.find_package()) for i in act_exp_list: @@ -976,13 +967,23 @@ def reportBadger(identity, objectlist): exploit = createExploit.exploitActivity() print str(i) extras_list=[] - extras_list+=intents.find_extras(str(i),common.sourceDirectory) + entries=common.get_entry_for_component('activity') + for n in entries: + tmp_extra=findExtras.find_extras(str(i),n) + if tmp_extra not in type_list: + if tmp_extra not in extras_list: + extras_list+=tmp_extra + common.dedup(extras_list) if re.match(r'^\..*',str(i)): i=str(package_name)+str(i) exploit.setExportedActivity(str(i)) for j in range(0,len(extras_list)): - extras_list[j] = extras_list[j].replace('\"','') - if (extras_list[j]==" " or extras_list[j]==""): + extras_list[j] = str(extras_list[j]).replace('\"','') + bad_extras=["\"\"","\" \"","[]"] + #if (extras_list[j]==" " or extras_list[j]==""): + if extras_list[j] in bad_extras: + pass + elif extras_list[j] in type_list: pass else: exploit.setExtra(extras_list[j]) @@ -991,7 +992,7 @@ def reportBadger(identity, objectlist): except Exception as e: common.logger.error("Problems creating exploit (activity): " + str(e)) if len(actalias_exp_list)>0: - print "ok" + common.logger.info("Sorry, we're still working on Activity Aliases") if len(serv_exp_list)>0: for i in range(0, len(serv_exp_list)): exploit = createExploit.exploitService() @@ -1004,7 +1005,13 @@ def reportBadger(identity, objectlist): exploit.setIntent(action) print rec_exp_list[i] extras_list=[] - extras_list+=intents.find_extras(rec_exp_list[i],common.sourceDirectory) + entries=common.get_entry_for_component('receiver') + for n in entries: + tmp_extra=findExtras.find_extras(rec_exp_list[i],n) + if tmp_extra not in type_list: + if tmp_extra not in extras_list: + extras_list+=tmp_extra + common.dedup(extras_list) if len(common.sploitparams)==0: for j in range(0,len(extras_list)): extras_list[j] = extras_list[j].replace('\"','') @@ -1028,7 +1035,7 @@ def reportBadger(identity, objectlist): writeExploit.write(exploit) except Exception as e: common.logger.error("Problems creating exploit (receiver): " + str(e)) - sdkManager.buildAPK('qark') + sdkManager.build_apk('qark') if common.interactive_mode: install=raw_input("Do you want to install this to your device? (y/n)").lower() else: diff --git a/sampleApps/goatdroid/OWASP-GoatDroid-0.9/dbs/fourgoats/db.lck b/sampleApps/goatdroid/OWASP-GoatDroid-0.9/dbs/fourgoats/db.lck index 4ab6938813dc8838a33d8181f2f27d735e537bd8..9cfc1ac4ad90cf0359b7daa60f80d28b5dcb5fc5 100644 GIT binary patch literal 38 qcmZQjNwhFDOExe_)ip3QN!3j=GBMFLHB3p;H2?u)GZTZf6bk^T^$6ww literal 38 qcmZQjNwhFDOExe_)ip3Qw$x2aG)dA;G)*zkH2?t#UAh}C$3;z%fBK$_Mv#@s(ClK`YZ`_aj z+j{6v(`NY2FQr950)?g~$i*0HR1v9EB$>w;OQ@1FWoJR8p;*I^q&g6wq^91Z8n|f9 xu_zXFH4<56_%Q8grF!;B2<%?A>;V4!K$ExN8hyzh_Qblskpv*Yvi`2p01F3kV{ delta 163 zcmV~$yA8rH5CG6b0tt{nshHz@_MPJ{9Yavr_Ypf#kRhlLLm)*g#Q=0jyf;tt^x6;o zX*mqP^-Uw?Ag-lKKotQCShz(n7q2CqusIGtr%|s%QM^ntv tidP&HWHhyr9HlByF!E{!$kAJ7Ev%xuZqs#r`L^qMxgRgv)${%M`~ficFjN2l diff --git a/sampleApps/goatdroid/OWASP-GoatDroid-0.9/dbs/herdfinancial/db.lck b/sampleApps/goatdroid/OWASP-GoatDroid-0.9/dbs/herdfinancial/db.lck index 304cdbc6cf130534dffef2cb6fd3fa91bbf34545..ef0986ef99cf136c3bce81125d2c9fd487ad02bb 100644 GIT binary patch literal 38 qcmZQjNlHpeF)%Q-&^0hLN!3j;v`Eu6H8e}oH2?t005`y2!#Lu diff --git a/sampleApps/goatdroid/OWASP-GoatDroid-0.9/dbs/herdfinancial/log/log.ctrl b/sampleApps/goatdroid/OWASP-GoatDroid-0.9/dbs/herdfinancial/log/log.ctrl new file mode 100644 index 0000000000000000000000000000000000000000..5fb54fe47a730fd912be45d48a486fbca2f56e46 GIT binary patch literal 48 hcmZQzU}#`qVBiE|7~ldjI2eT3ykG(_dV!`uBLF4a0$2b5 literal 0 HcmV?d00001 diff --git a/sampleApps/goatdroid/OWASP-GoatDroid-0.9/dbs/herdfinancial/log/log1.dat b/sampleApps/goatdroid/OWASP-GoatDroid-0.9/dbs/herdfinancial/log/log1.dat new file mode 100644 index 0000000000000000000000000000000000000000..b6625342add42deb6380fc136eb97af26419bc82 GIT binary patch literal 1048576 zcmeIu!3_W)00Ob|>DG>}#swUpB*4Gbs^;m