示例#1
0
    def run(self, *args,
            **kwargs) -> ScriptResponse.success or ScriptResponse.error:
        """
        Take email and look it up in breaches.
        Breaches info is provided by monitor.firefox.com (haveibeenpwned.com)
        """
        email = kwargs.get("email")
        if not isinstance(email, str):
            return ScriptResponse.error(
                result=None,
                message=
                f"Can't make query. Incorrect input type (got {type(email)}, need {type('')}).",
            )
        email_hash = sha1(email.encode()).hexdigest()

        with Session() as session:
            session.headers.update(Defaults.headers)

            resp = session.get(r"https://monitor.firefox.com")
            if resp.status_code != 200:
                return ScriptResponse.error(
                    message=
                    f"Can't look up email in breaches. Server response: {resp.status_code}.",
                )

            csrf_re = findall(r'(?<="_csrf" value=").*(?=">)', resp.text)
            if not csrf_re:
                return ScriptResponse.error(message=f"Can't find csrf token.")

            csrf = csrf_re[0]
            resp = session.post(
                r"https://monitor.firefox.com/scan",
                data={
                    "_csrf": csrf,
                    "emailHash": email_hash
                },
            )
            if resp.status_code != 200:
                return ScriptResponse.error(
                    message=
                    f"Can't look up email in breaches. Server response: {resp.status_code}.",
                )

        breaches = []
        soup = BeautifulSoup(resp.text, "html.parser")
        for breach in soup.find_all("a", class_="breach-card"):
            title = breach.find("span", class_="breach-title").text
            info = breach.find_all("span", class_="breach-value")
            if len(info) < 2:
                continue
            breaches.append({
                "title": title,
                "date": info[0].text,
                "compromised": info[1].text
            })

        return ScriptResponse.success(
            result=breaches,
            message=f"Email {email} is found in {len(breaches)} breaches.",
        )
示例#2
0
 async def __run(*args, **kwargs):
     try:
         username = kwargs.get("username")
         bad_symbols = list(set(username).intersection(string.punctuation))
         if bad_symbols:
             return ScriptResponse.error(
                 message=f"Invalid characters: {', '.join(bad_symbols)}")
         social = asyncio.Queue()
         for site in Networks().net:
             await social.put("https://{site}{username}".format(
                 site=site, username=username))
         temp_result = await asyncio.gather(*[
             asyncio.create_task(check_nickname_async(username, social))
             for _ in range(10)
         ])
         result = {username: []}
         for sub_massive in temp_result:
             for site in sub_massive:
                 result[username].append(site)
         return ScriptResponse.success(
             result=result,
             message="Found {count} user accounts".format(
                 count=len(result[username])),
         )
     except Exception as err:
         return ScriptResponse.error(message=str(err))
示例#3
0
    def run(self, *args, **kwargs):
        """
        Returns hash of favicon.ico of given url.
        :param args: args from core runner
        :param kwargs: kwargs from core runner
        :return: ScriptResponse message
        """
        url = kwargs.get("url")

        try:
            response = get(f"{url}/favicon.ico")
        except RequestException as req_err:
            return ScriptResponse.error(
                result=None,
                message=f"Can't connect to {url}!"
                f"Error message: {req_err}",
            )

        favicon = encodebytes(response.content)
        favicon_hash = hash(favicon)

        return ScriptResponse.success(
            result=favicon_hash,
            message=f"Successfully made favicon hash of {url}! "
            f"Use https://www.shodan.io/search?query=http.favicon.hash:{favicon_hash}",
        )
示例#4
0
 def run(self, *args, **kwargs) -> ScriptResponse.success or ScriptResponse.error:
     email = kwargs.get("email")
     result = self.email_verifier(email)
     if not result:
         return ScriptResponse.success(
             result=result, message=f"Sorry, email {email} does not exist"
         )
     return ScriptResponse.success(result=result, message=f"Email {email} exists")
示例#5
0
    def exec_script(
        path: str or Path,
        script_class: str = "Runner",
        function: str = "run",
        args: list or None = None,
        kwargs: dict or None = None,
    ) -> ScriptResponse or dict:
        """
        Load and exec python script
        :param path: name of the script to load
        :param script_class: class to initialize when script is started
        :param function: name of the function to run from script
        :param args: args to pass into the module
        :param kwargs: kwargs to pass into the module
        :return: result of the function
        """
        if args is None:
            args = []
        if kwargs is None:
            kwargs = {}
        loader = SourceFileLoader(fullname=script_class, path=str(path))
        module = ModuleType(name=loader.name)
        result = {"script": Path(path).parent.stem}

        # Check if don't forget to install all the dependencies, and that module can
        # be successfully loaded.

        # fmt: off
        try:
            loader.exec_module(module)
        except Exception as unexp_err:
            message = f"Unexpected module error: {str(unexp_err)}"
            logger.warning(message)
            result.update(ScriptResponse.error(message=message))
            return result
        # fmt: on

        # Module successfully loaded. We can set some module-scope variables that
        # we missed.
        module.__file__ = path

        # Execute the runner and check if something goes wrong.

        # fmt: off
        try:
            module_class = getattr(module, script_class)
            applicable = set(module_class.required).intersection(kwargs.keys())
            # If the current script is not applicable for the current set of arguments - skip it
            if not applicable:
                return
            class_instance = module_class(logger=path.parent.stem)
            result.update(getattr(class_instance, function)(*args, **kwargs))
        except Exception as unexp_err:
            result.update(ScriptResponse.error(message=f"Unexpected execution error: {str(unexp_err)}"))
        # fmt: on

        # In any possible case, return result from the module or ScriptResponse.error + script name
        return result
示例#6
0
 def run(self, *args, **kwargs) -> ScriptResponse.success or ScriptResponse.error:
     """
     Main runner function for the script
     :param args: args from core runner
     :param kwargs: kwargs from core runner
     :return: ScriptResponse message
     """
     result = self.user_greeting(user=kwargs.get("username"))
     if not result:
         return ScriptResponse.success(message="Sorry, no greetings for this user!")
     return ScriptResponse.success(
         result=result,
         message=f"Successfully finished! (args: {args}, kwargs: {kwargs})",
     )
示例#7
0
    def run(self, *args, **kwargs) -> ScriptResponse.success or ScriptResponse.error:
        # fmt: off
        response = self.__get_ip_info(kwargs.get("ip"))

        try:
            msg = (
                "Query successful!"
                if response["status"] == "success"
                else "Query failed!"
            )
            # we don't need duplicate status, let's get rid of it
            response.pop("status", None)
            return ScriptResponse.success(result=response, message=msg)
        except TypeError as type_err:
            return ScriptResponse.error(message=f"Error occurred while trying to get data: error status")
        except Exception as unexp_err:
            return ScriptResponse.error(message=f"Error occurred while trying to get data: {str(unexp_err)}")
示例#8
0
 def run(self, *args,
         **kwargs) -> ScriptResponse.success or ScriptResponse.error:
     """
     Parses torrents by ip.
     :param args: args from core runner.
     :param kwargs: kwargs from core runner.
     :return: ScriptResponse with dictionary of torrents.
     """
     ip = kwargs.get("ip")
     api_key = kwargs.get("torrent_api_key", Defaults.API_KEY)
     if not ip:
         return ScriptResponse.error(message="No IP was provided")
     response = get(
         f"https://api.antitor.com/history/peer/?ip={ip}&key={api_key}"
     ).json()
     return ScriptResponse.success(message=f"Script finished for {ip}",
                                   result=response)
示例#9
0
 def run(self, *args,
         **kwargs) -> ScriptResponse.success or ScriptResponse.error:
     """
     Return basic success response
     :param args: args
     :param kwargs: kwargs
     :return: ScriptResponse message
     """
     return ScriptResponse.success(message="Script finished")
示例#10
0
 def run(self, *args, **kwargs):
     """
     Returns HTTP response status code
     :param args: args from core runner
     :param kwargs: kwargs from core runner
     :return: ScriptResponse message
     """
     url = kwargs.get("url")
     status = get(url=url).status_code
     return ScriptResponse.success(
         result=status, message=f"Got HTTP response status from {url}")
示例#11
0
 def run(self, *args,
         **kwargs) -> ScriptResponse.success or ScriptResponse.error:
     """
     Main runner function for the script
     :param args: args from core runner
     :param kwargs: kwargs from core runner
     :return: ScriptResponse message
     """
     hostname = kwargs.get("hostname")
     return ScriptResponse.success(result=self.__get_host(hostname),
                                   message="Success")
示例#12
0
    def run(self, *args, **kwargs):
        """
        Try to find http title
        :param args: args from core runner
        :param kwargs: kwargs from core runner
        :return: http title if it's exist
        """
        url = kwargs.get("url")
        try:
            response = requests.get(url, verify=False).text
        except Exception as get_err:
            return ScriptResponse.error(result=None, message=str(get_err))

        search_title = search(r"<title>(.*)</title>", response)
        result = search_title.group(1) if search_title else None
        return ScriptResponse.success(
            result=result,
            message=f"Successfully found the title for {url}"
            if result
            else "Can not get the title or bad url",
        )
示例#13
0
    def run(self, *args,
            **kwargs) -> ScriptResponse.success or ScriptResponse.error:
        """
        Checks Secure, HttpOnly, Prefixed,
        Same-site flags for the
        cookies of a specified URL.
        :param args: args from core runner
        :param kwargs: kwargs from core runner
        :return: ScriptResponse with dictionary
        containing flags mentioned above.
        """

        url = kwargs.get("url")

        if not url:
            return ScriptResponse.error(message="Url was not provided!")

        result = {}

        response = get(url)
        for cookie in response.cookies:
            result[cookie.name] = {
                "Path":
                cookie.path,
                "Secure":
                cookie.secure,
                "HttpOnly":
                self.__has_http_only(cookie),
                "Prefix":
                cookie.name.startswith(
                    ("__Secure-", "__Host-")) if cookie.name else False,
                "Same-Site":
                cookie.__dict__.get("_rest").get("SameSite", "None"),
            }

        return ScriptResponse.success(
            result=result,
            message=f"Successfully finished cookie policy check for {url}",
        )
示例#14
0
 def run(self, *args,
         **kwargs) -> ScriptResponse.success or ScriptResponse.error:
     """
     Main runner function for the script
     :param args: args from core runner
     :param kwargs: kwargs from core runner
     :return: ScriptResponse message
     """
     try:
         result = self.__phone_to_region(phone=kwargs.get("phone"))
     except Exception:
         return ScriptResponse.error(result=None,
                                     message="Something went wrong!")
     result = result.split("~")
     if result[1] != "0":
         return ScriptResponse.success(result=None,
                                       message="Sorry, no such number!")
     return ScriptResponse.success(
         result=(result[-1], result[-2]),
         message=
         f"Found region: {result[-1]} | found operator: {result[-2]} | for phone number {result[0]}",
     )
示例#15
0
    def run(self, *args, **kwargs):
        """
        Returns list of allowed methods. E.g. ['GET', 'POST'].
        Also checks if method is forbidden or somehow filtered.
        Needs url to run.
        :param args: args from core runner
        :param kwargs: kwargs from core runner
        :return: ScriptResponse message
        """
        allowed_methods = []
        filtered_methods = []
        forbidden_methods = []
        server_error = []
        url = kwargs.get("url")

        # Copy original methods list to avoid class variable modifications
        methods = list(Defaults.METHODS)

        # Append random method to check if server is not faking.
        methods.append(get_random_method())

        for method in methods:
            try:
                status = request(method, url).status_code
                method_result = {"method": method, "status": status}

                # 2xx - success
                # 405 - method not allowed
                if 200 <= status < 300:
                    allowed_methods.append(method_result)
                elif status == 405:
                    forbidden_methods.append(method_result)
                else:
                    filtered_methods.append(method_result)
            except RequestException as req_err:
                method_result = {"method": method, "status": req_err}
                server_error.append(method_result)

        return ScriptResponse.success(
            result={
                "allowed": allowed_methods,
                "forbidden": forbidden_methods,
                "filtered": filtered_methods,
                "server_error": server_error,
            },
            message=f"URL: {url} - "
            f"allowed: {len(allowed_methods)}, "
            f"forbidden: {len(forbidden_methods)}, "
            f"filtered: {len(filtered_methods)}, "
            f"server_error: {len(server_error)}",
        )
示例#16
0
 def run(self, *args,
         **kwargs) -> ScriptResponse.success or ScriptResponse.error:
     """
     Main runner function for the script
     :param args: args from core runner
     :param kwargs: kwargs from core runner
     :return: ScriptResponse message
     """
     try:
         tm = time()
         email_gen = EmailGenerator()
         username = kwargs.get("username")
         if not username:
             raise KeyError("EmailGenerator can't work without username!")
         result = email_gen.generate(username)
     except Exception as err:
         return ScriptResponse.error(message=str(err))
     else:
         return ScriptResponse.success(
             result=result,
             message=
             f"Successfully finished! Got {len(result)} logins, script lasted {(time() - tm):.2f} seconds",
         )
示例#17
0
    def run(self, *args,
            **kwargs) -> ScriptResponse.success or ScriptResponse.error:
        """
        Main runner function for the script
        :param args: args from core runner
        :param kwargs: kwargs from core runner
        :return: ScriptResponse message
        """
        try:
            phone = kwargs.get("phone")
            region = kwargs.get("region")
            parsed_num = parse(phone, region)
        except NumberParseException:
            return ScriptResponse.error(
                result=None,
                message="Not viable number or not international format")
        except Exception:
            return ScriptResponse.error(result=None,
                                        message="Something went wrong!")
        try:
            result = [
                phone for phone_format in [
                    PhoneNumberFormat.NATIONAL,
                    PhoneNumberFormat.INTERNATIONAL,
                    PhoneNumberFormat.E164,
                ] for phone in self.__gen_all(
                    format_number(parsed_num, phone_format))
            ]
        except Exception:
            return ScriptResponse.error(result=None,
                                        message="Something went wrong!")

        return ScriptResponse.success(
            result=result,
            message=f"All possible number formats for phone number {phone}",
        )
示例#18
0
 def run(self, *args,
         **kwargs) -> ScriptResponse.success or ScriptResponse.error:
     fullname = kwargs.get("fullname")
     if not fullname:
         return ScriptResponse.error(result="Couldn't run the script",
                                     message="No name was provided")
     response = get(
         "http://www.fedsfm.ru/documents/terrorists-catalog-portal-act")
     if response.status_code != 200:
         return ScriptResponse.error(
             result="Couldn't run the script",
             message="Extremists name base is not available",
         )
     occurences = findall(rf"<li>\d+\. ({fullname.upper()}.*);</li>",
                          response.text)
     return ScriptResponse.success(
         result={
             "found": bool(occurences),
             "occurrences": occurences
         },
         message="Person found on the Russian extremists list"
         if bool(occurences) else
         "Person not found on the Russian extremists list",
     )
示例#19
0
    def run(self, *args,
            **kwargs) -> ScriptResponse.success or ScriptResponse.error:
        """
        A method that performs RDAP lookup. You can get the following information:
        - query - The IP address
        - asn - The Autonomous System Number
        - asn_date - The ASN Allocation date
        - asn_registry - The assigned ASN registry
        - asn_cidr - The assigned ASN CIDR
        - asn_country_code - The assigned ASN country code
        - asn_description - The ASN description
        - network - Network information which consists of the following fields:
            - cidr - Network routing block and IP address belongs to
            - country - Country code registered with the RIR in ISO 3166-1 format
            - end_address - The last IP address in a network block
            - events - List of event dictionaries with the following fields:
                - action - The reason for an event
                - timestamp - The date an event occured in ISO 8601 format
                - actor - The identifier for an event initiator (if any)
            - handle - Unique identifier for a registered object
            - ip_version - IP protocol version (v4 or v6) of an IP address
            - links - HTTP/HTTPS links provided for an RIR object
            - name - he identifier assigned to the network registration for an IP address
            - parent_handle - Unique identifier for the parent network of a registered network
            - start_address - The first IP address in a network block
            - status - List indicating the state of a registered object
            - type - The RIR classification of a registered network
        objects  - The objects (entities) referenced by an RIR network or by other entities with the following fields:
            - contact - Contact information registered with an RIR object. See "contacts" in "nir" section for more
                        info.
            - entities - List of object names referenced by an RIR object. Map these to other objects dictionary keys.
            - events - List of event dictionaries. See "events" in "network" section for more info.
            - events_actor - List of event (no actor) dictionaries
            - handle - Unique identifier for a registered object
            - links - List of HTTP/HTTPS links provided for an RIR object
            - roles - List of roles assigned to a registered object
            - status - List indicating the state of a registered object
        nir  - The National Internet Registry results which consists of the following fields:
            - cidr - Network routing block and IP address belongs to
            - range - Network range an IP address belongs to
            - name - he identifier assigned to the network registration for an IP address
            - handle - Unique identifier for a registered object
            - country - Country code registered with the RIR in ISO 3166-1 format
            - address - The mailing address for a registered network
            - postal_code - The postal code for a registered network
            - nameservers - he nameservers listed for a registered network
            - created - Network registration date in ISO 8601 format
            - updated - Network registration updated date in ISO 8601 format
            - contacts - Dictionary with keys: admin, tech. Values map to contact dictionaries if found:
                - name - The contact’s name
                - organization - The contact’s organization
                - division - The contact’s division of the organization
                - email - Contact email address
                - reply_email - Contact reply email address
                - updated - Updated date in ISO 8601 format
                - phone - Contact phone number
                - fax - Contact fax number
                - title - The contact’s position or job title

        :param args: variable length argument list.
        :param kwargs: arbitrary keyword arguments.

        :return: ScriptResponse.error with error message: returned if IP address is invalid or RDAP query failed.
                 ScriptResponse.success with RDAP lookup results: returned if IP address is valid and RDAP query was
                 successful.
        """

        try:
            ip = self.__validate_ip(kwargs.get("ip"))
        except ValueError:
            return ScriptResponse.error(message="Invalid IP address")

        try:
            rdap = IPWhois(ip).lookup_rdap()
        except Exception as e:
            return ScriptResponse.error(
                message=f"RDAP lookup failed. Unknown error occurred: {str(e)}"
            )

        # notices and remarks sections contains some useless info, let's get rid of it
        rdap["network"].pop("notices", None)

        for obj in rdap["objects"].keys():
            rdap["objects"][obj].pop("notices", None)
            rdap["objects"][obj].pop("remarks", None)

        # entities section contains objects section keys, so we don't need it
        rdap.pop("entities", None)

        return ScriptResponse.success(result=rdap,
                                      message="RDAP lookup successful")
示例#20
0
    def run(self, *args,
            **kwargs) -> ScriptResponse.success or ScriptResponse.error:
        """
        Make a Google search and return top results.
        :param args: user args
        :param kwargs: user kwargs
        :return: ScriptResponse message
        """

        query = kwargs.get("email", "")
        if not isinstance(query, str):
            return ScriptResponse.error(
                result=None,
                message=
                f"Can't make query. Incorrect input type (got {type(query)}, need {type('')}).",
            )

        query = query.replace(" ", "+")
        url = f'https://www.google.com/search?q="{query}"'
        headers = {"User-Agent": Defaults.USER_AGENT}
        resp = get(url, headers=headers)

        for attempt in range(5):
            if resp.status_code == 429:
                time_to_wait = randint(1, 5 + attempt)
                sleep(time_to_wait)
                resp = get(url, headers=headers)
            else:
                break

        if resp.status_code == 413:
            return ScriptResponse.success(
                result=None,
                message=f"Can't make query. Request is too long.",
            )
        elif resp.status_code == 429:
            return ScriptResponse.success(
                result=None,
                message=f"Can't make query. Too many requests.",
            )
        elif resp.status_code != 200:
            return ScriptResponse.success(
                result=None,
                message=
                f"Can't make query. Server response: {resp.status_code}.",
            )

        results = []
        soup = BeautifulSoup(resp.content, "html.parser")
        for g in soup.find_all("div", class_="r"):
            anchors = g.find_all("a")
            if not anchors:
                continue

            link = anchors[0]["href"]
            title = g.find("h3").text
            item = {"title": title, "link": link}
            results.append(item)

        return ScriptResponse.success(result=results,
                                      message="Search finished successfully.")
示例#21
0
    def run(self, *args, **kwargs) -> ScriptResponse.success or ScriptResponse.error:
        try:
            country_code, phone_number = self.__split_phone_number(kwargs.get("phone"))
        except Exception as e:
            return ScriptResponse.success(message=str(e))

        self.__driver.get(Constants.BASE_URL)

        # fill the first name and the last name
        self.__fill_form_field((By.ID, "ij_first_name"), Constants.FIRST_NAME)
        self.__fill_form_field((By.ID, "ij_last_name"), Constants.LAST_NAME)

        # let's fill the birthdate. First, we need to click the dropdown button and then we can select necessary item
        # dropdown list for day selection has id="dropdown1", for month selection has id="dropdown2", for year selection
        # has id="dropdown3". We will choose the first element in every list.
        for i in range(1, 4):
            self.__click_elem((By.ID, "dropdown{}".format(i)))
            self.__click_elem(
                (
                    By.ID,
                    "option_list_options_container_{}_{}".format(
                        i, Constants.BIRTHDATE
                    ),
                )
            )

        # sometimes gender option doesn't appear. We need to click submit button and wait
        self.__click_elem((By.ID, "ij_submit"))
        self.__click_elem((By.CSS_SELECTOR, "div[role='radio']"))
        self.__click_elem((By.ID, "ij_submit"))

        # we need to wait for url to change and for page to load
        WebDriverWait(self.__driver, Defaults.MAX_TIMEOUT).until(
            ec.url_changes(Constants.FINISH_URL)
        )
        self.__wait_page_load()

        # we need to choose necessary country code
        # first, we need to click dropdown button to get access to all VK country codes
        self.__click_elem((By.ID, "dropdown1"))

        # wait for list of codes to appear
        WebDriverWait(self.__driver, Defaults.MAX_TIMEOUT).until(
            ec.visibility_of_element_located((By.ID, "list_options_container_1"))
        )
        phone_codes = self.__driver.find_element_by_id(
            "list_options_container_1"
        ).find_elements_by_tag_name("li")

        for code in phone_codes:
            if country_code in code.text:
                code.click()
                break

        self.__fill_form_field((By.ID, "join_phone"), phone_number)
        self.__click_elem((By.ID, "join_send_phone"))
        self.__wait_page_load()

        try:
            WebDriverWait(self.__driver, Defaults.MAX_TIMEOUT).until(
                ec.presence_of_element_located((By.ID, "join_called_phone"))
            )

            self.__driver.quit()

            return ScriptResponse.success(
                message="There is a user with such phone number!"
            )
        except TimeoutException:
            self.__driver.quit()

            return ScriptResponse.success(
                message="User with such phone number doesn't exist!"
            )