Zeus-Scanner/var/google_search/search.py

282 lines
9.5 KiB
Python

import os
import re
import time
try:
from urllib import unquote
except ImportError:
from urllib.parse import unquote
import requests
from selenium import webdriver
from pyvirtualdisplay import Display
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.proxy import *
from lib.settings import (
logger,
set_color,
proxy_string_to_dict,
DEFAULT_USER_AGENT,
URL_QUERY_REGEX,
URL_REGEX,
shutdown,
create_dir,
)
try:
unicode
except NameError:
unicode = str
def bypass_ip_block(url, content_sep=("continue=", "Fid", "%")):
"""
bypass Google's IP blocking by extracting the true URL from the ban URL.
"""
def __add_https(data):
if "https://" in data:
return data
else:
return "https://{}".format(url.split("://")[-1])
if isinstance(url, unicode):
url = str(url)
content_list_start = []
content_list_end = []
if content_sep[0] in url:
data_list = url.split(content_sep[0])
url_to_use = data_list[1]
else:
url_to_use = url
for match in re.finditer(content_sep[1], url_to_use):
content_list_start.append((match.start(), match.end()))
splice_to_use = content_list_start[-1][-1]
for match in re.finditer(content_sep[2], url[0:splice_to_use]):
content_list_end.append((match.start(), match.end()))
return __add_https(url[0:content_list_end[-1][-1] - 1])
def get_urls(query, url, verbose=False, warning=True, user_agent=None, proxy=None, **kwargs):
"""
Bypass Google captchas and Google API by using selenium-webdriver to gather
the Google URL. This will open a robot controlled browser window and attempt
to get a URL from Google that will be used for scraping afterwards.
"""
if verbose:
logger.debug(set_color(
"setting up the virtual display to hide the browser...", level=10
))
ff_display = Display(visible=0, size=(800, 600))
ff_display.start()
logger.info(set_color(
"firefox browser display will be hidden while it performs the query..."
))
if warning:
logger.warning(set_color(
"your web browser will be automated in order for Zeus to successfully "
"bypass captchas and API calls. this is done in order to grab the URL "
"from the search and parse the results. please give selenium time to "
"finish it's task...", level=30
))
if verbose:
logger.debug(set_color(
"running selenium-webdriver and launching browser...", level=10
))
if verbose:
logger.debug(set_color(
"adjusting selenium-webdriver user-agent to '{}'...".format(user_agent), level=10
))
if proxy is not None:
proxy_type = proxy.keys()
proxy_to_use = Proxy({
"proxyType": ProxyType.MANUAL,
"httpProxy": proxy[proxy_type[0]],
"ftpProxy": proxy[proxy_type[0]],
"sslProxy": proxy[proxy_type[0]],
"noProxy": ""
})
if verbose:
logger.debug(set_color(
"setting selenium proxy to '{}'...".format(
''.join(proxy_type) + "://" + ''.join(proxy.values())
), level=10
))
else:
proxy_to_use = None
profile = webdriver.FirefoxProfile()
profile.set_preference("general.useragent.override", user_agent)
browser = webdriver.Firefox(profile, proxy=proxy_to_use)
logger.info(set_color("browser will open shortly..."))
browser.get(url)
if verbose:
logger.debug(set_color(
"searching search engine for the 'q' element (search button)...", level=10
))
search = browser.find_element_by_name('q')
logger.info(set_color(
"searching '{}' using query '{}'...".format(url, query)
))
search.send_keys(query)
search.send_keys(Keys.RETURN) # hit return after you enter search text
time.sleep(3)
if verbose:
logger.debug(set_color(
"obtaining URL from selenium..."
))
retval = browser.current_url
ban_url_schema = ["http://ipv6.google.com", "http://ipv4.google.com"]
if any(u in retval for u in ban_url_schema): # if you got IP banned
logger.warning(set_color(
"it appears that Google is attempting to block your IP address, attempting bypass...", level=30
))
try:
retval = bypass_ip_block(retval)
except IndexError:
browser.close() # stop all the random rogue processes
ff_display.stop()
logger.warning(set_color(
"for now the IP ban bypass will only work for queries that have Google's search syntax "
"in them. (IE inurl:, incontext:, incontent:)", level=30
))
raise NotImplementedError(
"bypass for query '{}' is not implemented yet, try again with a different dork, "
"or change your IP address...".format(query)
)
if verbose:
logger.debug(set_color(
"found current URL from selenium browser...", level=10
))
logger.info(set_color(
"closing the browser and continuing process.."
))
browser.close()
ff_display.stop()
return retval
def parse_search_results(
query, url, verbose=False, dirname="{}/log/url-log", filename="url-log-{}.log", **kwargs):
"""
Parse a webpage from Google for URL's with a GET(query) parameter
"""
exclude = "google" or "webcache" or "youtube"
splitter = "&"
create_dir(dirname.format(os.getcwd()))
full_file_path = "{}/{}".format(
dirname.format(os.getcwd()), filename.format(len(os.listdir(dirname.format(
os.getcwd()
))) + 1)
)
def __get_headers():
try:
proxy_string = kwargs.get("proxy")
except:
pass
try:
user_agent = kwargs.get("agent")
except:
pass
return proxy_string, user_agent
if verbose:
logger.debug(set_color(
"checking for user-agent and proxy configuration...", level=10
))
proxy_string, user_agent = __get_headers()
if proxy_string is None:
proxy_string = None
else:
proxy_string = proxy_string_to_dict(proxy_string)
if user_agent is None:
user_agent = DEFAULT_USER_AGENT
else:
user_agent = user_agent
user_agent_info = "adjusting user-agent header to {}..."
if user_agent is not DEFAULT_USER_AGENT:
user_agent_info = user_agent_info.format(user_agent.strip())
else:
user_agent_info = user_agent_info.format("default user agent '{}'".format(DEFAULT_USER_AGENT))
proxy_string_info = "setting proxy to {}..."
if proxy_string is not None:
proxy_string_info = proxy_string_info.format(
''.join(proxy_string.keys()) + "://" + ''.join(proxy_string.values()))
else:
proxy_string_info = "no proxy configuration detected..."
headers = {
"Connection": "close",
"user-agent": user_agent
}
logger.info(set_color(
"attempting to gather query URL..."
))
try:
query_url = get_urls(query, url, verbose=verbose, user_agent=user_agent, proxy=proxy_string)
except Exception as e:
if "WebDriverException" in str(e):
logger.exception(set_color(
"it seems that you exited the browser, please allow the browser "
"to complete it's run so that Zeus can bypass captchas and API "
"calls", level=50
))
else:
logger.exception(set_color(
"{} failed to gather the URL from search engine, caught exception '{}' "
"exception has been logged to current log file...".format(
os.path.basename(__file__), str(e).strip()), level=50)
)
shutdown()
logger.info(set_color(
"URL successfully gathered, searching for GET parameters..."
))
logger.info(set_color(proxy_string_info))
req = requests.get(query_url, proxies=proxy_string)
logger.info(set_color(user_agent_info))
req.headers.update(headers)
found_urls = URL_REGEX.findall(req.text)
retval = set()
for urls in list(found_urls):
for url in list(urls):
url = unquote(url)
if URL_QUERY_REGEX.match(url) and exclude not in url:
if isinstance(url, unicode):
url = str(url).encode("utf-8")
if verbose:
try:
logger.debug(set_color(
"found '{}'...".format(url.split(splitter)[0]), level=10
))
except TypeError:
logger.debug(set_color(
"found '{}'...".format(str(url).split(splitter)[0]), level=10
))
retval.add(url.split("&")[0])
logger.info(set_color(
"found a total of {} URL's with a GET parameter...".format(len(retval))
))
if len(retval) != 0:
logger.info(set_color(
"saving found URL's under '{}'...".format(full_file_path)
))
with open(full_file_path, "a+") as log:
for url in list(retval):
log.write(url + "\n")
else:
logger.critical(set_color(
"did not find any usable URL's with the given query '{}' "
"using search engine '{}'...".format(query, url), level=50
))
shutdown()
return list(retval) if len(retval) != 0 else None