コード例 #1
0
class UserEnum:

    _instance = None
    logger = None
    target = None
    request = None

    def __new__(cls):
        # Creating Logger as a Singleton and init the colored output
        if cls._instance is None:
            cls._instance = super(UserEnum, cls).__new__(cls)
            cls._instance.init_userenum()
        return cls._instance

    def init_userenum(self):
        self.logger = Logger().get_logger()
        self.target = Target()
        self.request = Request()

    def user_enumeration(self):
        self.logger.debug("user_enumeration")
        url = "%s%s" % (self.target.url, constants.SHAREPOINT_SITEUSER_API_URL)

        # Starting User Enumeration
        try:
            r = self.request.request_get(url)
            if r.status_code != '200':
                self.logger.warning(
                    "User enumeration API is unreachable or current account is not authorized :("
                )
            else:
                xml = BeautifulSoup(r.text.encode("utf-8"), "lxml")
                for child in xml.find_all("m:properties"):

                    info_sid_issuer = child.find("d:userid")
                    found_user = {}
                    found_user["login name"] = child.find("d:loginname").text
                    found_user["title"] = child.find("d:title").text
                    found_user["isSiteAdmin"] = child.find(
                        "d:issiteadmin").text
                    if [t_child for t_child in info_sid_issuer.children]:
                        found_user["sid"] = info_sid_issuer.find(
                            "d:nameid").text
                        found_user["issuer"] = info_sid_issuer.find(
                            "d:nameidissuer").text
                    self.target.found_users.append(found_user)
                    self.logger.info("#################")
                    for key in found_user:
                        logger.info("%s : %s" (key, found_user[key]))
                    self.logger.info("#################")

        except Exception:
            raise ValueError("Unhandled exception in user_enumeration.")
コード例 #2
0
class BruteForce:
    
    _instance = None
    logger = None
    target = None
    request = None
    domain = None
    dict_user = None
    dict_password = None

    def __new__(cls, domain, dict_user, dict_password):
        # Creating Logger as a Singleton and init the colored output
        if cls._instance is None:
            cls._instance = super(BruteForce, cls).__new__(cls)
            cls._instance.init_bruteforce(domain, dict_user, dict_password)
        return cls._instance

    def init_bruteforce(self, domain, dict_user, dict_password):
        self.logger = Logger().get_logger()
        self.target = Target()
        self.request = Request()
        self.domain = domain
        self.dict_user = dict_user
        self.dict_password = dict_password
        self.logger.debug("init_bruteforce")

    def bruteforce(self):
        self.logger.debug("Starting bruteforce")

        url = "%s%s" % (self.target.url,constants.SHAREPOINT_DEFAULT_URL)
        if not path.exists(self.dict_user):
            raise ValueError("User file does not exists (wrong path?)")
        if not path.exists(self.dict_password):
            raise ValueError("Password file does not exists (wrong path?)")

        file_user = open(self.dict_user, "r")
        file_password = open(self.dict_password, "r")

        # save the current session
        tmp = self.request.session

        # Starting bruteforce
        for user in file_user:
            user = user.rstrip()
            for passwd in file_password:
                passwd = passwd.rstrip()

                # create a new session for each request
                self.request.init_requests(self.domain, user, passwd)

                try:
                    r = self.request.request_get(url)
                    if str(r.status_code)[0] != '4':
                        self.logger.debug("Found user and password: %s - %s" % (user, passwd))
                        self.target.credentials.append({"username":user,"password":passwd})
                except Exception as e:
                    raise ValueError("Unhandled error during running the brute force.")

            # restore the index of the file
            file_password.seek(0)

        # restore the old session
        self.request.session = tmp

        file_user.close()
        file_password.close()
コード例 #3
0
class Sharepoint:
    _instance = None
    logger = None
    target = None
    request = None

    def __new__(cls):
        # Creating Logger as a Singleton and init the colored output
        if cls._instance is None:
            cls._instance = super(Sharepoint, cls).__new__(cls)
            cls._instance.init_sharepoint()
        return cls._instance

    def init_sharepoint(self):
        self.logger = Logger().get_logger()
        self.target = Target()
        self.request = Request()

    def check_availability(self):
        self.logger.debug("check_availability")
        try:
            r = self.request.request_get(self.target.url)

            if r.status_code != 200:
                self.logger.warning("Please take attention, the target answered with %i code." % r.status_code)

        except Exception:
            raise ValueError("Unhandled error on check_availability().")

        return r

    def check_iis_target(self, headers):
        self.logger.debug("check_iis_target")
        # Detection by header parse
        detected_version_iis = detect_server_by_headers(headers)
        if detected_version_iis:
            self.target.server = detected_version_iis
            self.logger.debug("Server version Detected (headers parse): {}".format(detected_version_iis))

        # detect the technology if present
        detected_tec = detect_tec_by_headers(headers)
        if detected_tec:
            self.target.technology = detected_tec
            self.logger.debug("Technology detected (headers parse): {}".format(detected_tec))

    def check_share_point(self, headers):
        self.logger.debug("check_share_point")
        # Detection by header parse
        detected_version_share_point = self.detect_sharepoint_by_headers(headers)
        if detected_version_share_point:
            self.logger.debug("SharePoint version Detected (headers parse): {}".format(detected_version_share_point))

        # Detection by conf file parse #
        if not detected_version_share_point:
            detected_version_share_point = self.detect_sharepoint_by_servicefile()
            if detected_version_share_point:
                self.logger.debug(
                    "SharePoint version Detected (service.cnf parse): {}".format(detected_version_share_point))

        self.get_version(detected_version_share_point)



    def detect_sharepoint_by_headers(self, headers):
        self.logger.debug("detect_sharepoint_by_headers")
        useful_headers = [header for header in headers if "sharepoint" in header.lower()]
        if "MicrosoftSharePointTeamServices" in headers.keys():
            version = headers["MicrosoftSharePointTeamServices"].split(";")[0].split(":")[0]
            return version
        elif len(useful_headers) > 0:
            self.logger.warning(
                "Header %s was found, it may not bring the exact version." % headers[useful_headers[0]].replace("\r\n",
                                                                                                                ""))
        return None

    def detect_sharepoint_by_servicefile(self):
        self.logger.debug("detect_sharepoint_by_servicefile")
        version = None
        for service_url in constants.SHAREPOINT_SERVICE_URLS:
            try:

                # request the url and save the data into the session variable
                r = self.request.request_get(self.target.url + service_url)

                if r.status_code == 200:
                    if "vti_extenderversion" in r.text:
                        version = r.text.split("vti_extenderversion:SR|")[1].replace("\n", "")
                        break
                    if "vti_buildversion" in r.text:
                        version = r.text.split("vti_extenderversion:SR|")[1].replace("\n", "")
                        break

            except Exception:
                raise ValueError("Unhandled error detect_sharepoint_by_servicefile().")

        return version

    def get_version(self,patch_number):


        _patch_tokens = patch_number.split(".")
        _major_version = int(_patch_tokens[0])
        _minor_version = int(_patch_tokens[1])
        _build_version = int(_patch_tokens[3])
        _patch_number = "%s.%s.%s" % (_major_version,_minor_version,_build_version)
        _last_version = ""
        _last_date = ""
        db_version = {
            "version": "",
            "date": ""
        }



        with open('%s%sversions.csv' % (constants.DATABASE_FOLDER, os.path.sep),"r") as file_versions:

            for line in file_versions:

                _line_tokens = line.split(",")
                _checked_version = _line_tokens[0].split(".")
                _checked_version_date = _line_tokens[2]

                #### if there are not enough tokens, we skip it #######

                if(len(_checked_version)<4):
                    continue

                #### Extract major, minor and build version #######

                _checked_version_major = int(_checked_version[0])
                _checked_version_minor = int(_checked_version[1])
                _checked_version_build = int(_checked_version[2])

                #### reformat checked version date #######

                if(_checked_version_date!="N/A"):
                    _checked_version_date = datetime.strptime(_checked_version_date, "%Y %B %d")

                #### reformat checked version structure #######

                _checked_version = "%s.%s.%s" % (_checked_version_major,_checked_version_minor,_checked_version_build)

                #### check if we found a version #######

                if(_checked_version == _patch_number):
                    db_version["version"] = _checked_version
                    db_version["date"] = _checked_version_date
                    self.logger.info("Version details found.")
                    break

                #### if not a suitable version is found, we return the closer one (since they are ordered) #######

                if((_major_version > _checked_version_major) or (_major_version == _checked_version_major and _build_version > _checked_version_build)):

                    db_version["version"] = _checked_version
                    db_version["date"] = _checked_version_date
                    self.logger.info("Version could not be found, performing best guess.")
                    break

        self.target.sharepoint = db_version
コード例 #4
0
class CheckSoapApi:

    _instance = None
    logger = None
    target = None
    request = None

    def __new__(cls):
        # Creating Logger as a Singleton and init the colored output
        if cls._instance is None:
            cls._instance = super(CheckSoapApi, cls).__new__(cls)
            cls._instance.init_soap_api()
        return cls._instance

    def init_soap_api(self):
        self.logger = Logger().get_logger()
        self.target = Target()
        self.request = Request()

    def check_soap_api(self, detailed):
        self.logger.debug("starting check_soap_api")
        url = self.target.url
        # TODO check more https://docs.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ms467069
        for path in constants.SHAREPOINT_ASMX_PATHS:
            self.check_soap_availability(
                constants.SHAREPOINT_ASMX_START_PATH % (url, path), detailed)
        for path in constants.SHAREPOINT_SVC_PATHS:
            self.check_soap_availability(
                constants.SHAREPOINT_SVC_START_PATH % (url, path), detailed)

    def check_soap_availability(self, url, detailed):
        self.logger.debug("starting check_soap_availability")
        try:
            # request the url and save the data into the session variable
            r = self.request.request_get(url)

            if r.status_code == 200:
                self.logger.info("%s is reachable :)." % url)
            elif r.status_code == 401:
                self.logger.warning("%s unauthorized :(." % url)
                return False
        except Exception:
            raise ValueError("Unhandled error check_soap_availability().")

        if detailed:
            client = Client(url,
                            transport=Transport(session=self.request.session))
            for service in client.wsdl.services.values():
                for port in service.ports.values():
                    for operation in port.binding._operations.values():
                        parameters = {}
                        if operation.input.body:
                            for parameter in operation.input.body.type.elements:
                                parameters[parameter[0]] = xsd.SkipValue
                            with client.settings(raw_response=True):
                                response = client.service[operation.name](
                                    **parameters)
                                if str(response.status_code)[0] == "2":
                                    self.logger.info(
                                        "--- Available method: %s" %
                                        operation.name)
                                if str(response.status_code)[0] == "5":
                                    self.logger.info(
                                        "--- Maybe available (double check) method: %s"
                                        % operation.name)