├── tmp └── urls.txt ├── reports └── .gitkeep ├── plugins ├── plugin_example │ └── frida.js ├── hide_app_icon_plugin │ ├── plugin.py │ └── frida.js ├── location_spoofer_plugin │ ├── plugin.py │ └── frida.js ├── library_plugin │ ├── frida.js │ ├── lib │ │ └── Library.py │ └── plugin.py ├── json_plugin │ ├── frida.js │ ├── lib │ │ └── Json.py │ └── plugin.py ├── strings_plugin │ ├── lib │ │ └── String.py │ ├── frida.js │ └── plugin.py ├── proxy_plugin │ ├── lib │ │ └── Proxy.py │ ├── frida.js │ └── plugin.py ├── base64_plugin │ ├── lib │ │ └── Base64.py │ └── plugin.py ├── file_interaction_plugin │ ├── lib │ │ └── File.py │ ├── frida.js │ └── plugin.py ├── socket_plugin │ ├── lib │ │ └── Socket.py │ ├── plugin.py │ └── frida.js ├── delete_file_plugin │ ├── lib │ │ └── DeletedFiles.py │ ├── plugin.py │ └── frida.js ├── log_plugin │ ├── lib │ │ └── Log.py │ ├── frida.js │ └── plugin.py ├── shared_preferences_plugin │ ├── lib │ │ └── SharedPreferences.py │ ├── frida.js │ └── plugin.py ├── hash_plugin │ ├── lib │ │ └── Hash.py │ ├── frida.js │ └── plugin.py ├── anti_emulator_plugin │ ├── lib │ │ └── AntiEmulator.py │ └── plugin.py ├── tcpdump_plugin │ ├── lib │ │ └── TCPDump.py │ └── plugin.py ├── proxy_url_plugin │ ├── lib │ │ └── ProxyURL.py │ └── plugin.py ├── cipher_plugin │ ├── lib │ │ └── Cipher.py │ ├── frida.js │ └── plugin.py └── dexclassloader_plugin │ ├── lib │ └── DexClassLoader.py │ └── plugin.py ├── external └── containers │ ├── .gitattributes │ ├── MANIFEST.in │ ├── js │ ├── jwt-provider │ │ ├── .gitignore │ │ ├── requirements.txt │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── gen-passwords.py │ │ └── jwt-provider.py │ ├── public │ │ ├── favicon.ico │ │ ├── manifest.json │ │ └── index.html │ ├── protoc-plugin │ │ ├── README.MD │ │ └── Makefile │ ├── src │ │ ├── components │ │ │ ├── emulator │ │ │ │ ├── style.styl │ │ │ │ ├── views │ │ │ │ │ ├── logcat_view.js │ │ │ │ │ ├── simple_png_view.js │ │ │ │ │ └── webrtc_view.js │ │ │ │ └── net │ │ │ │ │ └── logcat.js │ │ │ └── copyright.js │ │ ├── App.test.js │ │ ├── index.css │ │ ├── index.js │ │ ├── App.css │ │ ├── App.js │ │ └── logo.svg │ ├── develop │ │ ├── README.md │ │ ├── Dockerfile.mac │ │ ├── Dockerfile.unix │ │ └── envoy.yaml │ ├── .gitignore │ ├── .dockerignore │ ├── docker │ │ ├── nginx.Dockerfile │ │ ├── envoy.Dockerfile │ │ ├── docker-compose.yaml │ │ ├── docker-compose-with-adb.yaml │ │ └── certs │ │ │ ├── self_sign.crt │ │ │ └── self_sign.key │ ├── develop.sh │ └── package.json │ ├── emu │ ├── __init__.py │ └── templates │ │ ├── README.md │ │ ├── default.pa │ │ └── avd │ │ ├── Pixel2.ini │ │ └── Pixel2.avd │ │ └── config.ini │ ├── pyproject.toml │ ├── aemu-container.code-workspace │ ├── tox.ini │ ├── run.sh │ ├── setup.cfg │ ├── run-with-gpu.sh │ ├── CONTRIBUTING.md │ ├── configure.sh │ ├── tests │ └── e2e │ │ ├── utils.py │ │ └── test_launch_containers.py │ ├── .gitignore │ └── create_web_container.sh ├── lib ├── model │ ├── TargetFiles.py │ ├── Rendering.py │ ├── Analysis.py │ ├── Key.py │ ├── database │ │ └── Database.py │ ├── Url.py │ └── Application.py ├── modules │ └── Module.py ├── receiver │ ├── Receiver.py │ ├── Screenrecord.py │ ├── Proxy.py │ └── TCPDump.py ├── adb │ ├── Physical.py │ └── DockerEmulator.py ├── proxy │ └── HttpProxy.py └── report │ └── ReportGenerator.py ├── assets ├── final.gif └── AVD_example.png ├── templates ├── report │ ├── fragments │ │ ├── plugins │ │ │ ├── Base64.jinja │ │ │ ├── Cipher.jinja │ │ │ ├── File.jinja │ │ │ ├── Hash.jinja │ │ │ ├── Json.jinja │ │ │ ├── Library.jinja │ │ │ ├── Log.jinja │ │ │ ├── Socket.jinja │ │ │ ├── String.jinja │ │ │ ├── DeletedFiles.jinja │ │ │ ├── ProxyURL.jinja │ │ │ ├── DexClassLoader.jinja │ │ │ └── SharedPreferences.jinja │ │ ├── application │ │ │ └── description.jinja │ │ ├── footer.jinja │ │ ├── app_info.jinja │ │ ├── sidebar.jinja │ │ ├── summary.jinja │ │ └── head.jinja │ └── index.jinja ├── fragments │ ├── body.jinja │ ├── footer.jinja │ ├── applications.jinja │ ├── application │ │ ├── keys.jinja │ │ └── urls.jinja │ ├── summary.jinja │ ├── head.jinja │ └── plugins.jinja └── index.jinja ├── dep ├── dist │ └── img │ │ ├── avatar.png │ │ ├── icons.png │ │ ├── photo1.png │ │ ├── photo2.png │ │ ├── photo3.jpg │ │ ├── photo4.jpg │ │ ├── prod-1.jpg │ │ ├── prod-2.jpg │ │ ├── prod-3.jpg │ │ ├── prod-4.jpg │ │ ├── prod-5.jpg │ │ ├── avatar04.png │ │ ├── avatar2.png │ │ ├── avatar3.png │ │ ├── avatar5.png │ │ ├── boxed-bg.jpg │ │ ├── boxed-bg.png │ │ ├── credit │ │ ├── visa.png │ │ ├── cirrus.png │ │ ├── mestro.png │ │ ├── paypal.png │ │ ├── paypal2.png │ │ ├── mastercard.png │ │ └── american-express.png │ │ ├── AdminLTELogo.png │ │ ├── user1-128x128.jpg │ │ ├── user2-160x160.jpg │ │ ├── user3-128x128.jpg │ │ ├── user4-128x128.jpg │ │ ├── user5-128x128.jpg │ │ ├── user6-128x128.jpg │ │ ├── user7-128x128.jpg │ │ ├── user8-128x128.jpg │ │ └── default-150x150.png ├── fontawesome-free │ ├── webfonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.ttf │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ ├── fa-solid-900.woff2 │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.woff │ │ └── fa-regular-400.woff2 │ └── css │ │ ├── solid.min.css │ │ ├── brands.min.css │ │ ├── regular.min.css │ │ ├── brands.css │ │ ├── solid.css │ │ └── regular.css ├── datatables-responsive │ └── js │ │ ├── responsive.bootstrap4.min.js │ │ └── responsive.bootstrap4.js └── datatables-bs4 │ └── js │ └── dataTables.bootstrap4.min.js ├── out ├── platform-tools │ └── adb ├── default.pa └── avd │ ├── Pixel2.ini │ └── Pixel2.avd │ └── config.ini ├── config.py ├── frida_scripts └── lib │ ├── common_functions.js │ └── hooks.js ├── scripts ├── install_cert.sh └── uninstall.py ├── package.json ├── .gitignore ├── requirements.txt ├── tests └── database_test.py ├── main.py └── config └── config.ini /tmp/urls.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /reports/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/plugin_example/frida.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /external/containers/.gitattributes: -------------------------------------------------------------------------------- 1 | emu/_version.py export-subst 2 | -------------------------------------------------------------------------------- /lib/model/TargetFiles.py: -------------------------------------------------------------------------------- 1 | # TODO : Store modified files informations -------------------------------------------------------------------------------- /external/containers/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include versioneer.py 2 | include emu/_version.py 3 | -------------------------------------------------------------------------------- /assets/final.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/assets/final.gif -------------------------------------------------------------------------------- /templates/report/fragments/plugins/Base64.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /templates/report/fragments/plugins/Cipher.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /templates/report/fragments/plugins/File.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /templates/report/fragments/plugins/Hash.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /templates/report/fragments/plugins/Json.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /templates/report/fragments/plugins/Library.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /templates/report/fragments/plugins/Log.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /templates/report/fragments/plugins/Socket.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /templates/report/fragments/plugins/String.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /external/containers/js/jwt-provider/.gitignore: -------------------------------------------------------------------------------- 1 | passwd 2 | jwt_secrets_priv.jwks 3 | jwt_secrets_pub.jwks 4 | -------------------------------------------------------------------------------- /templates/report/fragments/plugins/DeletedFiles.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /templates/report/fragments/plugins/ProxyURL.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /assets/AVD_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/assets/AVD_example.png -------------------------------------------------------------------------------- /dep/dist/img/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/avatar.png -------------------------------------------------------------------------------- /dep/dist/img/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/icons.png -------------------------------------------------------------------------------- /dep/dist/img/photo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/photo1.png -------------------------------------------------------------------------------- /dep/dist/img/photo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/photo2.png -------------------------------------------------------------------------------- /dep/dist/img/photo3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/photo3.jpg -------------------------------------------------------------------------------- /dep/dist/img/photo4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/photo4.jpg -------------------------------------------------------------------------------- /dep/dist/img/prod-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/prod-1.jpg -------------------------------------------------------------------------------- /dep/dist/img/prod-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/prod-2.jpg -------------------------------------------------------------------------------- /dep/dist/img/prod-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/prod-3.jpg -------------------------------------------------------------------------------- /dep/dist/img/prod-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/prod-4.jpg -------------------------------------------------------------------------------- /dep/dist/img/prod-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/prod-5.jpg -------------------------------------------------------------------------------- /out/platform-tools/adb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/out/platform-tools/adb -------------------------------------------------------------------------------- /templates/report/fragments/plugins/DexClassLoader.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /templates/report/fragments/plugins/SharedPreferences.jinja: -------------------------------------------------------------------------------- 1 | {% include 'fragments/plugins/plugin_template.jinja' %} -------------------------------------------------------------------------------- /dep/dist/img/avatar04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/avatar04.png -------------------------------------------------------------------------------- /dep/dist/img/avatar2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/avatar2.png -------------------------------------------------------------------------------- /dep/dist/img/avatar3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/avatar3.png -------------------------------------------------------------------------------- /dep/dist/img/avatar5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/avatar5.png -------------------------------------------------------------------------------- /dep/dist/img/boxed-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/boxed-bg.jpg -------------------------------------------------------------------------------- /dep/dist/img/boxed-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/boxed-bg.png -------------------------------------------------------------------------------- /dep/dist/img/credit/visa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/credit/visa.png -------------------------------------------------------------------------------- /dep/dist/img/AdminLTELogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/AdminLTELogo.png -------------------------------------------------------------------------------- /dep/dist/img/credit/cirrus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/credit/cirrus.png -------------------------------------------------------------------------------- /dep/dist/img/credit/mestro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/credit/mestro.png -------------------------------------------------------------------------------- /dep/dist/img/credit/paypal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/credit/paypal.png -------------------------------------------------------------------------------- /dep/dist/img/user1-128x128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/user1-128x128.jpg -------------------------------------------------------------------------------- /dep/dist/img/user2-160x160.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/user2-160x160.jpg -------------------------------------------------------------------------------- /dep/dist/img/user3-128x128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/user3-128x128.jpg -------------------------------------------------------------------------------- /dep/dist/img/user4-128x128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/user4-128x128.jpg -------------------------------------------------------------------------------- /dep/dist/img/user5-128x128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/user5-128x128.jpg -------------------------------------------------------------------------------- /dep/dist/img/user6-128x128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/user6-128x128.jpg -------------------------------------------------------------------------------- /dep/dist/img/user7-128x128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/user7-128x128.jpg -------------------------------------------------------------------------------- /dep/dist/img/user8-128x128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/user8-128x128.jpg -------------------------------------------------------------------------------- /dep/dist/img/credit/paypal2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/credit/paypal2.png -------------------------------------------------------------------------------- /dep/dist/img/default-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/default-150x150.png -------------------------------------------------------------------------------- /dep/dist/img/credit/mastercard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/credit/mastercard.png -------------------------------------------------------------------------------- /external/containers/js/jwt-provider/requirements.txt: -------------------------------------------------------------------------------- 1 | pyjwt 2 | flask 3 | flask-cors 4 | absl-py 5 | Flask-HTTPAuth 6 | Werkzeug 7 | JWCrypto -------------------------------------------------------------------------------- /dep/dist/img/credit/american-express.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/dist/img/credit/american-express.png -------------------------------------------------------------------------------- /external/containers/emu/__init__.py: -------------------------------------------------------------------------------- 1 | from ._version import get_versions 2 | 3 | __version__ = get_versions()["version"] 4 | del get_versions 5 | -------------------------------------------------------------------------------- /external/containers/js/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/external/containers/js/public/favicon.ico -------------------------------------------------------------------------------- /dep/fontawesome-free/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/fontawesome-free/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /dep/fontawesome-free/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/fontawesome-free/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /dep/fontawesome-free/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/fontawesome-free/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /dep/fontawesome-free/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/fontawesome-free/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /dep/fontawesome-free/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/fontawesome-free/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /dep/fontawesome-free/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/fontawesome-free/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /dep/fontawesome-free/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/fontawesome-free/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /dep/fontawesome-free/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/fontawesome-free/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /dep/fontawesome-free/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/fontawesome-free/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /dep/fontawesome-free/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/fontawesome-free/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /dep/fontawesome-free/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/fontawesome-free/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /dep/fontawesome-free/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Areizen/Android-Malware-Sandbox/HEAD/dep/fontawesome-free/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /external/containers/js/protoc-plugin/README.MD: -------------------------------------------------------------------------------- 1 | The plugin is taken from: https://github.com/grpc/grpc-web/tree/master/javascript/net/grpc/web @ ffe8e9c 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/model/Rendering.py: -------------------------------------------------------------------------------- 1 | class Rendering: 2 | 3 | def __init__(self, p_analysis, p_plugins): 4 | self.analysis = p_analysis 5 | self.plugins = p_plugins -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | import os 3 | dirname = os.path.dirname(os.path.realpath(__file__)) 4 | 5 | config = configparser.ConfigParser() 6 | config.read(f"{dirname}/config/config.ini") -------------------------------------------------------------------------------- /external/containers/js/src/components/emulator/style.styl: -------------------------------------------------------------------------------- 1 | .btn{ 2 | display:block; 3 | margin-bottom:30px 4 | padding:8px 10px 5 | } 6 | .container{ 7 | margin:20px 8 | 9 | } 10 | -------------------------------------------------------------------------------- /external/containers/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | # Minimum requirements for the build system to execute. 3 | requires = ["setuptools", "wheel"] # PEP 508 specifications. 4 | 5 | [tool.black] 6 | line-length = 120 -------------------------------------------------------------------------------- /templates/fragments/body.jinja: -------------------------------------------------------------------------------- 1 |
2 |

Report of analysis {{ param.analysis.uuid }}

3 | {% include 'fragments/summary.jinja' %} 4 | {% include 'fragments/applications.jinja' %} 5 |
-------------------------------------------------------------------------------- /templates/index.jinja: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% include 'fragments/head.jinja' %} 4 | 5 | 6 | {% include 'fragments/body.jinja' %} 7 | {% include 'fragments/footer.jinja' %} 8 | 9 | -------------------------------------------------------------------------------- /frida_scripts/lib/common_functions.js: -------------------------------------------------------------------------------- 1 | function Where(stack){ 2 | var at = ""; 3 | for(var i = 0; i < stack.length; ++i){ 4 | at += stack[i].toString() + "\n"; 5 | } 6 | return at; 7 | } 8 | 9 | export { Where }; 10 | -------------------------------------------------------------------------------- /external/containers/aemu-container.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "js/src/android_emulation_control" 5 | }, 6 | { 7 | "path": "." 8 | } 9 | ], 10 | "settings": { 11 | "python.formatting.provider": "black" 12 | } 13 | } -------------------------------------------------------------------------------- /external/containers/js/develop/README.md: -------------------------------------------------------------------------------- 1 | This contains an envoy configuration that can be used during development. 2 | It is configured as a gRPC proxy to the emulator running on port 5556. 3 | It will redirect the rest to the npm develop endpoint on port 3000 4 | 5 | 6 | -------------------------------------------------------------------------------- /external/containers/emu/templates/README.md: -------------------------------------------------------------------------------- 1 | The (sub)directories here contain templates that will be used to create the final docker image. 2 | The layout should follow the desired layout in the container. 3 | 4 | Make sure to update setup.py if you add new directories here. 5 | -------------------------------------------------------------------------------- /external/containers/js/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /lib/modules/Module.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | 4 | class Module: 5 | 6 | def __init__(self, device, application): 7 | self.application = application 8 | self.device = device 9 | 10 | def select(self, path): 11 | logging.error("Module:start() should not be called on the superclass") 12 | -------------------------------------------------------------------------------- /scripts/install_cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ca=$1 3 | device_id=$2 4 | 5 | hash=$(openssl x509 -inform PEM -subject_hash_old -in $ca| head -1) 6 | cert_name=$hash.0 7 | 8 | adb -s $device_id root 9 | adb -s $device_id remount 10 | adb -s $device_id push $ca /system/etc/security/cacerts/$cert_name 11 | adb -s $device_id reboot -------------------------------------------------------------------------------- /lib/receiver/Receiver.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | class Receiver: 4 | 5 | def __init__(self,type): 6 | self.type = type 7 | 8 | def start(self): 9 | logging.error("Receiver:start() should not be called directly from superclass !") 10 | 11 | def stop(self): 12 | logging.error("Receiver:start() should not be called directly from superclass !") 13 | -------------------------------------------------------------------------------- /external/containers/js/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /out/default.pa: -------------------------------------------------------------------------------- 1 | # This is a NOP configuration for pulse audio, all audio goes nowhere! 2 | load-module module-null-sink sink_name=NOP sink_properties=device.description=NOP 3 | 4 | # Make pulse accessible on all channels. We only have null audio, and Docker 5 | # should isolate our network anyways. 6 | load-module module-native-protocol-unix auth-anonymous=1 socket=/tmp/pulse-socket 7 | load-module module-native-protocol-tcp auth-anonymous=1 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sandbox_v2", 3 | "version": "1.0.0", 4 | "description": "A simple android sandbox", 5 | "main": "index.js", 6 | "directories": { 7 | "lib": "lib" 8 | }, 9 | "dependencies": { 10 | "frida-compile": "^9.0.3" 11 | }, 12 | "devDependencies": {}, 13 | "scripts": { 14 | "test": "echo \"Error: no test specified\" && exit 1" 15 | }, 16 | "author": "Romain KRAFT", 17 | "license": "ISC" 18 | } 19 | -------------------------------------------------------------------------------- /external/containers/emu/templates/default.pa: -------------------------------------------------------------------------------- 1 | # This is a NOP configuration for pulse audio, all audio goes nowhere! 2 | load-module module-null-sink sink_name=NOP sink_properties=device.description=NOP 3 | 4 | # Make pulse accessible on all channels. We only have null audio, and Docker 5 | # should isolate our network anyways. 6 | load-module module-native-protocol-unix auth-anonymous=1 socket=/tmp/pulse-socket 7 | load-module module-native-protocol-tcp auth-anonymous=1 -------------------------------------------------------------------------------- /external/containers/js/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 5 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /templates/fragments/footer.jinja: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/hide_app_icon_plugin/plugin.py: -------------------------------------------------------------------------------- 1 | import os 2 | import logging 3 | 4 | current_path = os.path.dirname(os.path.realpath(__file__)) 5 | 6 | def onload(): 7 | logging.debug("HideAppIcon:loaded()") 8 | 9 | def onunload(): 10 | logging.debug("HideAppIcon:unloaded()") 11 | 12 | def parse(module, message, data): 13 | pass 14 | 15 | def get_frida_script(): 16 | logging.debug("HideAppIcon:get_frida_script()") 17 | with open(f"{current_path}/frida.js") as f: 18 | return ("HideAppIcon", f.read()) -------------------------------------------------------------------------------- /external/containers/js/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | 5 | import App from './App'; 6 | import * as serviceWorker from './serviceWorker'; 7 | 8 | ReactDOM.render(, document.getElementById('root')); 9 | 10 | // If you want your app to work offline and load faster, you can change 11 | // unregister() to register() below. Note this comes with some pitfalls. 12 | // Learn more about service workers: https://bit.ly/CRA-PWA 13 | serviceWorker.unregister(); 14 | -------------------------------------------------------------------------------- /plugins/location_spoofer_plugin/plugin.py: -------------------------------------------------------------------------------- 1 | import os 2 | import logging 3 | 4 | current_path = os.path.dirname(os.path.realpath(__file__)) 5 | 6 | def onload(): 7 | logging.debug("LocationSpoofer:loaded()") 8 | 9 | def onunload(): 10 | logging.debug("LocationSpoofer:unloaded()") 11 | 12 | def parse(module, message, data): 13 | pass 14 | 15 | def get_frida_script(): 16 | logging.debug("LocationSpoofer:get_frida_script()") 17 | with open(f"{current_path}/frida.js") as f: 18 | return ("LocationSpoofer", f.read()) -------------------------------------------------------------------------------- /external/containers/js/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | *.o 8 | 9 | # testing 10 | coverage 11 | 12 | # production 13 | build 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | protoc-gen-grpc-web 26 | src/android_emulation_control/* 27 | docker/certs/jwt_secrets_pub.jwks 28 | -------------------------------------------------------------------------------- /templates/report/fragments/application/description.jinja: -------------------------------------------------------------------------------- 1 |
2 |

Information: {{ application.package }}

3 |

Application name : {{ application.get_app_name() }}

4 |

Package name : {{ application.package }}

5 |

SHA256 : {{ application.sha256 }}

6 |

Icon :

7 | {{ application.sha256 }}.png 8 |
9 |
-------------------------------------------------------------------------------- /external/containers/js/.dockerignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # grpc/protoc related things. 15 | /grpc-web 16 | /protoc-plugin 17 | /android_emulation_control 18 | 19 | # misc 20 | .DS_Store 21 | .env.local 22 | .env.development.local 23 | .env.test.local 24 | .env.production.local 25 | 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | protoc-gen-grpc-web 30 | -------------------------------------------------------------------------------- /plugins/library_plugin/frida.js: -------------------------------------------------------------------------------- 1 | function hook_lib(){ 2 | 3 | Interceptor.attach(Module.findExportByName(null, 'android_dlopen_ext'),{ 4 | onEnter: function(args){ 5 | // first arg is the path to the library loaded 6 | var library_path = Memory.readCString(args[0]) 7 | var obj = {"plugin": "library", "name" : library_path}; 8 | send(JSON.stringify(obj)); 9 | }, 10 | onLeave: function(args){ 11 | console.log(args) 12 | console.log("[+] Loaded") 13 | } 14 | }) 15 | } 16 | 17 | hook_lib() -------------------------------------------------------------------------------- /lib/model/Analysis.py: -------------------------------------------------------------------------------- 1 | from lib.model import Application 2 | from lib.model.database.Database import Database 3 | 4 | from sqlalchemy import Column, Integer, String, Date 5 | from sqlalchemy.orm import relationship 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class Analysis(Base): 11 | __tablename__ = 'analysis' 12 | 13 | id = Column(Integer, primary_key=True) 14 | uuid = Column(String) 15 | date = Column(Date) 16 | application = relationship("Application") 17 | 18 | def __repr__(self): 19 | return f'' -------------------------------------------------------------------------------- /external/containers/js/docker/nginx.Dockerfile: -------------------------------------------------------------------------------- 1 | # Stage 0, "build-stage", based on Node.js, to build and compile the frontend 2 | FROM tiangolo/node-frontend:10 as build-stage 3 | WORKDIR /app 4 | COPY package*.json /app/ 5 | RUN npm install 6 | COPY ./ /app/ 7 | ARG configuration=production 8 | 9 | RUN npm run build 10 | # Stage 1, based on Nginx, to have only the compiled app, ready for production with Nginx 11 | FROM nginx:1.16 12 | COPY --from=build-stage /app/build/ /usr/share/nginx/html 13 | # Copy the default nginx.conf provided by tiangolo/node-frontend 14 | COPY --from=build-stage /nginx.conf /etc/nginx/conf.d/default.conf -------------------------------------------------------------------------------- /plugins/json_plugin/frida.js: -------------------------------------------------------------------------------- 1 | function jsonHooks(){ 2 | 3 | var jsonObj = Java.use("org.json.JSONObject"); 4 | var jsonArr = Java.use("org.json.JSONArray"); 5 | 6 | var jsonClasses = [jsonObj, jsonArr]; 7 | 8 | jsonClasses.forEach(function(jsonClass, i) { 9 | jsonClass.$init.overload('java.lang.String').implementation = function(str){ 10 | var result = this.$init(str); 11 | var obj = {"plugin": "json", "method": jsonClass.toString() + ".$init('java.lang.String')", "value" : str}; 12 | send(JSON.stringify(obj)); 13 | return result; 14 | } 15 | }); 16 | } 17 | 18 | jsonHooks(); 19 | -------------------------------------------------------------------------------- /external/containers/js/develop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | trap killgroup SIGINT 3 | 4 | killgroup(){ 5 | echo killing... be patient... 6 | docker stop emu-dev-grpc-web 7 | kill 0 8 | } 9 | 10 | cd "$(dirname "$0")" 11 | BUILD_OS=$(uname -s) 12 | case $BUILD_OS in 13 | Darwin) 14 | echo "Building for Mac" 15 | docker build -t emu-dev-web -f develop/Dockerfile.mac develop 16 | ;; 17 | *) 18 | echo "Building for linux" 19 | docker build -t emu-dev-web -f develop/Dockerfile.unix develop 20 | ;; 21 | esac 22 | docker rm emu-dev-grpc-web 23 | docker run -p 8080:8080 -p 8001:8001 --name emu-dev-grpc-web emu-dev-web & 24 | npm start & 25 | wait 26 | -------------------------------------------------------------------------------- /templates/fragments/applications.jinja: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Applications

4 | {% for application in param.analysis.application %} 5 | 6 |
7 |
8 |
9 | {% include 'fragments/application/description.jinja' %} 10 | {% include 'fragments/application/urls.jinja' %} 11 | {% include 'fragments/application/keys.jinja' %} 12 | {% include 'fragments/plugins.jinja' %} 13 | 14 |
15 |
16 |
17 | {% endfor %} 18 |
-------------------------------------------------------------------------------- /external/containers/js/src/components/copyright.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Description of this file. 3 | */ 4 | import React, { Component } from "react"; 5 | import Typography from "@material-ui/core/Typography"; 6 | import Link from "@material-ui/core/Link"; 7 | 8 | export default class Copyright extends Component { 9 | render() { 10 | return ( 11 | 12 | {"Copyright © "} 13 | 14 | Your Website 15 | {" "} 16 | {new Date().getFullYear()} 17 | {"."} 18 | 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /templates/fragments/application/keys.jinja: -------------------------------------------------------------------------------- 1 |
2 |

Keys used

3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {% for key in application.key %} 13 | 14 | 15 | 16 | 17 | {% endfor %} 18 | 19 |
TypeValue
{{ key.type }}{{ key.value }}
20 |
-------------------------------------------------------------------------------- /dep/fontawesome-free/css/solid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:"Font Awesome 5 Free";font-weight:900} -------------------------------------------------------------------------------- /templates/fragments/summary.jinja: -------------------------------------------------------------------------------- 1 |
2 |

Summary :

3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% for application in param.analysis.application %} 14 | 15 | 16 | 17 | 18 | 19 | {% endfor %} 20 | 21 |
HashPackage NameLink
{{ application.sha256 }}{{ application.package }}Link
22 |
-------------------------------------------------------------------------------- /dep/fontawesome-free/css/brands.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands";font-weight:400} -------------------------------------------------------------------------------- /dep/fontawesome-free/css/regular.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-family:"Font Awesome 5 Free";font-weight:400} -------------------------------------------------------------------------------- /plugins/library_plugin/lib/Library.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class Library(Base): 11 | __tablename__ = 'library' 12 | 13 | id = Column(Integer, primary_key=True) 14 | date = Column(DateTime, default=datetime.datetime.utcnow) 15 | name = Column(String) 16 | application_id = Column(Integer, ForeignKey('application.id')) 17 | 18 | def __init__(self, name): 19 | self.name = name 20 | 21 | def __repr__(self): 22 | return f'' 23 | -------------------------------------------------------------------------------- /plugins/strings_plugin/lib/String.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class String(Base): 11 | __tablename__ = 'string' 12 | 13 | id = Column(Integer, primary_key=True) 14 | date = Column(DateTime, default=datetime.datetime.utcnow) 15 | value = Column(String) 16 | application_id = Column(Integer, ForeignKey('application.id')) 17 | 18 | def __init__(self, value): 19 | self.value = value 20 | 21 | def __repr__(self): 22 | return f'' 23 | -------------------------------------------------------------------------------- /plugins/proxy_plugin/lib/Proxy.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class Proxy(Base): 11 | __tablename__ = 'proxy' 12 | 13 | id = Column(Integer, primary_key=True) 14 | date = Column(DateTime, default=datetime.datetime.utcnow) 15 | method = Column(String) 16 | application_id = Column(Integer, ForeignKey('application.id')) 17 | 18 | def __init__(self, p_method): 19 | self.method = p_method 20 | 21 | def __repr__(self): 22 | return f'' 23 | -------------------------------------------------------------------------------- /lib/model/Key.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class Key(Base): 11 | __tablename__ = 'key' 12 | 13 | id = Column(Integer, primary_key=True) 14 | type = Column(String) 15 | value = Column(String) 16 | date = Column(DateTime, default=datetime.datetime.utcnow) 17 | application_id = Column(Integer, ForeignKey('application.id')) 18 | 19 | def __init__(self, type, key): 20 | self.type = type 21 | self.value = key 22 | 23 | def __repr__(self): 24 | return f'' 25 | -------------------------------------------------------------------------------- /plugins/strings_plugin/frida.js: -------------------------------------------------------------------------------- 1 | function to_string(){ 2 | 3 | const String = Java.use('java.lang.String'); 4 | const StringBuilder = Java.use('java.lang.StringBuilder'); 5 | 6 | String.toString.implementation = function(){ 7 | const x = this.toString() 8 | if(x.length > 5){ 9 | var obj = {"plugin": "to_string", "string" : x}; 10 | send(JSON.stringify(obj)) 11 | } 12 | return x 13 | } 14 | 15 | StringBuilder.toString.implementation = function(){ 16 | const x = this.toString() 17 | if(x.length > 5){ 18 | var obj = {"plugin": "to_string", "string" : x}; 19 | send(JSON.stringify(obj)) 20 | } 21 | return x 22 | } 23 | 24 | } 25 | 26 | to_string(); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Sphinx documentation 10 | docs/_build/ 11 | 12 | # PyBuilder 13 | target/ 14 | 15 | # Jupyter Notebook 16 | .ipynb_checkpoints 17 | 18 | # IPython 19 | profile_default/ 20 | ipython_config.py 21 | 22 | # pyenv 23 | .python-version 24 | 25 | # celery beat schedule file 26 | celerybeat-schedule 27 | 28 | # SageMath parsed files 29 | *.sage.py 30 | 31 | # Environments 32 | .env 33 | .venv 34 | env/ 35 | venv/ 36 | ENV/ 37 | env.bak/ 38 | venv.bak/ 39 | 40 | 41 | node_modules/ 42 | package-lock.json 43 | frida-scripts/_agent.js 44 | .idea/ 45 | 46 | 47 | **/*.db 48 | foo.db 49 | tmp/*.txt 50 | reports/* 51 | frida_scripts/*.js 52 | **/*.zip 53 | **/*.apk -------------------------------------------------------------------------------- /lib/receiver/Screenrecord.py: -------------------------------------------------------------------------------- 1 | from lib.receiver.Receiver import Receiver 2 | import logging 3 | 4 | 5 | class Screenrecord(Receiver): 6 | 7 | def __init__(self, module, report_path, device): 8 | Receiver.__init__(self,"ScreenrecordReceiver") 9 | self.module = module 10 | self.device = device 11 | self.file_path = f"/data/local/tmp/screenrecord_{self.module.application.package}.mp4" 12 | self.out_directory = f"{report_path}" 13 | 14 | def start(self): 15 | logging.debug("Screenrecord:start()") 16 | self.device.start_screenrecord(self.file_path) 17 | 18 | 19 | def stop(self): 20 | logging.debug("Screenrecord:stop()") 21 | self.device.get_screenrecord_file(self.file_path, self.out_directory) 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /lib/adb/Physical.py: -------------------------------------------------------------------------------- 1 | from .Device import Device 2 | 3 | import subprocess 4 | import logging 5 | 6 | 7 | class Physical(Device): 8 | 9 | def __init__(self,path_config,configuration,): 10 | Device.__init__(self, path_config, configuration, "Physical") 11 | 12 | def start(self): 13 | ''' 14 | Set the device-id to the current plugged phone 15 | :return: 16 | ''' 17 | logging.debug("Physiscal:launching_application()") 18 | devices = self.list_devices() 19 | 20 | if(len(devices['physical']) != 1): 21 | logging.error("No physical device plugged or too many ( only one can be pluuged at time )") 22 | else: 23 | self.device_id = devices['physical'][0] 24 | logging.debug(f"Device id : {self.device_id}") -------------------------------------------------------------------------------- /plugins/json_plugin/lib/Json.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class Json(Base): 11 | __tablename__ = 'json' 12 | 13 | id = Column(Integer, primary_key=True) 14 | date = Column(DateTime, default=datetime.datetime.utcnow) 15 | method = Column(String) 16 | value = Column(String) 17 | application_id = Column(Integer, ForeignKey('application.id')) 18 | 19 | def __init__(self, method, value): 20 | self.method = method 21 | self.value = value 22 | 23 | def __repr__(self): 24 | return f'' 25 | -------------------------------------------------------------------------------- /dep/fontawesome-free/css/brands.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Brands'; 7 | font-style: normal; 8 | font-weight: 400; 9 | font-display: block; 10 | src: url("../webfonts/fa-brands-400.eot"); 11 | src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); } 12 | 13 | .fab { 14 | font-family: 'Font Awesome 5 Brands'; 15 | font-weight: 400; } 16 | -------------------------------------------------------------------------------- /dep/fontawesome-free/css/solid.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Free'; 7 | font-style: normal; 8 | font-weight: 900; 9 | font-display: block; 10 | src: url("../webfonts/fa-solid-900.eot"); 11 | src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); } 12 | 13 | .fa, 14 | .fas { 15 | font-family: 'Font Awesome 5 Free'; 16 | font-weight: 900; } 17 | -------------------------------------------------------------------------------- /dep/fontawesome-free/css/regular.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Free'; 7 | font-style: normal; 8 | font-weight: 400; 9 | font-display: block; 10 | src: url("../webfonts/fa-regular-400.eot"); 11 | src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); } 12 | 13 | .far { 14 | font-family: 'Font Awesome 5 Free'; 15 | font-weight: 400; } 16 | -------------------------------------------------------------------------------- /external/containers/tox.ini: -------------------------------------------------------------------------------- 1 | # content of: tox.ini , put in same dir as setup.py 2 | [tox] 3 | envlist = py27,py37 4 | 5 | [testenv] 6 | # install pytest in the virtualenv where commands will be executed 7 | deps = pytest 8 | py27: mock 9 | commands = 10 | # NOTE: you can run any command line tool here - not just tests 11 | pytest 12 | 13 | [pytest] 14 | norecursedirs = docs *.egg-info .git src js venv py2 py.tox 15 | log_format = %(asctime)s {%(pathname)s:%(lineno)d} %(levelname)s %(message)s 16 | log_date_format = %Y-%m-%d %H:%M:%S 17 | log_level = INFO 18 | markers = 19 | slow: marks tests as slow (deselect with '-m "not slow"') 20 | e2e: marks test as end to end, requires docker (deselect with '-m "not e2e"') 21 | linux: marks test that require kvm & docker (deselect with '-m "not linux"') 22 | -------------------------------------------------------------------------------- /out/avd/Pixel2.ini: -------------------------------------------------------------------------------- 1 | # Copyright 2019 - The Android Open Source Project 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | # Basic config used to create an avd for now. 17 | avd.ini.encoding=UTF-8 18 | path.rel=avd/Pixel2.avd 19 | path=/android-home/Pixel2.avd 20 | target=android-28 -------------------------------------------------------------------------------- /external/containers/js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^4.5.0", 7 | "@material-ui/icons": "^4.4.3", 8 | "@material-ui/styles": "^4.5.0", 9 | "axios": "^0.19.0", 10 | "google-protobuf": "^3.10.0", 11 | "grpc-web": "^1.0.6", 12 | "react": "^16.10.2", 13 | "react-dom": "^16.10.2", 14 | "react-scripts": "^3.2.0" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "eslintIgnore": [ 24 | "**" 25 | ] 26 | }, 27 | "browserslist": [ 28 | ">0.2%", 29 | "not dead", 30 | "not ie <= 11", 31 | "not op_mini all" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /external/containers/emu/templates/avd/Pixel2.ini: -------------------------------------------------------------------------------- 1 | # Copyright 2019 - The Android Open Source Project 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | # Basic config used to create an avd for now. 17 | avd.ini.encoding=UTF-8 18 | path.rel=avd/Pixel2.avd 19 | path=/android-home/Pixel2.avd 20 | target=android-{{api}} -------------------------------------------------------------------------------- /external/containers/run.sh: -------------------------------------------------------------------------------- 1 | # Copyright 2019 The Android Open Source Project 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | CONTAINER_ID=$1 15 | shift 16 | PARAMS="$@" 17 | docker run -e "ADBKEY=$(cat ~/.android/adbkey)" -e "EMULATOR_PARAMS=${PARAMS}" --device /dev/kvm --publish 5556:5556/tcp --publish 5555:5555/tcp ${CONTAINER_ID} 18 | -------------------------------------------------------------------------------- /plugins/base64_plugin/lib/Base64.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class Base64(Base): 11 | __tablename__ = 'base64' 12 | 13 | id = Column(Integer, primary_key=True) 14 | date = Column(DateTime, default=datetime.datetime.utcnow) 15 | method = Column(String) 16 | value = Column(String) 17 | stack = Column(String) 18 | application_id = Column(Integer, ForeignKey('application.id')) 19 | 20 | def __init__(self, p_method, base64Value, stack): 21 | self.method = p_method 22 | self.value = base64Value 23 | self.stack = stack 24 | 25 | def __repr__(self): 26 | return f'' 27 | -------------------------------------------------------------------------------- /plugins/file_interaction_plugin/lib/File.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class File(Base): 11 | __tablename__ = 'file' 12 | 13 | id = Column(Integer, primary_key=True) 14 | date = Column(DateTime, default=datetime.datetime.utcnow) 15 | method = Column(String) 16 | name = Column(String) 17 | stack = Column(String) 18 | application_id = Column(Integer, ForeignKey('application.id')) 19 | 20 | def __init__(self, method, name, stack): 21 | self.method = method 22 | self.name = name 23 | self.stack = stack 24 | 25 | def __repr__(self): 26 | return f'' 27 | -------------------------------------------------------------------------------- /templates/report/fragments/footer.jinja: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /external/containers/js/develop/Dockerfile.mac: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | #FROM envoyproxy/envoy:latest 15 | FROM envoyproxy/envoy:latest 16 | 17 | # Workaround for linux missing host.docker.internal 18 | COPY ./envoy.yaml /etc/envoy/envoy.yaml 19 | CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml 20 | -------------------------------------------------------------------------------- /external/containers/setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | # This includes the license file(s) in the wheel. 3 | # https://wheel.readthedocs.io/en/stable/user_guide.html#including-license-files-in-the-generated-wheel-file 4 | license_files = LICENSE 5 | 6 | [bdist_wheel] 7 | # This flag says to generate wheels that support both Python 2 and Python 8 | # 3. If your code will not run unchanged on both Python 2 and 3, you will 9 | # need to generate separate wheels for each Python version that you 10 | # support. Removing this line (or setting universal to 0) will prevent 11 | # bdist_wheel from trying to make a universal wheel. For more see: 12 | # https://packaging.python.org/guides/distributing-packages-using-setuptools/#wheels 13 | universal=1 14 | 15 | 16 | [versioneer] 17 | VCS = git 18 | style = pep440 19 | versionfile_source = emu/_version.py 20 | tag_prefix = 21 | parentdir_prefix = emu-docker- 22 | -------------------------------------------------------------------------------- /plugins/socket_plugin/lib/Socket.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class Socket(Base): 11 | __tablename__ = 'socket' 12 | 13 | id = Column(Integer, primary_key=True) 14 | date = Column(DateTime, default=datetime.datetime.utcnow) 15 | method = Column(String) 16 | value = Column(String) 17 | stack = Column(String) 18 | application_id = Column(Integer, ForeignKey('application.id')) 19 | 20 | def __init__(self, method, value, stack): 21 | self.method = method 22 | self.value = value 23 | self.stack = stack 24 | 25 | 26 | def __repr__(self): 27 | return f'' 28 | -------------------------------------------------------------------------------- /plugins/delete_file_plugin/lib/DeletedFiles.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class DeletedFiles(Base): 11 | __tablename__ = 'deletedFiles' 12 | 13 | id = Column(Integer, primary_key=True) 14 | date = Column(DateTime, default=datetime.datetime.utcnow) 15 | method = Column(String) 16 | name = Column(String) 17 | stack = Column(String) 18 | application_id = Column(Integer, ForeignKey('application.id')) 19 | 20 | def __init__(self, p_method, p_name, p_stack): 21 | self.method = p_method 22 | self.name = p_name 23 | self.stack = p_stack 24 | 25 | def __repr__(self): 26 | return f'' 27 | -------------------------------------------------------------------------------- /external/containers/js/jwt-provider/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2019 - The Android Open Source Project 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | FROM debian:stretch-slim 15 | RUN apt-get update -y 16 | RUN apt-get install -y python-pip python-dev build-essential 17 | COPY . /app 18 | WORKDIR /app 19 | RUN pip install -r requirements.txt 20 | ENTRYPOINT ["python"] 21 | CMD ["jwt-provider.py"] 22 | -------------------------------------------------------------------------------- /external/containers/js/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 40vmin; 8 | pointer-events: none; 9 | } 10 | 11 | .App-header { 12 | background-color: #282c34; 13 | min-height: 100vh; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: center; 18 | font-size: calc(10px + 2vmin); 19 | color: white; 20 | } 21 | 22 | .App-link { 23 | color: #61dafb; 24 | } 25 | 26 | .container { 27 | width: 100%; 28 | height: 768px; 29 | margin: auto; 30 | padding: 10px; 31 | } 32 | 33 | .leftpanel { 34 | float: left; 35 | height:768px; 36 | width: 440px; 37 | } 38 | .rightpanel { 39 | margin-left: 15%; 40 | height:768px; 41 | } 42 | @keyframes App-logo-spin { 43 | from { 44 | transform: rotate(0deg); 45 | } 46 | to { 47 | transform: rotate(360deg); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /external/containers/js/develop/Dockerfile.unix: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | #FROM envoyproxy/envoy:latest 15 | FROM envoyproxy/envoy:latest 16 | 17 | # Workaround for linux missing host.docker.internal 18 | COPY ./envoy.yaml /etc/envoy/envoy.yaml 19 | CMD echo "172.17.0.1 host.docker.internal" >> /etc/hosts && /usr/local/bin/envoy -c /etc/envoy/envoy.yaml 20 | -------------------------------------------------------------------------------- /plugins/log_plugin/lib/Log.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class Log(Base): 11 | __tablename__ = 'log' 12 | 13 | id = Column(Integer, primary_key=True) 14 | date = Column(DateTime, default=datetime.datetime.utcnow) 15 | method = Column(String) 16 | tag = Column(String) 17 | message = Column(String) 18 | stacktrace = Column(String) 19 | application_id = Column(Integer, ForeignKey('application.id')) 20 | 21 | def __init__(self, method, tag, message, stacktrace): 22 | self.method = method 23 | self.tag = tag 24 | self.message = message 25 | self.stacktrace = stacktrace 26 | 27 | def __repr__(self): 28 | return f'' 29 | -------------------------------------------------------------------------------- /plugins/shared_preferences_plugin/lib/SharedPreferences.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class SharedPreferences(Base): 11 | __tablename__ = 'shared_preferences' 12 | 13 | id = Column(Integer, primary_key=True) 14 | date = Column(DateTime, default=datetime.datetime.utcnow) 15 | method = Column(String) 16 | file_path = Column(String) 17 | value = Column(String) 18 | application_id = Column(Integer, ForeignKey('application.id')) 19 | 20 | def __init__(self, method, file_path, value): 21 | self.method = method 22 | self.file_path = file_path 23 | self.value = value 24 | 25 | def __repr__(self): 26 | return f'' 27 | -------------------------------------------------------------------------------- /plugins/shared_preferences_plugin/frida.js: -------------------------------------------------------------------------------- 1 | function notifyNewSharedPreference() { 2 | var sharedPrefs = Java.use('android.app.SharedPreferencesImpl'); 3 | 4 | sharedPrefs.$init.overload('java.io.File', 'int').implementation = function(file, mode) { 5 | var result = this.$init(file, mode); 6 | var obj = {"plugin": "sharedprefs", "method": "SharedPreferencesImpl.$init('java.lang.String', 'int')", "file": file.getAbsolutePath(), "value": mode}; 7 | send(JSON.stringify(obj)); 8 | return result; 9 | } 10 | 11 | Java.use('android.app.SharedPreferencesImpl$EditorImpl').putString.overload('java.lang.String', 'java.lang.String').implementation = function(k, v) { 12 | var obj = {"plugin": "sharedprefs", "method":"SharedPreferences.Editor.putString('java.lang.String', 'java.lang.String')", "file": 'NULL', "value": k+" = "+v}; 13 | send(JSON.stringify(obj)); 14 | return this.putString(k, v); 15 | } 16 | } 17 | 18 | 19 | notifyNewSharedPreference(); -------------------------------------------------------------------------------- /external/containers/js/docker/envoy.Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | #FROM envoyproxy/envoy:latest 15 | FROM envoyproxy/envoy:latest 16 | 17 | COPY ./envoy.yaml /etc/envoy/envoy.yaml 18 | ADD certs/self_sign.crt /etc/cert.crt 19 | ADD certs/self_sign.key /etc/key.key 20 | ADD certs/jwt_secrets_pub.jwks /etc/jwt_secrets_pub.jwks 21 | CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml 22 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | androguard 2 | asn1crypto 3 | backcall 4 | blinker 5 | brotlipy 6 | certifi 7 | cffi 8 | chardet 9 | click 10 | colorama 11 | coloredlogs 12 | console-menu 13 | cryptography<2.5,>=2.1.4 14 | cycler 15 | decorator 16 | docker 17 | frida 18 | future 19 | h11 20 | h2 21 | hpack 22 | hyperframe 23 | idna 24 | ipython-genutils 25 | jedi 26 | Jinja2 27 | kaitaistruct 28 | kiwisolver 29 | ldap3 30 | lxml 31 | MarkupSafe==2.0.1 32 | matplotlib 33 | mitmproxy==5.0.0 34 | networkx 35 | numpy 36 | parso 37 | passlib 38 | pexpect 39 | pickleshare 40 | prompt-toolkit 41 | ptyprocess 42 | pyasn1 43 | pycparser 44 | pydot 45 | Pygments 46 | pyOpenSSL==19.0.0 47 | pyparsing 48 | pyperclip 49 | python-dateutil 50 | requests 51 | ruamel.yaml 52 | six 53 | sortedcontainers 54 | SQLAlchemy 55 | SQLAlchemy-Utils 56 | tornado 57 | tqdm 58 | traitlets 59 | urlfetch 60 | urllib3 61 | urwid<2.1,>=2.0.1 62 | wcwidth 63 | websocket-client 64 | wsproto<0.15.0,>=0.14.0 65 | scapy 66 | filetype 67 | -------------------------------------------------------------------------------- /plugins/hash_plugin/lib/Hash.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class Hash(Base): 11 | __tablename__ = 'hash' 12 | 13 | id = Column(Integer, primary_key=True) 14 | date = Column(DateTime, default=datetime.datetime.utcnow) 15 | algorithm = Column(String) 16 | input_value = Column(String) 17 | output_value = Column(String) 18 | application_id = Column(Integer, ForeignKey('application.id')) 19 | 20 | def __init__(self, algo, input_value, output_value): 21 | self.algorithm = algo 22 | self.input_value = input_value 23 | self.output_value = output_value 24 | 25 | 26 | def __repr__(self): 27 | return f'' 28 | -------------------------------------------------------------------------------- /plugins/anti_emulator_plugin/lib/AntiEmulator.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from lib.model.database.Database import Database 4 | 5 | from sqlalchemy import Column, Integer, String, Date, DateTime, ForeignKey 6 | 7 | Base = Database.get_declarative_base() 8 | 9 | 10 | class AntiEmulator(Base): 11 | __tablename__ = 'anti_emulator' 12 | 13 | id = Column(Integer, primary_key=True) 14 | property = Column(String) 15 | real_value = Column(String) 16 | return_value = Column(String) 17 | date = Column(DateTime, default=datetime.datetime.utcnow) 18 | application_id = Column(Integer, ForeignKey('application.id')) 19 | 20 | def __init__(self, property, real_value, return_value): 21 | self.property = property 22 | self.real_value = real_value 23 | self.return_value = return_value 24 | 25 | 26 | def __repr__(self): 27 | return f'' 28 | -------------------------------------------------------------------------------- /templates/fragments/head.jinja: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Report of analysis {{ param.analysis.uuid }} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 21 | -------------------------------------------------------------------------------- /templates/fragments/plugins.jinja: -------------------------------------------------------------------------------- 1 |
2 |

Plugins

3 | 4 | {% for pluginName, listPluginInstance in param.plugins.items() %} 5 |
6 |

{{ pluginName }}

7 | 8 | 9 | 10 | 11 | {% for key in listPluginInstance[0].keys() %} 12 | 13 | {% endfor %} 14 | 15 | 16 | 17 | {% for pluginInstance in listPluginInstance %} 18 | 19 | {% for value in pluginInstance.values() %} 20 | 21 | {% endfor %} 22 | 23 | {% endfor %} 24 | 25 |
{{ key }}
{{ value|e -}}
26 | {% endfor %} 27 | 28 |
-------------------------------------------------------------------------------- /plugins/hash_plugin/frida.js: -------------------------------------------------------------------------------- 1 | var md_id; 2 | var input_value; 3 | 4 | function hashHook(){ 5 | var MessageDigest = Java.use("java.security.MessageDigest"); 6 | 7 | MessageDigest.update.overload('[B').implementation = function(input){ 8 | var result = this.update(input); 9 | md_id = this.hashCode(); // method from Object 10 | input_value = new Uint8Array(input); 11 | return result; 12 | } 13 | 14 | MessageDigest.digest.overload().implementation = function(){ 15 | var result = this.digest(); 16 | if (this.hashCode() == md_id){ 17 | var hexInput = Buffer.from(input_value).toString('hex'); 18 | var hexOutput = Buffer.from(new Uint8Array(result)).toString('hex'); 19 | var obj = {"plugin": "hash", "algo" : this.getAlgorithm(), "input_value": hexInput, "output_value": hexOutput}; 20 | send(JSON.stringify(obj)); 21 | md_id = ''; 22 | input_value = ''; 23 | } 24 | return result; 25 | } 26 | } 27 | 28 | hashHook(); -------------------------------------------------------------------------------- /plugins/tcpdump_plugin/lib/TCPDump.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import re 3 | import socket 4 | from urllib.parse import urlparse 5 | 6 | from sqlalchemy import Column, Integer, String, Boolean, ForeignKey, DateTime 7 | 8 | from lib.model.database.Database import Database 9 | 10 | import binascii 11 | import base64 12 | 13 | Base = Database.get_declarative_base() 14 | 15 | 16 | class TCPDump(Base): 17 | __tablename__ = 'tcpdump' 18 | id = Column(Integer, primary_key=True) 19 | date = Column(DateTime, default=datetime.datetime.utcnow) 20 | summary = Column(String) 21 | show = Column(String) 22 | hexdump = Column(String) 23 | file_path = Column(String) 24 | application_id = Column(Integer, ForeignKey('application.id')) 25 | 26 | def __init__(self, msg): 27 | self.summary = msg['summary'] 28 | self.show = msg['show'] 29 | self.hexdump = msg['hexdump'] 30 | self.file_path = msg['file_path'] 31 | 32 | def __repr__(self): 33 | return f'' -------------------------------------------------------------------------------- /templates/report/fragments/app_info.jinja: -------------------------------------------------------------------------------- 1 |
2 |
3 | {% if application.url|length > 1 %} 4 | {% include 'fragments/application/urls.jinja' %} 5 | {% endif %} 6 | {% if application.key|length > 1 %} 7 | {% include 'fragments/application/keys.jinja' %} 8 | {% endif %} 9 |
10 | 11 | {% set colors = ['danger', 'info', 'warning', 'success', 'primary', 'secondary'] %} 12 | 13 | 14 | {% for pluginName, listPluginInstance in param.plugins.items() %} 15 | 16 | {% set loop_index = loop.index %} 17 | {% include 'fragments/plugins/' + pluginName + '.jinja' %} 18 | {% endfor %} 19 |
20 |
21 |
22 |
23 |
-------------------------------------------------------------------------------- /out/avd/Pixel2.avd/config.ini: -------------------------------------------------------------------------------- 1 | AvdId=Pixel2 2 | PlayStore.enabled=False 3 | avd.ini.displayname=Pixel2 4 | avd.ini.encoding=UTF-8 5 | # Real Pixel2 ships with 32GB 6 | disk.dataPartition.size=512MB 7 | fastboot.forceColdBoot=no 8 | hw.accelerometer=yes 9 | hw.audioInput=yes 10 | hw.battery=yes 11 | hw.camera.back=emulated 12 | hw.camera.front=emulated 13 | hw.cpu.ncore=4 14 | hw.dPad=no 15 | hw.device.hash2=MD5:bc5032b2a871da511332401af3ac6bb0 16 | hw.device.manufacturer=Google 17 | hw.gps=yes 18 | hw.gpu.enabled=yes 19 | hw.gpu.mode=auto 20 | hw.initialOrientation=Portrait 21 | hw.keyboard=yes 22 | hw.mainKeys=no 23 | hw.ramSize=4096 24 | hw.sensors.orientation=yes 25 | hw.sensors.proximity=yes 26 | hw.trackBall=no 27 | runtime.network.latency=none 28 | runtime.network.speed=full 29 | vm.heapSize=512 30 | tag.display=Google APIs 31 | # Set some 32 | hw.lcd.density=440 33 | hw.lcd.height=1920 34 | hw.lcd.width=1080 35 | # Unused 36 | # hw.sdCard=yes 37 | # sdcard.size=512M 38 | 39 | tag.id=android 40 | abi.type=x86_64 41 | hw.cpu.arch=x86_64 42 | image.sysdir.1=system-images/android/x86_64/ 43 | 44 | # End of default configuration 45 | -------------------------------------------------------------------------------- /lib/proxy/HttpProxy.py: -------------------------------------------------------------------------------- 1 | from mitmproxy import ctx 2 | import os 3 | import json 4 | from mitmproxy import tcp 5 | 6 | dirname = os.path.dirname(os.path.realpath(__file__)) + "/../../" 7 | 8 | class Addon(): 9 | 10 | def __init__(self): 11 | self.url_json = {'plugin': 'proxyURL', 'url' : '', 'req_method' : '', 'resp_code': '', 'request': '', 'response': ''} 12 | 13 | def request(self, flow): 14 | ''' 15 | Addon used by mitmproxy that store each url in a file 16 | :param flow: 17 | :return: 18 | ''' 19 | self.url_json["url"] = flow.request.pretty_url 20 | self.url_json["req_method"] = flow.request.method 21 | self.url_json['request'] = flow.request.text 22 | 23 | 24 | def response(self, flow): 25 | self.url_json['resp_code'] = flow.response.status_code 26 | self.url_json['response'] = flow.response.text 27 | 28 | with open(f"{dirname}tmp/urls.txt","a") as f: 29 | ctx.log.info(f"Writing url : {self.url_json['url']}") 30 | f.write(json.dumps(self.url_json)) 31 | f.write('\n') 32 | 33 | addons = [ 34 | Addon() 35 | ] -------------------------------------------------------------------------------- /scripts/uninstall.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import frida 3 | import subprocess 4 | import sys 5 | 6 | if len(sys.argv) !=2: 7 | print(f"[-] Usage : python {sys.argv[0]} ") 8 | sys.exit(-1) 9 | 10 | def message(message, data): 11 | print(message) 12 | 13 | device = frida.get_usb_device() 14 | 15 | 16 | session_gatekeeper = device.attach("system_server") 17 | 18 | # see : https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java?q=DELETE_FAILED_DEVICE_POLICY_MANAGER&ss=android%2Fplatform%2Fsuperproject 19 | script_gatekeeper = session_gatekeeper.create_script(""" 20 | Java.perform(function(){ 21 | const PackageManager = Java.use("com.android.server.pm.PackageManagerService") 22 | 23 | PackageManager.isPackageDeviceAdmin.implementation = function(packageName, userId){ 24 | console.log("isPackageDeviceAdmin called !"); 25 | return false; 26 | } 27 | }) 28 | """) 29 | script_gatekeeper.on("message", message) 30 | script_gatekeeper.load() 31 | 32 | pid = subprocess.Popen(["adb","uninstall", sys.argv[1]]) 33 | pid.wait() -------------------------------------------------------------------------------- /external/containers/js/docker/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | services: 3 | 4 | front-envoy: 5 | build: 6 | context: . 7 | dockerfile: envoy.Dockerfile 8 | networks: 9 | - envoymesh 10 | expose: 11 | - "8080" 12 | - "8001" 13 | - "8443" 14 | ports: 15 | - "80:8080" 16 | - "443:8443" 17 | - "8001:8001" 18 | 19 | emulator: 20 | build: 21 | context: ../../src 22 | dockerfile: Dockerfile 23 | networks: 24 | envoymesh: 25 | aliases: 26 | - emulator 27 | devices: [/dev/kvm] 28 | shm_size: 128M 29 | expose: 30 | - "5556" 31 | 32 | jwt_signer: 33 | build: 34 | context: ../jwt-provider 35 | dockerfile: Dockerfile 36 | networks: 37 | envoymesh: 38 | aliases: 39 | - jwt_signer 40 | expose: 41 | - "8080" 42 | 43 | 44 | 45 | nginx: 46 | build: 47 | context: .. 48 | dockerfile: docker/nginx.Dockerfile 49 | networks: 50 | envoymesh: 51 | aliases: 52 | - nginx 53 | expose: 54 | - "80" 55 | 56 | 57 | networks: 58 | envoymesh: {} 59 | -------------------------------------------------------------------------------- /external/containers/emu/templates/avd/Pixel2.avd/config.ini: -------------------------------------------------------------------------------- 1 | AvdId=Pixel2 2 | PlayStore.enabled={{playstore}} 3 | avd.ini.displayname=Pixel2 4 | avd.ini.encoding=UTF-8 5 | # Real Pixel2 ships with 32GB 6 | disk.dataPartition.size=512MB 7 | fastboot.forceColdBoot=no 8 | hw.accelerometer=yes 9 | hw.audioInput=yes 10 | hw.battery=yes 11 | hw.camera.back=emulated 12 | hw.camera.front=emulated 13 | hw.cpu.ncore=4 14 | hw.dPad=no 15 | hw.device.hash2=MD5:bc5032b2a871da511332401af3ac6bb0 16 | hw.device.manufacturer=Google 17 | hw.gps=yes 18 | hw.gpu.enabled=yes 19 | hw.gpu.mode=auto 20 | hw.initialOrientation=Portrait 21 | hw.keyboard=yes 22 | hw.mainKeys=no 23 | hw.ramSize=4096 24 | hw.sensors.orientation=yes 25 | hw.sensors.proximity=yes 26 | hw.trackBall=no 27 | runtime.network.latency=none 28 | runtime.network.speed=full 29 | vm.heapSize=512 30 | tag.display=Google APIs 31 | # Set some 32 | hw.lcd.density=440 33 | hw.lcd.height=1920 34 | hw.lcd.width=1080 35 | # Unused 36 | # hw.sdCard=yes 37 | # sdcard.size=512M 38 | 39 | tag.id={{tag}} 40 | abi.type={{abi}} 41 | hw.cpu.arch={{cpu}} 42 | image.sysdir.1=system-images/android/{{abi}}/ 43 | 44 | # End of default configuration 45 | 46 | -------------------------------------------------------------------------------- /templates/fragments/application/urls.jinja: -------------------------------------------------------------------------------- 1 |
2 |

Urls reached

3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {% for url in application.url %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {% endfor %} 32 | 33 |
SchemeIpDomainPathQueryStack TraceIs up ?Nb of times ?Date
{{ url.scheme }}{{ url.ip }}{{ url.domain }}{{ url.uri }}{{ url.query }}{{ url.stacktrace }}{{ url.is_up }}{{ url.nb }}{{ url.date }}
34 |
-------------------------------------------------------------------------------- /external/containers/run-with-gpu.sh: -------------------------------------------------------------------------------- 1 | # Copyright 2019 The Android Open Source Project 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This launcher will force the emulator to use hardware acceleration. In order to use this you will need to have 16 | # installed the nvida docker container drivers (https://github.com/NVIDIA/nvidia-docker) 17 | CONTAINER_ID=$1 18 | shift 19 | PARAMS="$@" 20 | # Allow display access from the container. 21 | xhost +si:localuser:root 22 | docker run --gpus all -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -e "ADBKEY=$(cat ~/.android/adbkey)" -e "EMULATOR_PARAMS=-gpu host ${PARAMS}" --device /dev/kvm --publish 5556:5556/tcp --publish 5555:5555/tcp ${CONTAINER_ID} 23 | -------------------------------------------------------------------------------- /lib/model/database/Database.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import create_engine 2 | from sqlalchemy.ext.declarative import declarative_base 3 | from sqlalchemy.orm import sessionmaker 4 | 5 | 6 | class Database: 7 | _engine = None 8 | _configuration = None 9 | _base = None 10 | _session = None 11 | 12 | @staticmethod 13 | def set_configuration(configuration): 14 | Database._configuration = configuration 15 | 16 | @staticmethod 17 | def get_engine(): 18 | if Database._engine is None: 19 | Database._engine = create_engine(Database._configuration['DATABASE'].get('url'), echo=False, connect_args={'check_same_thread': False}) 20 | return Database._engine 21 | 22 | @staticmethod 23 | def get_declarative_base(): 24 | if Database._base is None: 25 | Database._base = declarative_base() 26 | return Database._base 27 | 28 | @staticmethod 29 | def get_session(): 30 | if Database._session is None : 31 | Database.get_declarative_base().metadata.create_all(Database.get_engine()) 32 | Session = sessionmaker(bind=Database.get_engine()) 33 | Database._session = Session() 34 | return Database._session 35 | -------------------------------------------------------------------------------- /external/containers/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows 28 | [Google's Open Source Community Guidelines](https://opensource.google.com/conduct/). 29 | -------------------------------------------------------------------------------- /plugins/proxy_url_plugin/lib/ProxyURL.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import re 3 | import socket 4 | from urllib.parse import urlparse 5 | 6 | from sqlalchemy import Column, Integer, String, Boolean, ForeignKey, DateTime 7 | 8 | from lib.model.database.Database import Database 9 | 10 | import binascii 11 | import base64 12 | 13 | Base = Database.get_declarative_base() 14 | 15 | 16 | class ProxyURL(Base): 17 | __tablename__ = 'proxyURL' 18 | id = Column(Integer, primary_key=True) 19 | date = Column(DateTime, default=datetime.datetime.utcnow) 20 | response_code = Column(String) 21 | req_method = Column(String) 22 | url = Column(String) 23 | request = Column(String) 24 | response = Column(String) 25 | application_id = Column(Integer, ForeignKey('application.id')) 26 | 27 | def __init__(self, msg_json): 28 | self.response_code = msg_json['resp_code'] 29 | self.req_method = msg_json['req_method'] 30 | self.url = msg_json['url'] 31 | self.request = msg_json['request'] 32 | self.response = msg_json['response'] 33 | 34 | def __repr__(self): 35 | return f'' -------------------------------------------------------------------------------- /external/containers/js/protoc-plugin/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | CXX = g++ 16 | PROTOHEADER=$(shell pkg-config --variable prefix protobuf)/include 17 | PROTOLIB=$(shell pkg-config --variable prefix protobuf)/lib 18 | CPPFLAGS += -I/usr/local/include -pthread -I$(PROTOHEADER) 19 | CXXFLAGS += -std=c++11 20 | LDFLAGS += -L/usr/local/lib -L$(PROTOLIB) -lprotoc -lprotobuf -lpthread -ldl 21 | 22 | all: protoc-gen-grpc-web 23 | 24 | protoc-gen-grpc-web: grpc_generator.o 25 | $(CXX) $^ $(LDFLAGS) -o $@ 26 | 27 | install: protoc-gen-grpc-web 28 | install protoc-gen-grpc-web /usr/local/bin/protoc-gen-grpc-web 29 | 30 | clean: 31 | rm -f *.o protoc-gen-grpc-web 32 | -------------------------------------------------------------------------------- /dep/datatables-responsive/js/responsive.bootstrap4.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Bootstrap 4 integration for DataTables' Responsive 3 | ©2016 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(c){"function"===typeof define&&define.amd?define(["jquery","datatables.net-bs4","datatables.net-responsive"],function(a){return c(a,window,document)}):"object"===typeof exports?module.exports=function(a,b){a||(a=window);if(!b||!b.fn.dataTable)b=require("datatables.net-bs4")(a,b).$;b.fn.dataTable.Responsive||require("datatables.net-responsive")(a,b);return c(b,a,a.document)}:c(jQuery,window,document)})(function(c){var a=c.fn.dataTable,b=a.Responsive.display,g=b.modal,e=c('