mirror of
https://github.com/Ekultek/Zeus-Scanner.git
synced 2026-03-11 08:55:51 +00:00
Compare commits
47 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21b8756306 | ||
|
|
d75169e401 | ||
|
|
f6a3ada2f0 | ||
|
|
ac83743b4d | ||
|
|
910c3e434a | ||
|
|
f512423c4e | ||
|
|
2ca5c5ac3f | ||
|
|
55ba7ca7fe | ||
|
|
caa7a4a564 | ||
|
|
3d8cf0e9f8 | ||
|
|
9dae61919d | ||
|
|
fe9c0abb76 | ||
|
|
443c0d94d1 | ||
|
|
cfc348f03f | ||
|
|
6cecf4f6d1 | ||
|
|
69a9305e11 | ||
|
|
f14bbe5645 | ||
|
|
51905bbc82 | ||
|
|
b857e6b120 | ||
|
|
ae134c3989 | ||
|
|
e5ac6316d3 | ||
|
|
cadc40b81a | ||
|
|
b0ea074e4e | ||
|
|
14f2506ef5 | ||
|
|
1bfac89266 | ||
|
|
f0056a0133 | ||
|
|
31c530cc9f | ||
|
|
1423e420d5 | ||
|
|
f7a7b436f8 | ||
|
|
05d88eaec8 | ||
|
|
73a6458fb8 | ||
|
|
aab81e892e | ||
|
|
6e2e13a2c7 | ||
|
|
a302562893 | ||
|
|
c83f745f84 | ||
|
|
301461bf71 | ||
|
|
14a7204e88 | ||
|
|
e5b52d7b45 | ||
|
|
362753d57c | ||
|
|
27701e6660 | ||
|
|
82f0c1f1ec | ||
|
|
b16a9c184a | ||
|
|
43199d690d | ||
|
|
0349835951 | ||
|
|
6e3d4b98f8 | ||
|
|
4e0945b842 | ||
|
|
b86db8008f |
34 changed files with 5169 additions and 5768 deletions
34
Dockerfile
Normal file
34
Dockerfile
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
FROM ubuntu:18.10
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt update && \
|
||||
apt install -y \
|
||||
libxml2-dev \
|
||||
libxslt1-dev \
|
||||
libgtk-3-dev \
|
||||
libdbus-glib-1-2 \
|
||||
python-dev \
|
||||
python-pip \
|
||||
git \
|
||||
curl \
|
||||
nmap \
|
||||
sqlmap \
|
||||
xvfb \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG GECKO_DRIVER_VERSION=0.23.0
|
||||
ARG FIREFOX_VERSION=58.0.2
|
||||
|
||||
RUN git clone https://github.com/ekultek/zeus-scanner.git . && \
|
||||
pip install -r requirements.txt
|
||||
|
||||
RUN curl -L https://github.com/mozilla/geckodriver/releases/download/v${GECKO_DRIVER_VERSION}/geckodriver-v${GECKO_DRIVER_VERSION}-linux64.tar.gz | tar xz -C /usr/bin
|
||||
|
||||
RUN curl -L https://ftp.mozilla.org/pub/firefox/releases/${FIREFOX_VERSION}/linux-$(uname -m)/en-US/firefox-${FIREFOX_VERSION}.tar.bz2 -o firefox.tar.bz2 && \
|
||||
tar xjf firefox.tar.bz2 -C /opt && \
|
||||
rm firefox.tar.bz2 && \
|
||||
ln -s /opt/firefox/firefox /usr/bin/firefox
|
||||
|
||||
CMD ["python", "zeus.py"]
|
||||
|
||||
43
README.md
43
README.md
|
|
@ -1,8 +1,12 @@
|
|||
**_NOTE: due to dumbass people, automatic issue creation has been turned off until further notice_**
|
||||
|
||||
----
|
||||
|
||||
[](https://github.com/ekultek/zeus-scanner/stargazers)
|
||||
[](https://github.com/ekultek/zeus-scanner/network)
|
||||
[](https://github.com/ekultek/zeus-scanner/issues)
|
||||
[](https://raw.githubusercontent.com/Ekultek/Zeus-Scanner/master/.github/LICENSE.md)
|
||||
[](https://twitter.com/Zeus_Scanner)
|
||||
[](https://twitter.com/stay__salty)
|
||||
[](https://github.com/Ekultek/Zeus-Scanner#donations)
|
||||
|
||||
# Helpful links directory
|
||||
|
|
@ -13,6 +17,7 @@
|
|||
- [Requirements and installation](https://github.com/Ekultek/Zeus-Scanner#requirements)
|
||||
- [Ubuntu/Debian](https://github.com/Ekultek/Zeus-Scanner#ubuntudebian)
|
||||
- [centOS](https://github.com/Ekultek/Zeus-Scanner#centos)
|
||||
- [Backbox](https://github.com/Ekultek/Zeus-Scanner#backbox)
|
||||
- [other](https://github.com/Ekultek/Zeus-Scanner#others)
|
||||
- [Screenshots](https://github.com/Ekultek/Zeus-Scanner#screenshots)
|
||||
- [Demo video](https://vimeo.com/239885768)
|
||||
|
|
@ -79,7 +84,7 @@ There are some requirements for this to be run successfully.
|
|||
##### Basic requirements
|
||||
|
||||
- `libxml2-dev`, `libxslt1-dev`, `python-dev` are required for the installation process
|
||||
- Firefox web browser is required as of now, you will need Firefox version `<=57 >=51` (between 51 and 57). Full functionality for other browsers will eventually be added.
|
||||
- Firefox web browser is required as of now, you will need Firefox version `<=58 >=52` (between 52 and 58). Full functionality for other browsers will eventually be added.
|
||||
- If you want to run sqlmap through the URL's you will need sqlmap somewhere on your system.
|
||||
- If you want to run a port scan using nmap on the URL's IP addresses. You will need nmap on your system.
|
||||
- [Geckodriver](https://github.com/mozilla/geckodriver) is required to run the firefox web browser and will be installed the first time you run. It will be added to your `/usr/bin` so that it can be run in your ENV PATH.
|
||||
|
|
@ -99,7 +104,7 @@ There are some requirements for this to be run successfully.
|
|||
|
||||
### Installation
|
||||
|
||||
You can download the latest [tar.gz](https://github.com/ekultek/zeus-scanner/tarball/master), the latest [zip](https://github.com/ekultek/zeus-scanner/zipball/master), or you can find the current stable release [here](https://github.com/Ekultek/Zeus-Scanner/releases/tag/v1.4). Alternatively you can install the latest development version by following the instructions that best match your operating system:
|
||||
You can download the latest [tar.gz](https://github.com/ekultek/zeus-scanner/tarball/master), the latest [zip](https://github.com/ekultek/zeus-scanner/zipball/master), or you can find the current stable release [here](https://github.com/Ekultek/Zeus-Scanner/releases/tag/v1.5). Alternatively you can install the latest development version by following the instructions that best match your operating system:
|
||||
|
||||
**_NOTE: (optional but highly advised)_** add sqlmap and nmap to your environment PATH by moving them to `/usr/bin` or by adding them to the PATH via terminal
|
||||
|
||||
|
|
@ -115,6 +120,36 @@ sudo apt-get install libxml2-dev libxslt1-dev python-dev && git clone https://g
|
|||
sudo apt-get install gcc python-devel libxml2-dev libxslt1-dev python-dev && git clone https://github.com/ekultek/zeus-scanner.git && cd zeus-scanner && sudo pip2 install -r requirements.txt && sudo python zeus.py
|
||||
```
|
||||
|
||||
#### Backbox
|
||||
|
||||
64 bit installation:
|
||||
```
|
||||
sudo -s << EOF
|
||||
aptitude purge firefox
|
||||
wget https://ftp.mozilla.org/pub/firefox/releases/57.0/linux-x86_64/en-US/firefox-57.0.tar.bz2
|
||||
tar -xjf firefox-57.0.tar.bz2
|
||||
rm -rf /opt/firefox*
|
||||
mv firefox /opt/firefox57
|
||||
mv /usr/bin/firefox /usr/bin/firefoxold
|
||||
ln -s /opt/firefox57/firefox-bin /usr/bin/firefox
|
||||
apt-get install libxml2-dev libxslt1-dev python-dev && git clone https://github.com/ekultek/zeus-scanner.git && cd zeus-scanner && pip2 install -r requirements.txt && python zeus.py
|
||||
EOF
|
||||
```
|
||||
|
||||
32 bit installation:
|
||||
```
|
||||
sudo -s << EOF
|
||||
aptitude purge firefox
|
||||
wget https://ftp.mozilla.org/pub/firefox/releases/57.0/linux-i686/en-US/firefox-57.0.tar.bz2
|
||||
tar -xjf firefox-57.0.tar.bz2
|
||||
rm -rf /opt/firefox*
|
||||
mv firefox /opt/firefox57
|
||||
mv /usr/bin/firefox /usr/bin/firefoxold
|
||||
ln -s /opt/firefox57/firefox-bin /usr/bin/firefox
|
||||
apt-get install libxml2-dev libxslt1-dev python-dev && git clone https://github.com/ekultek/zeus-scanner.git && cd zeus-scanner && pip2 install -r requirements.txt && python zeus.py
|
||||
EOF
|
||||
```
|
||||
|
||||
##### Others
|
||||
|
||||
```
|
||||
|
|
@ -145,4 +180,4 @@ OpenSource Projects is a Facebook community page who's goal is to give developer
|
|||
|
||||
- [Spanish](https://github.com/Ekultek/Zeus-Scanner/blob/master/.github/translations/README-spanish.md)
|
||||
- [Russian](https://github.com/Ekultek/Zeus-Scanner/blob/master/.github/translations/README-russian.md)
|
||||
- [French](https://github.com/Ekultek/Zeus-Scanner/blob/master/.github/translations/README-french.md)
|
||||
- [French](https://github.com/Ekultek/Zeus-Scanner/blob/master/.github/translations/README-french.md)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import os
|
||||
import sys
|
||||
import time
|
||||
import shlex
|
||||
import platform
|
||||
import threading
|
||||
import subprocess
|
||||
import tarfile
|
||||
try:
|
||||
|
|
@ -13,6 +17,27 @@ import lib.core.common
|
|||
import lib.core.settings
|
||||
|
||||
|
||||
stop_animation = False
|
||||
xvfb_path = "{}/etc/scripts/install_xvfb.sh".format(os.getcwd())
|
||||
|
||||
|
||||
def animation(text):
|
||||
global stop_animation
|
||||
i = 0
|
||||
while not stop_animation:
|
||||
temp_text = list(text)
|
||||
if i >= len(temp_text):
|
||||
i = 0
|
||||
temp_text[i] = temp_text[i].upper()
|
||||
temp_text = ''.join(temp_text)
|
||||
sys.stdout.write("\033[92m{}\r\033[0m".format(temp_text))
|
||||
sys.stdout.flush()
|
||||
i += 1
|
||||
time.sleep(0.1)
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
def disclaimer():
|
||||
question = raw_input(
|
||||
"\033[91mAttacking targets without consent is not only illegal, but it "
|
||||
|
|
@ -28,7 +53,7 @@ def disclaimer():
|
|||
else:
|
||||
lib.core.settings.logger.fatal(lib.core.settings.set_color(
|
||||
"you have not agreed with the terms of service, so "
|
||||
"Zeus will shut down now...", level=50
|
||||
"Zeus will shut down now", level=50
|
||||
))
|
||||
return False
|
||||
|
||||
|
|
@ -46,6 +71,8 @@ def parse_hosts(filepath="/etc/hosts"):
|
|||
|
||||
|
||||
def find_tools(to_search=("sqlmap", "nmap"), directory="{}/bin/paths", filename="path_config.ini"):
|
||||
global stop_animation
|
||||
|
||||
lib.core.settings.create_dir(directory.format(os.getcwd()))
|
||||
full_path = "{}/{}".format(
|
||||
directory.format(os.getcwd()),
|
||||
|
|
@ -62,6 +89,8 @@ def find_tools(to_search=("sqlmap", "nmap"), directory="{}/bin/paths", filename=
|
|||
path_schema[item] = None
|
||||
for key, value in path_schema.iteritems():
|
||||
if value is None:
|
||||
stop_animation = True
|
||||
print("\n")
|
||||
provided_path = lib.core.common.prompt(
|
||||
"what is the full path to {} on your system".format(key)
|
||||
)
|
||||
|
|
@ -78,9 +107,9 @@ def config_gecko_version(browser_version):
|
|||
figure out which gecko version you need
|
||||
"""
|
||||
version_specs = {
|
||||
(56, 57): 19,
|
||||
(55, 54): 18,
|
||||
(53, 52, 51): 17
|
||||
(57, 58): 19,
|
||||
(56, 55, 54): 18,
|
||||
(53, 52): 17
|
||||
}
|
||||
if isinstance(browser_version, (tuple, list, set)):
|
||||
major = browser_version[0]
|
||||
|
|
@ -112,11 +141,13 @@ def check_xvfb(exc="Xvfb"):
|
|||
"""
|
||||
test for xvfb on the users system
|
||||
"""
|
||||
global xvfb_path
|
||||
global stop_animation
|
||||
if whichcraft.which(exc) is None:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"installing Xvfb, required by pyvirutaldisplay..."
|
||||
))
|
||||
subprocess.call(["sudo", "apt-get", "install", "xvfb"])
|
||||
cmd = shlex.split("sudo sh {}".format(xvfb_path))
|
||||
subprocess.call(cmd)
|
||||
stop_animation = True
|
||||
|
||||
else:
|
||||
return True
|
||||
|
||||
|
|
@ -136,53 +167,45 @@ def check_if_run(file_check="{}/bin/executed.txt"):
|
|||
return True
|
||||
|
||||
|
||||
def untar_gecko(filename="{}/bin/drivers/geckodriver-v0.{}.0-linux{}.tar.gz", verbose=False):
|
||||
def untar_gecko(filename="{}/bin/drivers/geckodriver-v0.{}.0-linux{}.tar.gz"):
|
||||
"""
|
||||
untar the correct gecko driver for your computer architecture
|
||||
"""
|
||||
global stop_animation
|
||||
|
||||
arch_info = {"64bit": "64", "32bit": "32"}
|
||||
file_arch = arch_info[platform.architecture()[0]]
|
||||
ff_version = lib.core.settings.get_browser_version()
|
||||
ff_version = lib.core.settings.get_browser_version(output=False)
|
||||
if isinstance(ff_version, str) or ff_version is None:
|
||||
stop_animation = True
|
||||
ff_version = lib.core.common.prompt(
|
||||
"enter your firefox browser version (if you don't know it run firefox --version"
|
||||
"enter your firefox browser version (if you don't know it run firefox --version)"
|
||||
)
|
||||
gecko_version = config_gecko_version(ff_version)
|
||||
if gecko_version is None:
|
||||
stop_animation = True
|
||||
lib.core.settings.logger.fatal(lib.core.settings.set_color(
|
||||
"your current firefox version is not supported by Zeus...", level=50
|
||||
"your current firefox version is not supported by Zeus", level=50
|
||||
))
|
||||
lib.core.common.shutdown()
|
||||
gecko_full_filename = filename.format(os.getcwd(), gecko_version, file_arch)
|
||||
with open(lib.core.settings.GECKO_VERSION_INFO_PATH, "a+") as log:
|
||||
log.write(gecko_full_filename.split("/")[-1])
|
||||
tar = tarfile.open(filename.format(os.getcwd(), gecko_version, file_arch), "r:gz")
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"extracting the correct driver for your architecture...", level=10
|
||||
))
|
||||
try:
|
||||
tar.extractall("/usr/bin")
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"driver extracted into /usr/bin (you may change this, but ensure that it "
|
||||
"is in your PATH)...", level=10
|
||||
))
|
||||
except IOError as e:
|
||||
if "Text file busy" in str(e):
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"the driver is already installed..."
|
||||
))
|
||||
tar.close()
|
||||
pass
|
||||
except Exception as e:
|
||||
if "[Errno 13] Permission denied: '/usr/bin/geckodriver'" in str(e):
|
||||
lib.core.settings.logger.exception(lib.core.settings.set_color(
|
||||
"first run must be ran as root (sudo python zeus.py)...", level=50
|
||||
"first run must be ran as root (sudo python zeus.py)", level=50
|
||||
))
|
||||
else:
|
||||
lib.core.settings.logger.exception(lib.core.settings.set_color(
|
||||
"ran into exception '{}', logged to current log file...".format(e), level=50
|
||||
"ran into exception '{}', logged to current log file".format(e), level=50
|
||||
))
|
||||
exit(-1)
|
||||
tar.close()
|
||||
|
|
@ -192,10 +215,6 @@ def ensure_placed(item="geckodriver", verbose=False):
|
|||
"""
|
||||
use whichcraft to ensure that the driver has been placed in your PATH variable
|
||||
"""
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"ensuring that the driver exists in your system path...", level=10
|
||||
))
|
||||
if not whichcraft.which(item):
|
||||
lib.core.settings.logger.fatal(lib.core.settings.set_color(
|
||||
"the executable '{}' does not appear to be in your /usr/bin PATH. "
|
||||
|
|
@ -204,10 +223,6 @@ def ensure_placed(item="geckodriver", verbose=False):
|
|||
))
|
||||
exit(-1)
|
||||
else:
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"driver exists, continuing...", level=10
|
||||
))
|
||||
return True
|
||||
|
||||
|
||||
|
|
@ -215,39 +230,28 @@ def main(rewrite="{}/bin/executed.txt", verbose=False):
|
|||
"""
|
||||
main method
|
||||
"""
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"verifying operating system...", level=10
|
||||
))
|
||||
if not check_os():
|
||||
raise NotImplementedError(lib.core.settings.set_color(
|
||||
"as of now, Zeus requires Linux to run successfully "
|
||||
"your current operating system '{}' is not implemented "
|
||||
"yet...".format(platform.platform()), level=50
|
||||
"yet".format(platform.platform()), level=50
|
||||
))
|
||||
if check_if_run():
|
||||
if not disclaimer():
|
||||
exit(1)
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"seems this is your first time running the application, "
|
||||
"doing setup please wait..."
|
||||
))
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"checking if xvfb is on your system...", level=10
|
||||
))
|
||||
t = threading.Thread(target=animation, args=(
|
||||
"seems this is your first time running the application, doing setup please wait..",))
|
||||
t.daemon = True
|
||||
t.start()
|
||||
find_tools()
|
||||
check_xvfb()
|
||||
untar_gecko(verbose=verbose)
|
||||
untar_gecko()
|
||||
parse_hosts()
|
||||
if ensure_placed(verbose=verbose):
|
||||
with open(rewrite.format(os.getcwd()), "w") as rw:
|
||||
rw.write("TRUE")
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"done, continuing process..."
|
||||
"done, continuing process"
|
||||
))
|
||||
else:
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"already ran, skipping...", level=10
|
||||
))
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -1,111 +1,119 @@
|
|||
1caf80ae9a944960ef67773c2bbdd6b2 ./zeus.py
|
||||
685a20fa3fc7652b5c3e39821cdc6f25 ./zeus.py
|
||||
4b32db388e8acda35570c734d27c950c ./etc/scripts/launch_sqlmap.sh
|
||||
6ad5f22ec4a6f8324bfb1b01ab6d51ec ./etc/scripts/cleanup.sh
|
||||
74d7bee13890a9dd279bb857591647ce ./etc/scripts/reinstall.sh
|
||||
869025acb457dc881e53e440aa11dd7b ./etc/scripts/reinstall.sh
|
||||
155c9482f690f1482f324a7ffd8b8098 ./etc/scripts/fix_pie.sh
|
||||
0e435c641bc636ac0b3d54e032d9cf6a ./etc/scripts/install_nmap.sh
|
||||
440431165b2db8a537c1a93cb2232f16 ./etc/scripts/install_xvfb.sh
|
||||
66b11aa388ea909de7b212341259a318 ./etc/auths/git_auth
|
||||
8f686b05c5c5dfc02f0fcaa7ebc8677c ./etc/auths/whois_auth
|
||||
d3ad89703575a712a0aeead2b176d8c5 ./etc/html/clickjacking_test_page.html
|
||||
642a77905d8bb4e5533e0e9c2137c0fa ./etc/text_files/agents.txt
|
||||
82cc68f46539d0255f7ce14cd86cd49b ./etc/text_files/link_ext.txt
|
||||
9659c647c725773e82d130e0f5c73c57 ./etc/text_files/dorks.txt
|
||||
dc7bfc3d7b9b23340ee37806316bd770 ./etc/text_files/xss_payloads.txt
|
||||
c57ac34fe965961917ac8a207df256d5 ./etc/text_files/dorks.txt
|
||||
cf85d83da34d70720193d83950c31fdc ./etc/text_files/xss_payloads.txt
|
||||
6cabeb9919d2301efc4ba3d8869282d6 ./etc/checksum/md5sum.md5
|
||||
5250f0aa13b8af4775efa506e77de1ce ./etc/xml/headers.xml
|
||||
d41d8cd98f00b204e9800998ecf8427e ./bin/__init__.py
|
||||
ebd255c3ab49efde3155338e5d596b63 ./bin/unzip_gecko.py
|
||||
3be7ee6f4267e0d0cf2143b58792527b ./bin/paths/path_config.ini
|
||||
fa5084cc7ee56ff2df8631b76be5be4d ./bin/unzip_gecko.py
|
||||
c0d83f0b82a6b30de8811e69e6d95c61 ./bin/executed.txt
|
||||
dc1eb4ebe0f372af48b5a9c107ebc68d ./bin/drivers/geckodriver-v0.18.0-linux32.tar.gz
|
||||
be18faeea6e7db9db6990d8667e2298f ./bin/drivers/geckodriver-v0.17.0-linux64.tar.gz
|
||||
79b1a158f96d29942a111c0905f1c807 ./bin/drivers/geckodriver-v0.17.0-linux32.tar.gz
|
||||
ca6935a72fd0527d15a78a17a35e56e8 ./bin/drivers/geckodriver-v0.19.0-linux64.tar.gz
|
||||
4ccb56fb3700005c9f9188f84152f21a ./bin/drivers/geckodriver-v0.18.0-linux64.tar.gz
|
||||
07cd383c8aef8ea5ef194a506141afd6 ./bin/drivers/geckodriver-v0.19.0-linux32.tar.gz
|
||||
785c28da8b681a7e23964f99118b5aab ./lib/tamper_scripts/obfuscateordinal_encode.py
|
||||
145e4a7dc985e99962dabe3b221fc51e ./lib/tamper_scripts/obfuscateordinal_encode.py
|
||||
10bf1bc4ef0287d31633148fab557e8a ./lib/tamper_scripts/uppercase_encode.py
|
||||
5b68de0ce3a783b870921b09b5222146 ./lib/tamper_scripts/hex_encode.py
|
||||
fcef22874b6732fd1b1bd062e18e65db ./lib/tamper_scripts/hex_encode.py
|
||||
1537b3b94566aebf0f89bed074e96581 ./lib/tamper_scripts/url_encode.py
|
||||
d41d8cd98f00b204e9800998ecf8427e ./lib/tamper_scripts/__init__.py
|
||||
7b636a332b2e99547ec9565d8e094308 ./lib/tamper_scripts/unicode_encode.py
|
||||
07a792bccd13f64873a27aee4aaa8ea6 ./lib/tamper_scripts/space2comment_encode.py
|
||||
1053a0c89e514d2c94bc822d34715896 ./lib/tamper_scripts/randomcase_encode.py
|
||||
349c30cbab4308bd94829d92b4e34f9d ./lib/tamper_scripts/lowercase_encode.py
|
||||
6e1d6276a295f6c5d41b6f6f0e1316b0 ./lib/tamper_scripts/enclosebrackets_encode.py
|
||||
694231b4c2f99406481c34ced85ddfe1 ./lib/tamper_scripts/base64_encode.py
|
||||
6ac38bec8c32eab57efa01f7a06dff14 ./lib/tamper_scripts/space2null_encode.py
|
||||
3b8c95a6a3b7cecce5118f2fb1ccc6b8 ./lib/tamper_scripts/appendnull_encode.py
|
||||
0c5e78674a8d27e7c20af1dca8656789 ./lib/tamper_scripts/enclosebrackets_encode.py
|
||||
5824916df46428a8304ee0156bcee989 ./lib/tamper_scripts/multispace2comment_encode.py
|
||||
9fd42d65993aa20d1bf5acbc4d042d2e ./lib/tamper_scripts/base64_encode.py
|
||||
f77b7a9a19b94e26903eeecf5a787ea3 ./lib/tamper_scripts/space2null_encode.py
|
||||
3b8c95a6a3b7cecce5118f2fb1ccc6b8 ./lib/tamper_scripts/appendnull_encode.py
|
||||
8e8792e38649f18d90bb0084202bb59e ./lib/tamper_scripts/obfuscateentity_encode.py
|
||||
d41d8cd98f00b204e9800998ecf8427e ./lib/__init__.py
|
||||
6299b188a730844954044887f528435a ./lib/firewall/cloudfront.py
|
||||
d41d8cd98f00b204e9800998ecf8427e ./lib/firewall/__init__.py
|
||||
eb3a3066efbcf87dbc10a49be445cb8f ./lib/firewall/urlscan.py
|
||||
81a29a14d72980a306fbaec0dc772048 ./lib/firewall/fortigate.py
|
||||
d4986f3d95a773d7c3585b07bcd6310e ./lib/firewall/sucuri.py
|
||||
763af6773e920d6bdc185f5bd4df6084 ./lib/firewall/dw.py
|
||||
e4514021485dbb94c3f0023b04af01ad ./lib/firewall/aws.py
|
||||
eb3a3066efbcf87dbc10a49be445cb8f ./lib/firewall/urlscan.py
|
||||
71744d7a95f42063a8fb6e720932cd3d ./lib/firewall/sonicwall.py
|
||||
7af3ee8615c7dc761f050e0ba638eaef ./lib/firewall/armor.py
|
||||
1f303641d59686d544f2986ff74c6b31 ./lib/firewall/webseal.py
|
||||
78e6b01feb9bad68c2fc8a79e75930fd ./lib/firewall/yundun.py
|
||||
e4eef006dd909c222b1b9f48826c3ef5 ./lib/firewall/pk.py
|
||||
bf5285dc059c761e1719bc734ae8504f ./lib/firewall/varnish.py
|
||||
6b370050b40d8c1d2221424f756c7842 ./lib/firewall/paloalto.py
|
||||
73c1727e604ec6e00541687bfc64c0d6 ./lib/firewall/akamai.py
|
||||
6bbe2f6f6a2a1ddf0e416e94ec1f0763 ./lib/firewall/siteguard.py
|
||||
787e21ed577ff05b095aa0f0e5e5e9bf ./lib/firewall/cloudflare.py
|
||||
c3f01fc8ff7dfe7759f63bf16b00f127 ./lib/firewall/wordfence.py
|
||||
6ccf3a1df5aa6429cd3365b7b8ded8f4 ./lib/firewall/powerful.py
|
||||
54815706261c32b57fbbdc99244b5cdd ./lib/firewall/modsecurity.py
|
||||
5ee20e2c158d0734b4dd5a8eb47f8ea5 ./lib/firewall/squid.py
|
||||
71744d7a95f42063a8fb6e720932cd3d ./lib/firewall/sonicwall.py
|
||||
9070b43428bd17fd5faf86995cb559a2 ./lib/firewall/stringray.py
|
||||
bf5285dc059c761e1719bc734ae8504f ./lib/firewall/varnish.py
|
||||
78e6b01feb9bad68c2fc8a79e75930fd ./lib/firewall/yundun.py
|
||||
cb45428e92485b759ff5cb46a0be9c73 ./lib/firewall/yunsuo.py
|
||||
2f0a935d2bb9b8aa711e511f48595a81 ./lib/firewall/powerful.py
|
||||
bbd8b4c6100070d420d48dc7dfc297eb ./lib/firewall/webknight.py
|
||||
54815706261c32b57fbbdc99244b5cdd ./lib/firewall/modsecurity.py
|
||||
9070b43428bd17fd5faf86995cb559a2 ./lib/firewall/stringray.py
|
||||
5ee20e2c158d0734b4dd5a8eb47f8ea5 ./lib/firewall/squid.py
|
||||
95b908a21c0ff456ae59df4c6c189c54 ./lib/firewall/wallarm.py
|
||||
cb45428e92485b759ff5cb46a0be9c73 ./lib/firewall/yunsuo.py
|
||||
8fc8d62377bebbfa7ca4d70a79eab115 ./lib/firewall/bigip.py
|
||||
73c1727e604ec6e00541687bfc64c0d6 ./lib/firewall/akamai.py
|
||||
7af3ee8615c7dc761f050e0ba638eaef ./lib/firewall/armor.py
|
||||
763af6773e920d6bdc185f5bd4df6084 ./lib/firewall/dw.py
|
||||
81a29a14d72980a306fbaec0dc772048 ./lib/firewall/fortigate.py
|
||||
6ea65a0160c21e144e92334acc2e3667 ./lib/firewall/anquanbao.py
|
||||
22a0ad8f2fa1a16b651cb5ae37ca9b0d ./lib/firewall/generic.py
|
||||
ed18ed1f72f3887e63fa7ce060841e4a ./lib/plugins/aardvark.py
|
||||
a8b3e6924bab72607b1d1c1a8dcb561d ./lib/plugins/4d.py
|
||||
03355a122c047dc598fc271620119978 ./lib/plugins/jquery.py
|
||||
d41d8cd98f00b204e9800998ecf8427e ./lib/plugins/__init__.py
|
||||
353db8b22c031433ea73a12943927557 ./lib/plugins/clipbucket.py
|
||||
5908a81cc9b332348b26a3ccd5ddb798 ./lib/plugins/ihtml.py
|
||||
d76d2839ed8875739328bb5f2a838ba6 ./lib/plugins/360.py
|
||||
16e4708c510811760129f6fb4842e92e ./lib/plugins/3dcart.py
|
||||
2ce0a2101bb5706a136de83a729965f3 ./lib/plugins/b2evolution.py
|
||||
b4ab6d1e0d3582fc66111988b246acc0 ./lib/plugins/bmcremedy.py
|
||||
497facc7b12e6e691aab65980d8f5026 ./lib/plugins/bmcremedy.py
|
||||
2dcee5bc924732dd21f16983eef9a99d ./lib/plugins/abyss.py
|
||||
d2c100e6e6f7fbda8448d36a6928c979 ./lib/plugins/68classified.py
|
||||
f1eb201cce16853049a615805b01bc60 ./lib/plugins/bomgar.py
|
||||
ce3b79dc80e369ffd55d2cbe90e6a0ab ./lib/plugins/mssqlreportmanager.py
|
||||
55ec8cde9d438a90327911910164abf2 ./lib/plugins/opengraph.py
|
||||
8658f8a185499ec6d10b1d2da6104c27 ./lib/plugins/atomfeed.py
|
||||
c2533d4a8dc5fdaa4b8d584588b32ec2 ./lib/plugins/html5.py
|
||||
a3ed012f11ff2bffbc143fbef63d0c12 ./lib/plugins/3com.py
|
||||
55d834ae87e96787807e21b65ec68bca ./lib/plugins/moodle.py
|
||||
44019a327ec1db91851d652630788742 ./lib/plugins/googleapi.py
|
||||
c4ac50a3f3550c62219e7e4f38d4b496 ./lib/plugins/1024.py
|
||||
0b63885649f369ea410c8169e947fdab ./lib/plugins/accellion.py
|
||||
76a1d1decfb872bfafdf510c656f113a ./lib/plugins/rssfeed.py
|
||||
320f0db977c85b477ba1ea78b140cb8a ./lib/plugins/4images.py
|
||||
35dc8b7da4becb60662aab3c48a9210b ./lib/plugins/openxchange.py
|
||||
b5ff3286060c0bbc0fe1f0f591131c9c ./lib/attacks/gist_lookup/__init__.py
|
||||
86224bd899c2a2438042cbdc077dc4cc ./lib/attacks/clickjacking_scan/__init__.py
|
||||
bdb7ff546787d38bbbd0aac9d4a4cdf8 ./lib/attacks/clickjacking_scan/__init__.py
|
||||
d41d8cd98f00b204e9800998ecf8427e ./lib/attacks/__init__.py
|
||||
4c644b0e3a62b6c1528d34a04837aa35 ./lib/attacks/sqlmap_scan/__init__.py
|
||||
6e9e0a9e2c72e00d8690c0177b695d56 ./lib/attacks/sqlmap_scan/__init__.py
|
||||
5e5bb575014ebe613db6bf671d008cf8 ./lib/attacks/sqlmap_scan/sqlmap_opts.py
|
||||
7bc7a6f3e85651aab3588f087563eded ./lib/attacks/whois_lookup/__init__.py
|
||||
8ec72bb33df998e32b925e3060d9d17a ./lib/attacks/whois_lookup/whois.py
|
||||
916b768e783ff771bce80bd6f5112d4f ./lib/attacks/admin_panel_finder/__init__.py
|
||||
52942c7b33ff696901f5a4201ba4507f ./lib/attacks/xss_scan/__init__.py
|
||||
7642d078fe304a7ca8bfaaa070a0cb31 ./lib/attacks/nmap_scan/__init__.py
|
||||
d41d8cd98f00b204e9800998ecf8427e ./lib/attacks/whois_lookup/__init__.py
|
||||
c5b69617f040fef1d5930948905aa8d0 ./lib/attacks/whois_lookup/whois.py
|
||||
4fd96bb3002e949687d7ae863ee87264 ./lib/attacks/admin_panel_finder/__init__.py
|
||||
2017e69c3420c9e240fccb310f086da7 ./lib/attacks/xss_scan/__init__.py
|
||||
40ba04fb18dcbb81cb42376a825c238f ./lib/attacks/nmap_scan/__init__.py
|
||||
216999fa0e84866d5c1d96d5676034e4 ./lib/attacks/nmap_scan/nmap_opts.py
|
||||
c01ef6dc27a2d3ff99e282ccc89d7d45 ./lib/header_check/__init__.py
|
||||
cd8e35cfd995d0a93892cfc83f01dea7 ./lib/core/common.py
|
||||
4433353fb5c55578391d8b4006191ee8 ./lib/core/errors.py
|
||||
38d8ce4aec42ec147b44a36c69b15ea8 ./lib/core/parse.py
|
||||
d41d8cd98f00b204e9800998ecf8427e ./lib/core/__init__.py
|
||||
0112338e057d62d4580c86033c18df05 ./lib/core/settings.py
|
||||
0114ebe3d45612ef143f2777f027374c ./lib/header_check/__init__.py
|
||||
2a8acb2191d80da75f0e4d09c00df9f6 ./lib/core/common.py
|
||||
de4254c5e40f7aa4fb81e0608f758a2c ./lib/core/decorators.py
|
||||
9a02e5b913d210350545ac26510a63c9 ./var/search/__init__.py
|
||||
83928f6c090722d87a905a447cb51aed ./var/search/selenium_search.py
|
||||
cfcce04aac694eee7a6c73969861ce43 ./var/search/pgp_search.py
|
||||
3f045c64ef155a517b7a3f3b66905325 ./lib/core/errors.py
|
||||
d41d8cd98f00b204e9800998ecf8427e ./lib/core/__init__.py
|
||||
0faeed8eac30526f3751dd67fe5c9f7e ./lib/core/settings.py
|
||||
27bce5d5d1e7d01788c5273016b19370 ./lib/core/parse.py
|
||||
d41d8cd98f00b204e9800998ecf8427e ./var/__init__.py
|
||||
d41d8cd98f00b204e9800998ecf8427e ./var/auto_issue/__init__.py
|
||||
0c11c16126baf789388a661bbbefb149 ./var/auto_issue/github.py
|
||||
222102e56b3f4b9facda7ed28690d3f7 ./var/blackwidow/__init__.py
|
||||
c58e73857e42a07fa6eb559433b32c1a ./var/auto_issue/github.py
|
||||
503e44b36f0bcd81e20840be5b73320e ./var/search/__init__.py
|
||||
c52867e57beeeeac2da57f597b644faf ./var/search/selenium_search.py
|
||||
12340de27a75273cd444f7257d354311 ./var/search/pgp_search.py
|
||||
0af5ab455a535a2f141cfae4758a4bb4 ./var/blackwidow/__init__.py
|
||||
4
etc/scripts/install_xvfb.sh
Normal file
4
etc/scripts/install_xvfb.sh
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
sudo apt-get install xvfb --yes > /dev/null 2>&1
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
for pid in $(ps -ef | grep "firefox" | awk '{print $2}'); do kill -9 ${pid}; done > /dev/null 2>&1
|
||||
mv ~/.mozilla ~/.mozilla.old > /dev/null 2>&1
|
||||
rm /usr/lib/firefox* > /dev/null 2>&1
|
||||
sudo apt-get update > /dev/null 2>&1
|
||||
sudo apt-get --purge --reinstall --assume-yes install firefox=56.0 > /dev/null 2>&1
|
||||
sudo pip2 install selenium -U
|
||||
sudo pip2 install selenium -U > /dev/null 2>&1
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -35,7 +35,7 @@ def check_for_externals(url, data_sep="-" * 30, **kwargs):
|
|||
currently_searching = ext[robots if robots else sitemap]
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"currently searching for a '{}'...".format(currently_searching), level=10
|
||||
"currently searching for a '{}'".format(currently_searching), level=10
|
||||
))
|
||||
|
||||
try:
|
||||
|
|
@ -44,13 +44,13 @@ def check_for_externals(url, data_sep="-" * 30, **kwargs):
|
|||
_, code, data, _ = lib.core.common.get_page(full_url)
|
||||
except (TooManyRedirects, ConnectionError, ReadTimeout):
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"connection to '{}' failed, assuming does not exist and continuing...".format(full_url), level=40
|
||||
"connection to '{}' failed, assuming does not exist and continuing".format(full_url), level=40
|
||||
))
|
||||
return False
|
||||
|
||||
if code == 404:
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"unable to connect to '{}', assuming does not exist and continuing...".format(
|
||||
"unable to connect to '{}', assuming does not exist and continuing".format(
|
||||
full_url
|
||||
), level=40
|
||||
))
|
||||
|
|
@ -80,7 +80,7 @@ def check_for_externals(url, data_sep="-" * 30, **kwargs):
|
|||
)
|
||||
)
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"robots.txt page will be saved into a file...", level=25
|
||||
"robots.txt page will be saved into a file", level=25
|
||||
))
|
||||
return lib.core.common.write_to_log_file(
|
||||
data, lib.core.settings.ROBOTS_PAGE_PATH, lib.core.settings.ROBOTS_TXT_FILENAME.format(
|
||||
|
|
@ -89,7 +89,7 @@ def check_for_externals(url, data_sep="-" * 30, **kwargs):
|
|||
)
|
||||
elif sitemap:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"found a sitemap, saving to file...", level=25
|
||||
"found a sitemap, saving to file", level=25
|
||||
))
|
||||
return lib.core.common.write_to_log_file(
|
||||
data, lib.core.settings.SITEMAP_FILE_LOG_PATH, lib.core.settings.SITEMAP_FILENAME.format(
|
||||
|
|
@ -114,12 +114,12 @@ def check_for_admin_page(url, exts, protocol="http://", **kwargs):
|
|||
true_url = "{}{}{}".format(protocol, stripped_url, ext)
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"trying '{}'...".format(true_url), level=10
|
||||
"trying '{}'".format(true_url), level=10
|
||||
))
|
||||
try:
|
||||
urlopen(true_url, timeout=5)
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"connected successfully to '{}'...".format(true_url), level=25
|
||||
"connected successfully to '{}'".format(true_url), level=25
|
||||
))
|
||||
connections.add(true_url)
|
||||
except HTTPError as e:
|
||||
|
|
@ -127,7 +127,7 @@ def check_for_admin_page(url, exts, protocol="http://", **kwargs):
|
|||
if verbose:
|
||||
if "Access Denied" in str(e):
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"got access denied, possible control panel found without external access on '{}'...".format(
|
||||
"got access denied, possible control panel found without external access on '{}'".format(
|
||||
true_url
|
||||
),
|
||||
level=30
|
||||
|
|
@ -137,7 +137,7 @@ def check_for_admin_page(url, exts, protocol="http://", **kwargs):
|
|||
for error_code in lib.core.common.STATUS_CODES.iterkeys():
|
||||
if int(data[2].split(":")[0]) == error_code:
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"failed to connect got error code {} (reason: {})...".format(
|
||||
"failed to connect got error code {} (reason: {})".format(
|
||||
data[2], lib.core.common.STATUS_CODES[error_code]
|
||||
), level=40
|
||||
))
|
||||
|
|
@ -145,33 +145,33 @@ def check_for_admin_page(url, exts, protocol="http://", **kwargs):
|
|||
if verbose:
|
||||
if "<urlopen error timed out>" or "timeout: timed out" in str(e):
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"connection timed out assuming won't connect and skipping...", level=30
|
||||
"connection timed out assuming won't connect and skipping", level=30
|
||||
))
|
||||
else:
|
||||
lib.core.settings.logger.exception(lib.core.settings.set_color(
|
||||
"failed to connect with unexpected error '{}'...".format(str(e)), level=50
|
||||
"failed to connect with unexpected error '{}'".format(str(e)), level=50
|
||||
))
|
||||
request_issue_creation()
|
||||
possible_connections, connections = list(possible_connections), list(connections)
|
||||
data_msg = "found {} possible connections(s) and {} successful connection(s)..."
|
||||
data_msg = "found {} possible connections(s) and {} successful connection(s)"
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
data_msg.format(len(possible_connections), len(connections))
|
||||
))
|
||||
if len(connections) > 0:
|
||||
# create the connection tree if we got some connections
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"creating connection tree..."
|
||||
"creating connection tree"
|
||||
))
|
||||
lib.core.settings.create_tree(url, connections)
|
||||
else:
|
||||
lib.core.settings.logger.fatal(lib.core.settings.set_color(
|
||||
"did not receive any successful connections to the admin page of "
|
||||
"{}...".format(url), level=50
|
||||
"{}".format(url), level=50
|
||||
))
|
||||
if show_possibles:
|
||||
if len(possible_connections) > 0:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"creating possible connection tree..."
|
||||
"creating possible connection tree"
|
||||
))
|
||||
lib.core.settings.create_tree(url, possible_connections)
|
||||
else:
|
||||
|
|
@ -181,7 +181,7 @@ def check_for_admin_page(url, exts, protocol="http://", **kwargs):
|
|||
))
|
||||
if len(connections) > 0:
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"only writing successful connections to log file...", level=30
|
||||
"only writing successful connections to log file", level=30
|
||||
))
|
||||
lib.core.common.write_to_log_file(
|
||||
list(connections),
|
||||
|
|
@ -211,32 +211,32 @@ def main(url, show=False, verbose=False, **kwargs):
|
|||
|
||||
try:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"parsing robots.txt..."
|
||||
"parsing robots.txt"
|
||||
))
|
||||
results = check_for_externals(url, robots=True, batch=batch)
|
||||
if not results:
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"seems like this page is either blocking access to robots.txt or it does not exist...", level=30
|
||||
"seems like this page is either blocking access to robots.txt or it does not exist", level=30
|
||||
))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"checking for a sitemap..."
|
||||
"checking for a sitemap"
|
||||
))
|
||||
check_for_externals(url, sitemap=True)
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"loading extensions..."
|
||||
"loading extensions"
|
||||
))
|
||||
extensions = __load_extensions()
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"loaded a total of {} extensions...".format(len(extensions)), level=10
|
||||
"loaded a total of {} extensions".format(len(extensions)), level=10
|
||||
))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"attempting to bruteforce admin panel..."
|
||||
"attempting to bruteforce admin panel"
|
||||
))
|
||||
if do_threading:
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"starting {} threads, you will not be able to end the process until "
|
||||
"it is completed...".format(proc_num), level=30
|
||||
"it is completed".format(proc_num), level=30
|
||||
))
|
||||
tasks = []
|
||||
for _ in range(0, proc_num):
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ def clickjacking_main(url, **kwargs):
|
|||
)
|
||||
if question.lower().startswith("n"):
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"automatically removing all queries from URL..."
|
||||
"automatically removing all queries from URL"
|
||||
))
|
||||
url = "http://{}".format(lib.core.settings.replace_http(url, complete=True))
|
||||
|
||||
|
|
@ -73,14 +73,14 @@ def clickjacking_main(url, **kwargs):
|
|||
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"generating HTML...", level=10
|
||||
"generating HTML", level=10
|
||||
))
|
||||
|
||||
data = scanner.generate_html()
|
||||
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"HTML generated successfully...", level=10
|
||||
"HTML generated successfully", level=10
|
||||
))
|
||||
print("{}\n{}\n{}".format("-" * 30, data, "-" * 30))
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ def clickjacking_main(url, **kwargs):
|
|||
if results:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"it appears that provided URL '{}' is vulnerable to clickjacking, writing "
|
||||
"to HTML file...".format(url), level=25
|
||||
"to HTML file".format(url), level=25
|
||||
))
|
||||
lib.core.common.write_to_log_file(
|
||||
data,
|
||||
|
|
@ -99,7 +99,7 @@ def clickjacking_main(url, **kwargs):
|
|||
)
|
||||
else:
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"provided URL '{}' seems to have the correct protection from clickjacking...".format(
|
||||
"provided URL '{}' seems to have the correct protection from clickjacking".format(
|
||||
url
|
||||
), level=40
|
||||
))
|
||||
|
|
@ -109,6 +109,6 @@ def clickjacking_main(url, **kwargs):
|
|||
except Exception as e: # until I figure out the errors, we'll just make issues about them
|
||||
lib.core.settings.logger.exception(lib.core.settings.set_color(
|
||||
"Zeus failed to process the clickjacking test and received "
|
||||
"error code '{}'...".format(e), level=50
|
||||
"error code '{}'".format(e), level=50
|
||||
))
|
||||
var.auto_issue.github.request_issue_creation()
|
||||
|
|
|
|||
|
|
@ -1,158 +0,0 @@
|
|||
import re
|
||||
import sys
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
import lib.core.common
|
||||
import lib.core.settings
|
||||
|
||||
|
||||
def __create_url(redirect, template="https://gist.github.com{}"):
|
||||
"""
|
||||
create the URL for the Gists
|
||||
"""
|
||||
return template.format(redirect)
|
||||
|
||||
|
||||
def get_raw_html(redirect, verbose=False):
|
||||
"""
|
||||
get the raw HTML of the Gist plus the URL for it
|
||||
"""
|
||||
tag, descriptor = "a", "href"
|
||||
raw_gist_regex = re.compile(r".raw.[a-z0-9]{40}", re.I)
|
||||
_, status, html, _ = lib.core.common.get_page(redirect)
|
||||
|
||||
if status == 200:
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
for link in soup.findAll(tag):
|
||||
raw_gist_redirect = link.get(descriptor)
|
||||
if raw_gist_regex.search(str(raw_gist_redirect)) is not None:
|
||||
url = __create_url(raw_gist_redirect)
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"found raw Gist URL '{}'...".format(url), level=10
|
||||
))
|
||||
_, _, html, _ = lib.core.common.get_page(url)
|
||||
raw_soup = BeautifulSoup(html, "html.parser")
|
||||
return raw_soup, url
|
||||
else:
|
||||
return None, None
|
||||
|
||||
|
||||
def get_links(page_set, proxy=None, agent=None):
|
||||
"""
|
||||
parse 10 pages of Github gists and use them
|
||||
"""
|
||||
redirects, retval = set(), set()
|
||||
gist_search_url = "https://gist.github.com/discover?page={}"
|
||||
tag, descriptor = "a", "href"
|
||||
gist_regex = re.compile(r"[a-f0-9]{32}", re.I)
|
||||
gist_skip_schema = ("stargazers", "forks", "#comments")
|
||||
|
||||
for i in range(page_set):
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"fetching all Gists on page #{}...".format(i+1)
|
||||
))
|
||||
_, status, html, _ = lib.core.common.get_page(
|
||||
gist_search_url.format(i+1), proxy=proxy, agent=agent
|
||||
)
|
||||
if status == 200:
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
for link in soup.findAll(tag):
|
||||
redirect = link.get(descriptor)
|
||||
if not any(s in redirect for s in gist_skip_schema):
|
||||
if gist_regex.search(redirect) is not None:
|
||||
if not any(protocol in redirect for protocol in ["https://", "http://"]):
|
||||
redirects.add(__create_url(redirect))
|
||||
else:
|
||||
redirects.add(redirect)
|
||||
else:
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"page #{} failed to load with status code {} (reason '{}')...".format(
|
||||
i+1, status, lib.core.common.STATUS_CODES[int(status)]
|
||||
), level=30
|
||||
))
|
||||
continue
|
||||
return redirects
|
||||
|
||||
|
||||
def check_files_for_information(data_to_search, query):
|
||||
"""
|
||||
check the files to see if they contain any of the information that was specified
|
||||
"""
|
||||
# create multiple regex types to ensure that we cover all our
|
||||
# bases while we do the searching.
|
||||
# this will make it so that if there is a match anywhere
|
||||
# in anything, we'll find it.
|
||||
data_to_search = str(data_to_search)
|
||||
data_regex_schema = (
|
||||
# match a URL with or without www
|
||||
re.compile(r"(http(s)?)?(.//)?(www.)?{}".format(query), re.I),
|
||||
# match our string and any random character around it (I like to call it the tittyex)
|
||||
re.compile(r"(.)?{}(.)?".format(query), re.I),
|
||||
# single boundary match, checks if it's inside of something else
|
||||
re.compile(r"\b{}".format(query), re.I),
|
||||
# double boundary, same as above but with another boundary
|
||||
re.compile(r"\b{}\b".format(query), re.I),
|
||||
# wildcard match
|
||||
re.compile(r"{}*".format(query), re.I),
|
||||
# normal match
|
||||
re.compile(r"{}".format(query), re.I)
|
||||
)
|
||||
for regex in list(data_regex_schema):
|
||||
if regex.search(data_to_search) is not None:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"found match with given specifics ('{}'), saving Gist to file...".format(
|
||||
regex.pattern
|
||||
), level=25
|
||||
))
|
||||
lib.core.common.write_to_log_file(
|
||||
data_to_search,
|
||||
lib.core.settings.GIST_MATCH_LOG,
|
||||
lib.core.settings.GIST_FILENAME.format(query)
|
||||
)
|
||||
|
||||
|
||||
# @lib.core.decorators.tail_call_optimized
|
||||
def github_gist_search_main(query, **kwargs):
|
||||
"""
|
||||
main function for searching Gists
|
||||
"""
|
||||
proxy = kwargs.get("proxy", None)
|
||||
agent = kwargs.get("agent", None)
|
||||
verbose = kwargs.get("verbose", False)
|
||||
page_set = kwargs.get("page_set", 10)
|
||||
|
||||
# there seems to be a recursion issue in this function,
|
||||
# so until I get this figured out, we're going to change
|
||||
# the maximum recursion of the system when we get here
|
||||
sys.setrecursionlimit(1500)
|
||||
|
||||
try:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"searching a total of {} pages of Gists for '{}'...".format(
|
||||
page_set, query
|
||||
)
|
||||
))
|
||||
|
||||
if "www." in query:
|
||||
query = query.split(".")[1]
|
||||
|
||||
links = get_links(page_set, proxy=proxy, agent=agent)
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"found a total of {} links to search...".format(
|
||||
len(links)
|
||||
), level=15
|
||||
))
|
||||
for link in list(links):
|
||||
if link is not None:
|
||||
gist, gist_link = get_raw_html(link, verbose=verbose)
|
||||
check_files_for_information(gist, query)
|
||||
except KeyboardInterrupt:
|
||||
if not lib.core.common.pause():
|
||||
lib.core.common.shutdown()
|
||||
except Exception as e:
|
||||
lib.core.settings.logger.exception(lib.core.settings.set_color(
|
||||
"Gist search has failed with error '{}'...".format(str(e)), level=50
|
||||
))
|
||||
|
|
@ -41,7 +41,7 @@ class NmapHook(object):
|
|||
"""
|
||||
send all the information to a JSON file for further use
|
||||
"""
|
||||
lib.core.common.write_to_log_file(
|
||||
return lib.core.common.write_to_log_file(
|
||||
data, lib.core.settings.NMAP_LOG_FILE_PATH,
|
||||
lib.core.settings.NMAP_FILENAME.format(self.ip)
|
||||
)
|
||||
|
|
@ -52,13 +52,14 @@ class NmapHook(object):
|
|||
"""
|
||||
# have to create a spacer or the output comes out funky..
|
||||
spacer_data = {4: " " * 8, 6: " " * 6, 8: " " * 4}
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color("finding data for IP '{}'...".format(self.ip)))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color("finding data for IP '{}'".format(self.ip)))
|
||||
json_data = json.loads(json_data)["scan"]
|
||||
host = json_data[self.ip]["hostnames"][0]["name"]
|
||||
host_skip = (not len(host) == 0, " ", "", None)
|
||||
print(
|
||||
"{}\nScanned: {} ({})\tStatus: {}\nProtocol: {}\n".format(
|
||||
sep, self.ip,
|
||||
host if host is not "" or None or not len(host) == 0 else "unknown",
|
||||
host if host != any(s for s in list(host_skip)) else "unknown",
|
||||
json_data[self.ip]["status"]["state"],
|
||||
"TCP"
|
||||
)
|
||||
|
|
@ -98,35 +99,35 @@ def perform_port_scan(url, scanner=NmapHook, **kwargs):
|
|||
|
||||
with lib.core.decorators.TimeOut(seconds=timeout_time):
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"if the port scan is not completed in {}(m) it will timeout...".format(
|
||||
"if the port scan is not completed in {}(m) it will timeout".format(
|
||||
lib.core.settings.convert_to_minutes(timeout_time)
|
||||
), level=30
|
||||
))
|
||||
url = url.strip()
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"attempting to find IP address for hostname '{}'...".format(url)
|
||||
"attempting to find IP address for hostname '{}'".format(url)
|
||||
))
|
||||
|
||||
try:
|
||||
found_ip_address = socket.gethostbyname(url)
|
||||
except socket.gaierror:
|
||||
lib.core.settings.logger.fatal(lib.core.settings.set_color(
|
||||
"failed to gather IP address for URL '{}'...".format(url)
|
||||
"failed to gather IP address for URL '{}'".format(url)
|
||||
))
|
||||
return
|
||||
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"checking for nmap on your system...", level=10
|
||||
"checking for nmap on your system", level=10
|
||||
))
|
||||
nmap_exists = "".join(find_nmap())
|
||||
if nmap_exists:
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"nmap has been found under '{}'...".format(nmap_exists), level=10
|
||||
"nmap has been found under '{}'".format(nmap_exists), level=10
|
||||
))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"starting port scan on IP address '{}'...".format(found_ip_address)
|
||||
"starting port scan on IP address '{}'".format(found_ip_address)
|
||||
))
|
||||
try:
|
||||
data = scanner(found_ip_address, opts=opts)
|
||||
|
|
@ -134,11 +135,11 @@ def perform_port_scan(url, scanner=NmapHook, **kwargs):
|
|||
data.show_open_ports(json_data)
|
||||
file_path = data.send_to_file(json_data)
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"port scan completed, all data saved to JSON file under '{}'...".format(file_path)
|
||||
"port scan completed, all data saved to JSON file under '{}'".format(file_path)
|
||||
))
|
||||
except KeyError:
|
||||
lib.core.settings.logger.fatal(lib.core.settings.set_color(
|
||||
"no port information found for '{}({})'...".format(
|
||||
"no port information found for '{}({})'".format(
|
||||
url, found_ip_address
|
||||
), level=50
|
||||
))
|
||||
|
|
@ -149,20 +150,20 @@ def perform_port_scan(url, scanner=NmapHook, **kwargs):
|
|||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"port scan is taking to long and has hit the timeout, you "
|
||||
"can increase this time by passing the --time-sec flag (IE "
|
||||
"--time-sec 300)...", level=40
|
||||
"--time-sec 300)", level=40
|
||||
))
|
||||
except Exception as e:
|
||||
lib.core.settings.logger.exception(lib.core.settings.set_color(
|
||||
"ran into exception '{}', cannot continue quitting...".format(e), level=50
|
||||
"ran into exception '{}', cannot continue quitting".format(e), level=50
|
||||
))
|
||||
request_issue_creation()
|
||||
pass
|
||||
else:
|
||||
lib.core.settings.logger.fatal(lib.core.settings.set_color(
|
||||
"nmap was not found on your system...", level=50
|
||||
"nmap was not found on your system", level=50
|
||||
))
|
||||
lib.core.common.run_fix(
|
||||
"would you like to automatically install it",
|
||||
"sudo sh {}".format(lib.core.settings.NMAP_INSTALLER_TOOL),
|
||||
"nmap is not installed, please install it in order to continue..."
|
||||
"nmap is not installed, please install it in order to continue"
|
||||
)
|
||||
|
|
@ -111,7 +111,7 @@ class SqlmapHook(object):
|
|||
if current_status != "running":
|
||||
raise lib.core.errors.SqlmapFailedStart(
|
||||
"sqlmap API failed to start the run, check the client and see what "
|
||||
"the problem is and try again..."
|
||||
"the problem is and try again"
|
||||
)
|
||||
already_displayed = set()
|
||||
while current_status == "running":
|
||||
|
|
@ -156,7 +156,7 @@ def sqlmap_scan_main(url, port=None, verbose=None, opts=None, auto_start=False):
|
|||
|
||||
if auto_start:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"attempting to launch sqlmap API..."
|
||||
"attempting to launch sqlmap API"
|
||||
))
|
||||
sqlmap_api_command = shlex.split("sudo sh {} p {}".format(
|
||||
lib.core.settings.LAUNCH_SQLMAP_API_TOOL, "".join(found_path)
|
||||
|
|
@ -164,58 +164,58 @@ def sqlmap_scan_main(url, port=None, verbose=None, opts=None, auto_start=False):
|
|||
subprocess.Popen(sqlmap_api_command, stdout=subprocess.PIPE)
|
||||
if is_started:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"sqlmap API is up and running, continuing process..."
|
||||
"sqlmap API is up and running, continuing process"
|
||||
))
|
||||
else:
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"there was a problem starting sqlmap API...", level=40
|
||||
"there was a problem starting sqlmap API", level=40
|
||||
))
|
||||
lib.core.common.prompt(
|
||||
"manually start the API and press enter when ready..."
|
||||
"manually start the API and press enter when ready"
|
||||
)
|
||||
else:
|
||||
if not is_started:
|
||||
lib.core.common.prompt(
|
||||
"sqlmap API is not started, start it and press enter to continue..."
|
||||
"sqlmap API is not started, start it and press enter to continue"
|
||||
)
|
||||
try:
|
||||
sqlmap_scan = SqlmapHook(url, port=port)
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"initializing new sqlmap scan with given URL '{}'...".format(url)
|
||||
"initializing new sqlmap scan with given URL '{}'".format(url)
|
||||
))
|
||||
sqlmap_scan.init_new_scan()
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"scan initialized...", level=10
|
||||
"scan initialized", level=10
|
||||
))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"gathering sqlmap API scan ID..."
|
||||
"gathering sqlmap API scan ID"
|
||||
))
|
||||
api_id = sqlmap_scan.get_scan_id()
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"current sqlmap scan ID: '{}'...".format(api_id), level=10
|
||||
"current sqlmap scan ID: '{}'".format(api_id), level=10
|
||||
))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"starting sqlmap scan on url: '{}'...".format(url), level=25
|
||||
"starting sqlmap scan on url: '{}'".format(url), level=25
|
||||
))
|
||||
if opts:
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"using arguments: '{}'...".format(opts), level=10
|
||||
"using arguments: '{}'".format(opts), level=10
|
||||
))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"adding arguments to sqlmap API..."
|
||||
"adding arguments to sqlmap API"
|
||||
))
|
||||
else:
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"no arguments passed, skipping...", level=10
|
||||
"no arguments passed, skipping", level=10
|
||||
))
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"please keep in mind that this is the API, output will "
|
||||
"not be saved to log file, it may take a little longer "
|
||||
"to finish processing, launching sqlmap...", level=30
|
||||
"to finish processing, launching sqlmap", level=30
|
||||
))
|
||||
sqlmap_scan.start_scan(api_id, opts=opts)
|
||||
print("-" * 30)
|
||||
|
|
@ -224,7 +224,7 @@ def sqlmap_scan_main(url, port=None, verbose=None, opts=None, auto_start=False):
|
|||
except requests.exceptions.HTTPError as e:
|
||||
lib.core.settings.logger.exception(lib.core.settings.set_color(
|
||||
"ran into error '{}', seems you didn't start the server, check "
|
||||
"the server port and try again...".format(e), level=50
|
||||
"the server port and try again".format(e), level=50
|
||||
))
|
||||
pass
|
||||
except KeyboardInterrupt:
|
||||
|
|
@ -236,7 +236,7 @@ def sqlmap_scan_main(url, port=None, verbose=None, opts=None, auto_start=False):
|
|||
"sqlmap API is not started, did you forget to start it? "
|
||||
"You will need to open a new terminal, cd into sqlmap, and "
|
||||
"run `python sqlmapapi.py -s` otherwise pass the correct flags "
|
||||
"to auto start the API...", level=40
|
||||
"to auto start the API", level=40
|
||||
))
|
||||
pass
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ def whois_lookup_main(domain, **kwargs):
|
|||
|
||||
try:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"performing WhoIs lookup on given domain '{}'...".format(domain)
|
||||
"performing WhoIs lookup on given domain '{}'".format(domain)
|
||||
))
|
||||
if timeout is not None:
|
||||
time.sleep(timeout)
|
||||
|
|
@ -82,14 +82,14 @@ def whois_lookup_main(domain, **kwargs):
|
|||
raw_information = gather_raw_whois_info(domain)
|
||||
except Exception:
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"unable to produce information from WhoIs lookup...", level=40
|
||||
"unable to produce information from WhoIs lookup", level=40
|
||||
))
|
||||
return None
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"discovered raw information...", level=25
|
||||
"discovered raw information", level=25
|
||||
))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"gathering interesting information..."
|
||||
"gathering interesting information"
|
||||
))
|
||||
interesting_data = get_interesting(raw_information)
|
||||
if verbose:
|
||||
|
|
@ -97,7 +97,7 @@ def whois_lookup_main(domain, **kwargs):
|
|||
human_readable_display(domain, interesting_data)
|
||||
except (ValueError, Exception):
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"unable to display any information from WhoIs lookup on domain '{}'...".format(domain), level=50
|
||||
"unable to display any information from WhoIs lookup on domain '{}'".format(domain), level=50
|
||||
))
|
||||
return None
|
||||
lib.core.common.write_to_log_file(
|
||||
|
|
|
|||
|
|
@ -29,6 +29,19 @@ def list_tamper_scripts(path="{}/lib/tamper_scripts"):
|
|||
return retval
|
||||
|
||||
|
||||
def assign_protocol(url, force=False):
|
||||
auto_assign = ("http://{}", "https://{}")
|
||||
url_verification = re.compile(r"http(s)?", re.I)
|
||||
|
||||
if url_verification.search(url) is None:
|
||||
if not force:
|
||||
return auto_assign[0].format(url)
|
||||
else:
|
||||
return auto_assign[1].format(url)
|
||||
else:
|
||||
return url
|
||||
|
||||
|
||||
def __tamper_payload(payload, tamper_type, warning=True, **kwargs):
|
||||
"""
|
||||
add the tamper to the payload from the given tamper type
|
||||
|
|
@ -40,7 +53,7 @@ def __tamper_payload(payload, tamper_type, warning=True, **kwargs):
|
|||
if warning:
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"tampering payload with '{}'...".format(tamper), level=10
|
||||
"tampering payload with '{}'".format(tamper), level=10
|
||||
))
|
||||
if tamper in acceptable:
|
||||
tamper_name = "lib.tamper_scripts.{}_encode"
|
||||
|
|
@ -58,7 +71,7 @@ def __load_payloads(filename="{}/etc/text_files/xss_payloads.txt"):
|
|||
with open(filename.format(os.getcwd())) as payloads: return payloads.readlines()
|
||||
|
||||
|
||||
def create_urls(url, payload_list, tamper=None, verbose=False):
|
||||
def create_urls(url, payload_list, tamper=None, verbose=False, force=False):
|
||||
"""
|
||||
create the tampered URL's, write them to a temporary file and read them from there
|
||||
"""
|
||||
|
|
@ -73,13 +86,12 @@ def create_urls(url, payload_list, tamper=None, verbose=False):
|
|||
else:
|
||||
payload = __tamper_payload(payload, tamper_type=tamper, warning=False, verbose=verbose)
|
||||
except InvalidTamperProvided:
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"you provided and invalid tamper script, acceptable tamper scripts are: {}...".format(
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"you provided and invalid tamper script, acceptable tamper scripts are: {}".format(
|
||||
" | ".join(list_tamper_scripts()), level=40
|
||||
)
|
||||
))
|
||||
lib.core.common.shutdown()
|
||||
loaded_url = "{}{}\n".format(url.strip(), payload.strip())
|
||||
loaded_url = "{}{}\n".format(assign_protocol(url.strip(), force=force), payload.strip())
|
||||
tmp.write(loaded_url)
|
||||
return tf_name
|
||||
|
||||
|
|
@ -97,7 +109,7 @@ def find_xss_script(url, **kwargs):
|
|||
else:
|
||||
retval = data[payload_parser["query"]]
|
||||
|
||||
# just double checking...
|
||||
# just double checking
|
||||
if retval == "" or None:
|
||||
retval = data[payload_parser["path"]]
|
||||
return retval
|
||||
|
|
@ -110,35 +122,19 @@ def scan_xss(url, agent=None, proxy=None):
|
|||
be tampered or encoded if the site is not vulnerable
|
||||
"""
|
||||
|
||||
retry_flags = 3
|
||||
auto_assign = "http://{}"
|
||||
url_verification = re.compile(r"http(s)?", re.I)
|
||||
|
||||
if url_verification.search(url) is None:
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"protocol missing from URL, automatically assigning protocol...", level=30
|
||||
))
|
||||
url = auto_assign.format(url)
|
||||
|
||||
while retry_flags > 0:
|
||||
try:
|
||||
_, status, html_data, _ = lib.core.common.get_page(url, agent=agent, proxy=proxy)
|
||||
query = find_xss_script(url)
|
||||
for db in lib.core.settings.DBMS_ERRORS.keys():
|
||||
for item in lib.core.settings.DBMS_ERRORS[db]:
|
||||
if re.findall(item, html_data):
|
||||
return "sqli", db
|
||||
if status != 404:
|
||||
if query in html_data:
|
||||
return True, None
|
||||
retry_flags -= 1
|
||||
except requests.exceptions.ChunkedEncodingError:
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"encoding seems to be messed up, retrying request...", level=30
|
||||
))
|
||||
retry_flags -= 1
|
||||
|
||||
return False, None
|
||||
try:
|
||||
_, status, html_data, _ = lib.core.common.get_page(url, agent=agent, proxy=proxy)
|
||||
query = find_xss_script(url)
|
||||
for db in lib.core.settings.DBMS_ERRORS.keys():
|
||||
for item in lib.core.settings.DBMS_ERRORS[db]:
|
||||
if re.findall(item, html_data):
|
||||
return "sqli", db
|
||||
if status != 404:
|
||||
if query in html_data:
|
||||
return True, None
|
||||
return False, None
|
||||
except (requests.exceptions.ChunkedEncodingError, requests.exceptions.ConnectionError):
|
||||
return False, None
|
||||
|
||||
|
||||
def main_xss(start_url, proxy=None, agent=None, **kwargs):
|
||||
|
|
@ -148,6 +144,7 @@ def main_xss(start_url, proxy=None, agent=None, **kwargs):
|
|||
tamper = kwargs.get("tamper", None)
|
||||
verbose = kwargs.get("verbose", False)
|
||||
batch = kwargs.get("batch", False)
|
||||
force = kwargs.get("force_ssl", False)
|
||||
|
||||
question_msg = (
|
||||
"it appears that heuristic tests have shown this URL may not be a good "
|
||||
|
|
@ -168,30 +165,30 @@ def main_xss(start_url, proxy=None, agent=None, **kwargs):
|
|||
try:
|
||||
if tamper:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"tampering payloads with '{}'...".format(tamper)
|
||||
"tampering payloads with '{}'".format(tamper)
|
||||
))
|
||||
find_xss_script(start_url)
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"loading payloads..."
|
||||
"loading payloads"
|
||||
))
|
||||
payloads = __load_payloads()
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"a total of {} payloads loaded...".format(len(payloads)), level=10
|
||||
"a total of {} payloads loaded".format(len(payloads)), level=10
|
||||
))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"payloads will be written to a temporary file and read from there..."
|
||||
"payloads will be written to a temporary file and read from there"
|
||||
))
|
||||
filename = create_urls(start_url, payloads, tamper=tamper, verbose=verbose)
|
||||
filename = create_urls(start_url, payloads, tamper=tamper, verbose=verbose, force=force)
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"loaded URL's have been saved to '{}'...".format(filename), level=25
|
||||
"loaded URL's have been saved to '{}'".format(filename), level=25
|
||||
))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"testing for XSS vulnerabilities on host '{}'...".format(start_url)
|
||||
"testing for XSS vulnerabilities on host '{}'".format(start_url)
|
||||
))
|
||||
if proxy is not None:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"using proxy '{}'...".format(proxy)
|
||||
"using proxy '{}'".format(proxy)
|
||||
))
|
||||
success = set()
|
||||
with open(filename) as urls:
|
||||
|
|
@ -202,42 +199,44 @@ def main_xss(start_url, proxy=None, agent=None, **kwargs):
|
|||
result = scan_xss(url, proxy=proxy, agent=agent)
|
||||
if verbose:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"trying payload '{}'...".format(payload)
|
||||
"trying payload '{}'".format(payload)
|
||||
))
|
||||
if result[0] != "sqli" and result[0] is True:
|
||||
success.add(url)
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"payload '{}' appears to be usable...".format(payload), level=15
|
||||
"payload '{}' appears to be usable".format(payload), level=15
|
||||
))
|
||||
elif result[0] is "sqli":
|
||||
if i <= 1:
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"loaded URL '{}' threw a DBMS error and appears to be injectable, test for "
|
||||
"SQL injection, backend DBMS appears to be '{}'...".format(
|
||||
"SQL injection, backend DBMS appears to be '{}'".format(
|
||||
url, result[1]
|
||||
), level=40
|
||||
))
|
||||
else:
|
||||
if verbose:
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"SQL error discovered...", level=40
|
||||
"SQL error discovered", level=40
|
||||
))
|
||||
else:
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"host '{}' does not appear to be vulnerable to XSS attacks with payload '{}'...".format(
|
||||
"host '{}' does not appear to be vulnerable to XSS attacks with payload '{}'".format(
|
||||
start_url, payload
|
||||
), level=10
|
||||
))
|
||||
except (
|
||||
requests.exceptions.ConnectionError,
|
||||
requests.exceptions.TooManyRedirects,
|
||||
requests.exceptions.ReadTimeout
|
||||
requests.exceptions.ReadTimeout,
|
||||
requests.exceptions.InvalidURL
|
||||
):
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"payload '{}' caused a connection error, assuming no good and continuing...".format(payload), level=40
|
||||
))
|
||||
if not payload == "":
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"payload '{}' caused a connection error, assuming no good and continuing".format(payload), level=40
|
||||
))
|
||||
|
||||
if len(success) != 0:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
|
|
@ -246,7 +245,7 @@ def main_xss(start_url, proxy=None, agent=None, **kwargs):
|
|||
lib.core.settings.create_tree(start_url, list(success))
|
||||
else:
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"host '{}' does not appear to be vulnerable to XSS attacks...".format(start_url), level=40
|
||||
"host '{}' does not appear to be vulnerable to XSS attacks".format(start_url), level=40
|
||||
))
|
||||
question_msg = "would you like to keep the created URLs saved for further testing"
|
||||
if not batch:
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ STATUS_CODES = {
|
|||
200: "OK", 201: "created", 202: "accepted", 203: "non-authoritative information",
|
||||
204: "no content", 205: "reset content", 206: "partial content",
|
||||
207: "multi-status", 208: "already reported", 226: "IM used",
|
||||
300: "multiple choices", 301: "moved permanently", 302: "not found",
|
||||
300: "multiple choices", 301: "moved permanently", 302: "found redirect",
|
||||
303: "see other", 304: "not modified", 305: "use proxy",
|
||||
306: "switch proxy", 308: "permanent redirect",
|
||||
400: "bad request", 401: "unauthorized", 402: "payment required",
|
||||
|
|
@ -162,7 +162,7 @@ def write_to_log_file(data_to_write, path, filename, blacklist=False):
|
|||
items = log.readlines()
|
||||
if any(d.strip() == data_to_write for d in items):
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"query already in blacklist..."
|
||||
"query already in blacklist"
|
||||
))
|
||||
return full_file_path
|
||||
else:
|
||||
|
|
@ -181,7 +181,7 @@ def write_to_log_file(data_to_write, path, filename, blacklist=False):
|
|||
else:
|
||||
log.write(data_to_write + "\n")
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"successfully wrote found items to '{}'...".format(full_file_path)
|
||||
"successfully wrote found items to '{}'".format(full_file_path)
|
||||
))
|
||||
return full_file_path
|
||||
|
||||
|
|
@ -276,7 +276,7 @@ def run_fix(message, command, fail_message, exit_process=False):
|
|||
subprocess.call(cmd)
|
||||
if exit_process:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"command completed successfully, should be safe to re-run Zeus..."
|
||||
"command completed successfully, should be safe to re-run Zeus"
|
||||
))
|
||||
else:
|
||||
lib.core.settings.logger.fatal(lib.core.settings.set_color(
|
||||
|
|
@ -329,7 +329,11 @@ def get_page(url, **kwargs):
|
|||
else:
|
||||
proxies = {}
|
||||
|
||||
req = requests.get(url, params=headers, proxies=proxies, verify=False if skip_verf else True, timeout=20)
|
||||
if proxy is not None and "127.0.0.1" in proxy:
|
||||
req = requests.get(url, params=headers, proxies=proxies, verify=False, timeout=40)
|
||||
else:
|
||||
req = requests.get(url, params=headers, proxies=proxies, verify=False, timeout=20)
|
||||
|
||||
status = req.status_code
|
||||
html = req.content
|
||||
headers = req.headers
|
||||
|
|
|
|||
|
|
@ -19,4 +19,7 @@ class InvalidInputProvided(Exception): pass
|
|||
class InvalidTamperProvided(Exception): pass
|
||||
|
||||
|
||||
class PortScanTimeOutException(Exception): pass
|
||||
class PortScanTimeOutException(Exception): pass
|
||||
|
||||
|
||||
class ZeusArgumentException(Exception): pass
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import sys
|
||||
from optparse import (
|
||||
OptionParser,
|
||||
OptionGroup,
|
||||
|
|
@ -6,6 +7,7 @@ from optparse import (
|
|||
|
||||
import lib.core.settings
|
||||
import lib.core.common
|
||||
import lib.core.errors
|
||||
import lib.attacks.nmap_scan.nmap_opts
|
||||
import lib.attacks.sqlmap_scan.sqlmap_opts
|
||||
|
||||
|
|
@ -24,7 +26,7 @@ class ZeusParser(OptionParser):
|
|||
"""
|
||||
command line parser, parses all of Zeus's arguments and flags
|
||||
"""
|
||||
parser = OptionParser(usage="./zeus.py -d|r|l|f|b| DORK|FILE|URL [ATTACKS] [--OPTS]")
|
||||
parser = OptionParser(usage="./zeus.py -d|r|l|f|b DORK|FILE|URL [ATTACKS] [--OPTS]")
|
||||
|
||||
# mandatory options
|
||||
mandatory = OptionGroup(parser, "Mandatory Options",
|
||||
|
|
@ -45,6 +47,11 @@ class ZeusParser(OptionParser):
|
|||
mandatory.add_option("-f", "--url-file", dest="fileToEnumerate", metavar="FILE-PATH",
|
||||
help="Run an attack on URL's in a given file")
|
||||
|
||||
# being worked on
|
||||
# TODO:/
|
||||
mandatory.add_option("-u", "--url", dest="singleTargetRecon", metavar="URL",
|
||||
help=SUPPRESS_HELP)
|
||||
|
||||
# attack options
|
||||
attacks = OptionGroup(parser, "Attack arguments",
|
||||
"These arguments will give you the choice on how you want to check the websites")
|
||||
|
|
@ -67,8 +74,10 @@ class ZeusParser(OptionParser):
|
|||
attacks.add_option("-c", "--clickjacking", dest="performClickjackingScan", action="store_true",
|
||||
help="Perform a clickjacking scan on a provided URL")
|
||||
|
||||
# being worked on
|
||||
# TODO:/
|
||||
attacks.add_option("-g", "--github-search", dest="searchGithub", action="store_true",
|
||||
help="Perform a Github Gist search for any information on the found websites")
|
||||
help=SUPPRESS_HELP)
|
||||
|
||||
attacks.add_option("-P", "--pgp", dest="pgpLookup", action="store_true",
|
||||
help="Perform a PGP public key lookup on the found URLs")
|
||||
|
|
@ -96,6 +105,8 @@ class ZeusParser(OptionParser):
|
|||
attacks.add_option("--tamper", dest="tamperXssPayloads", metavar="TAMPER-SCRIPT",
|
||||
help="Send the XSS payloads through tampering before sending to the target")
|
||||
|
||||
# being worked on
|
||||
# TODO:/
|
||||
attacks.add_option("--thread", dest="threadPanels", action="store_true",
|
||||
help=SUPPRESS_HELP)
|
||||
|
||||
|
|
@ -141,6 +152,11 @@ class ZeusParser(OptionParser):
|
|||
help="Attempt to identify if the target is protected by some kind of "
|
||||
"WAF/IDS/IPS")
|
||||
|
||||
# being worked on
|
||||
# TODO:/
|
||||
search_items.add_option("--force-ssl", dest="forceSSL", action="store_true",
|
||||
help=SUPPRESS_HELP)
|
||||
|
||||
search_items.add_option("--identify-plugins", dest="identifyPlugin", action="store_true",
|
||||
help="Attempt to identify what plugins the target is using")
|
||||
|
||||
|
|
@ -182,6 +198,8 @@ class ZeusParser(OptionParser):
|
|||
misc.add_option("--version", dest="showCurrentVersion", action="store_true",
|
||||
help="Show the current version and exit")
|
||||
|
||||
# being worked on
|
||||
# TODO:/
|
||||
misc.add_option("-T", "--x-threads", dest="amountOfThreads", metavar="THREAD-AMOUNT", type=int,
|
||||
help=SUPPRESS_HELP)
|
||||
|
||||
|
|
@ -221,7 +239,7 @@ class ZeusParser(OptionParser):
|
|||
)
|
||||
print("\n")
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"for more information about sqlmap arguments, see here '{}'...".format(
|
||||
"for more information about sqlmap arguments, see here '{}'".format(
|
||||
lib.core.settings.SQLMAP_MAN_PAGE_URL
|
||||
)
|
||||
))
|
||||
|
|
@ -240,7 +258,7 @@ class ZeusParser(OptionParser):
|
|||
)
|
||||
print("\n")
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"for more information on what the arguments do please see here '{}'...".format(
|
||||
"for more information on what the arguments do please see here '{}'".format(
|
||||
lib.core.settings.NMAP_MAN_PAGE_URL
|
||||
)
|
||||
))
|
||||
|
|
@ -249,7 +267,29 @@ class ZeusParser(OptionParser):
|
|||
# update the program
|
||||
if opt.updateZeus:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"update in progress..."
|
||||
"update in progress"
|
||||
))
|
||||
lib.core.settings.update_zeus()
|
||||
lib.core.common.shutdown()
|
||||
|
||||
@staticmethod
|
||||
def verify_args(args=sys.argv):
|
||||
not_implemented_args = (
|
||||
"-T", "--x-threads", "--force-ssl", "--thread",
|
||||
"-g", "--github-search", "-u", "--url"
|
||||
)
|
||||
# check if any of the arguments are not implemented that have been passed
|
||||
# via the command line
|
||||
# TODO:/
|
||||
# need to create a way to parse all arguments for compatibility with one another
|
||||
for arg in args:
|
||||
for nia in not_implemented_args:
|
||||
if arg == nia:
|
||||
raise lib.core.errors.ZeusArgumentException(
|
||||
"\n\nit appears that one of the arguments you have passed ('{}'), "
|
||||
"has not been implemented into Zeus production yet. This usually means "
|
||||
"that the option is still in testing and is not ready for use. Arguments "
|
||||
"that are still in testing are: {}\n".format(
|
||||
nia, ", ".join(["'{}'".format(a) for a in not_implemented_args])
|
||||
)
|
||||
)
|
||||
|
|
@ -8,7 +8,6 @@ import shlex
|
|||
import difflib
|
||||
import logging
|
||||
import base64
|
||||
import string
|
||||
import random
|
||||
import socket
|
||||
import struct
|
||||
|
|
@ -45,7 +44,7 @@ CLONE = "https://github.com/ekultek/zeus-scanner.git"
|
|||
ISSUE_LINK = "https://github.com/ekultek/zeus-scanner/issues"
|
||||
|
||||
# current version <major.minor.commit.patch ID>
|
||||
VERSION = "1.4".format(PATCH_ID)
|
||||
VERSION = "1.5.2.{}".format(PATCH_ID)
|
||||
|
||||
# colors to output depending on the version
|
||||
VERSION_TYPE_COLORS = {"dev": 33, "stable": 92, "other": 30}
|
||||
|
|
@ -284,13 +283,6 @@ AUTHORIZED_SEARCH_ENGINES = {
|
|||
"pgp": "https://pgp.mit.edu/pks/lookup?search={}&op=index"
|
||||
}
|
||||
|
||||
# search page for Gists and rate checking URL
|
||||
GITHUB_GIST_SEARCH_URLS = {
|
||||
"search": "https://api.github.com/gists/public?page={}&per_page=100",
|
||||
"check_rate": "https://api.github.com/users/ZeusIssueReporter"
|
||||
|
||||
}
|
||||
|
||||
# extensions to exclude from the spider
|
||||
SPIDER_EXT_EXCLUDE = (
|
||||
"3ds", "3g2", "3gp", "7z", "DS_Store", "a", "aac", "adp", "ai", "aif", "aiff",
|
||||
|
|
@ -320,7 +312,7 @@ URL_EXCLUDES = (
|
|||
"torproject.org", "search-results.com", "index.com",
|
||||
"gov", ".gov", "facebook.com", "instagram.com", "snapchat",
|
||||
"stackoverflow", "stackexchange", "github.com", "apple.com",
|
||||
"http://my."
|
||||
"http://my.", "root.cern"
|
||||
)
|
||||
|
||||
# regular expressions used for DBMS recognition based on error message response
|
||||
|
|
@ -465,7 +457,7 @@ def setup(verbose=False):
|
|||
"""
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"checking if the application has been run before...", level=10
|
||||
"checking if the application has been run before", level=10
|
||||
))
|
||||
bin.unzip_gecko.main(verbose=verbose)
|
||||
|
||||
|
|
@ -513,12 +505,12 @@ def grab_random_agent(agent_path="{}/etc/text_files/agents.txt", verbose=False):
|
|||
"""
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"grabbing random user-agent from '{}'...".format(agent_path.format(os.getcwd())), level=10
|
||||
"grabbing random user-agent from '{}'".format(agent_path.format(os.getcwd())), level=10
|
||||
))
|
||||
with open(agent_path.format(os.getcwd())) as agents:
|
||||
retval = random.choice(agents.readlines())
|
||||
logger.info(set_color(
|
||||
"random agent being used '{}'...".format(retval.strip())
|
||||
"random agent being used '{}'".format(retval.strip())
|
||||
))
|
||||
return retval.strip()
|
||||
|
||||
|
|
@ -555,7 +547,7 @@ def update_zeus():
|
|||
return os.system("git pull origin master")
|
||||
else:
|
||||
logger.fatal(set_color(
|
||||
"no git repository found in directory, unable to update automatically..."
|
||||
"no git repository found in directory, unable to update automatically"
|
||||
))
|
||||
|
||||
|
||||
|
|
@ -608,28 +600,34 @@ def search_for_process(name):
|
|||
return False if not any(name in proc for proc in list(all_process_names)) else True
|
||||
|
||||
|
||||
def get_browser_version():
|
||||
def get_browser_version(output=True):
|
||||
"""
|
||||
obtain the firefox browser version, this is necessary because zeus can only handle certain versions.
|
||||
"""
|
||||
logger.info(set_color(
|
||||
"attempting to get firefox browser version..."
|
||||
))
|
||||
if output:
|
||||
logger.info(set_color(
|
||||
"attempting to get firefox browser version"
|
||||
))
|
||||
try:
|
||||
firefox_version_command = shlex.split("firefox --version")
|
||||
output = subprocess.check_output(firefox_version_command)
|
||||
except (OSError, Exception):
|
||||
except OSError:
|
||||
logger.error(set_color(
|
||||
"failed to run firefox...", level=50
|
||||
"failed to run firefox", level=50
|
||||
))
|
||||
return "failed to start"
|
||||
try:
|
||||
major, minor = map(int, re.search(r"(\d+).(\d+)", output).groups())
|
||||
except (ValueError, Exception):
|
||||
except ValueError:
|
||||
logger.error(set_color(
|
||||
"failed to parse '{}' for version number...".format(output), level=50
|
||||
"failed to parse '{}' for version number".format(output), level=50
|
||||
))
|
||||
return "failed to gather"
|
||||
return output
|
||||
except Exception as e:
|
||||
logger.error(set_color(
|
||||
"received and exception from firefox '{}'".format(str(e), level=50)
|
||||
))
|
||||
return str(e)
|
||||
return major, minor
|
||||
|
||||
|
||||
|
|
@ -643,11 +641,15 @@ def config_headers(**kwargs):
|
|||
rand_agent = kwargs.get("rand_agent", None)
|
||||
verbose = kwargs.get("verbose", False)
|
||||
if proxy is not None:
|
||||
if "127.0.0.1" in proxy:
|
||||
logger.warning(set_color(
|
||||
"timeout will be increased to 40s due to Tor being used", level=30
|
||||
))
|
||||
proxy_retval = proxy
|
||||
elif rand_proxy is not None:
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"loading random proxy from '{}'...".format(rand_proxy), level=10
|
||||
"loading random proxy from '{}'".format(rand_proxy), level=10
|
||||
))
|
||||
with open(rand_proxy) as proxies:
|
||||
possible = proxies.readlines()
|
||||
|
|
@ -673,14 +675,14 @@ def get_md5sum(url="https://raw.githubusercontent.com/Ekultek/Zeus-Scanner/maste
|
|||
return True
|
||||
|
||||
|
||||
def create_identifier(chars=string.ascii_letters):
|
||||
def create_identifier(st):
|
||||
"""
|
||||
create the identifier for your Github issue
|
||||
"""
|
||||
retval = []
|
||||
for _ in range(0, 7):
|
||||
retval.append(random.choice(chars))
|
||||
return "".join(retval)
|
||||
import hashlib
|
||||
obj = hashlib.md5()
|
||||
obj.update(st)
|
||||
return obj.hexdigest()[1:9]
|
||||
|
||||
|
||||
def config_search_engine(**kwargs):
|
||||
|
|
@ -693,8 +695,8 @@ def config_search_engine(**kwargs):
|
|||
ddg = kwargs.get("ddg", False)
|
||||
enum = kwargs.get("enum", None)
|
||||
|
||||
non_default_msg = "specified to use non-default search engine..."
|
||||
se_message = "using '{}' as the search engine..."
|
||||
non_default_msg = "specified to use non-default search engine"
|
||||
se_message = "using '{}' as the search engine"
|
||||
if ddg:
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
|
|
@ -706,7 +708,7 @@ def config_search_engine(**kwargs):
|
|||
se = AUTHORIZED_SEARCH_ENGINES["duckduckgo"]
|
||||
elif aol:
|
||||
logger.warning(set_color(
|
||||
"AOL will take a little longer due to pop-ups...", level=30
|
||||
"AOL will take a little longer due to pop-ups", level=30
|
||||
))
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
|
|
@ -727,16 +729,16 @@ def config_search_engine(**kwargs):
|
|||
se = AUTHORIZED_SEARCH_ENGINES["bing"]
|
||||
elif enum is not None:
|
||||
logger.info(set_color(
|
||||
"running enumeration on given file '{}'...".format(enum)
|
||||
"running enumeration on given file '{}'".format(enum)
|
||||
))
|
||||
se = None
|
||||
else:
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"using default search engine (Google)...", level=10
|
||||
"using default search engine (Google)", level=10
|
||||
))
|
||||
logger.info(set_color(
|
||||
"using default search engine..."
|
||||
"using default search engine"
|
||||
))
|
||||
se = AUTHORIZED_SEARCH_ENGINES["google"]
|
||||
return se
|
||||
|
|
@ -753,7 +755,7 @@ def create_arguments(**kwargs):
|
|||
conf_file = kwargs.get("conf", None)
|
||||
|
||||
logger.info(set_color(
|
||||
"creating arguments for {}...".format("sqlmap" if sqlmap else "nmap")
|
||||
"creating arguments for {}".format("sqlmap" if sqlmap else "nmap")
|
||||
))
|
||||
retval = []
|
||||
splitter = {"sqlmap": ",", "nmap": "|"}
|
||||
|
|
@ -765,7 +767,7 @@ def create_arguments(**kwargs):
|
|||
if o.lower() == opt[0]:
|
||||
retval.append((o, opt[1]))
|
||||
elif sqlmap:
|
||||
warn_msg = "option '{}' is not recognized by sqlmap API, skipping..."
|
||||
warn_msg = "option '{}' is not recognized by sqlmap API, skipping"
|
||||
if sqlmap_args is not None:
|
||||
for line in sqlmap_args.split(splitter["sqlmap"]):
|
||||
try:
|
||||
|
|
@ -788,7 +790,7 @@ def create_arguments(**kwargs):
|
|||
))
|
||||
|
||||
elif nmap:
|
||||
warning_msg = "option {} is not known by the nmap api, skipping..."
|
||||
warning_msg = "option {} is not known by the nmap api, skipping"
|
||||
if nmap_args is not None:
|
||||
for line in nmap_args.split(splitter["nmap"]):
|
||||
try:
|
||||
|
|
@ -826,7 +828,7 @@ def create_random_ip():
|
|||
if generated == "0.0.0.0" or "255.255.255.255":
|
||||
generated = __get_nodes() # if it isn't a real IP regenerate it
|
||||
logger.info(set_color(
|
||||
"random IP address generated for header '{}'...".format(generated)
|
||||
"random IP address generated for header '{}'".format(generated)
|
||||
))
|
||||
return generated
|
||||
|
||||
|
|
@ -854,7 +856,7 @@ def check_for_protection(protected, attack_type):
|
|||
|
||||
if attack_type in items or "all" in items:
|
||||
logger.warning(set_color(
|
||||
"provided target seems to have protection against this attack type...", level=30
|
||||
"provided target seems to have protection against this attack type", level=30
|
||||
))
|
||||
protected.clear() # clear the set
|
||||
return True
|
||||
|
|
@ -868,7 +870,7 @@ def deprecation(target_version, method, connect=True, *args, **kwargs):
|
|||
print(
|
||||
"[{} DEPRECATION] {}".format(
|
||||
time.strftime("%H:%M:%S"), set_color(
|
||||
"{} will be deprecated by version {}...".format(
|
||||
"{} will be deprecated by version {}".format(
|
||||
method.__name__, target_version
|
||||
), level=35
|
||||
)
|
||||
|
|
@ -880,7 +882,7 @@ def deprecation(target_version, method, connect=True, *args, **kwargs):
|
|||
"[{} DEPRECATION] {}".format(
|
||||
time.strftime("%H:%M:%S"), set_color(
|
||||
"{} has been deprecated and will no longer work, "
|
||||
"this attack type will be completely removed by v{}...".format(
|
||||
"this attack type will be completely removed by v{}".format(
|
||||
method.__name__, target_version
|
||||
), level=35
|
||||
)
|
||||
|
|
@ -896,10 +898,10 @@ def check_thread_num(number, batch=False, default=5):
|
|||
logger.warning(set_color(
|
||||
"you have specified {} threads, it is highly advised to not go over {} threads, "
|
||||
"doing so will most likely not give a significant performance increase and also "
|
||||
"will most likely cause unforeseen issues...".format(number, MAX_THREADS), level=30
|
||||
"will most likely cause unforeseen issues".format(number, MAX_THREADS), level=30
|
||||
))
|
||||
question_msg = "would you like to continue anyways"
|
||||
default_msg = "defaulting to 5 threads..."
|
||||
default_msg = "defaulting to 5 threads"
|
||||
if not batch:
|
||||
question = lib.core.common.prompt(
|
||||
question_msg, opts="yN"
|
||||
|
|
@ -931,7 +933,7 @@ def run_attacks(url, **kwargs):
|
|||
verbose = kwargs.get("verbose", False)
|
||||
whois = kwargs.get("whois", False)
|
||||
clickjacking = kwargs.get("clickjacking", False)
|
||||
github = kwargs.get("github", False)
|
||||
# github = kwargs.get("github", False)
|
||||
pgp = kwargs.get("pgp", False)
|
||||
auto_start = kwargs.get("auto_start", False)
|
||||
sqlmap_arguments = kwargs.get("sqlmap_args", None)
|
||||
|
|
@ -946,6 +948,7 @@ def run_attacks(url, **kwargs):
|
|||
agent = kwargs.get("agent", None)
|
||||
conf_file = kwargs.get("conf_file", None)
|
||||
threads = kwargs.get("threads", None)
|
||||
force_ssl = kwargs.get("ssl", False)
|
||||
|
||||
if threads > MAX_THREADS:
|
||||
threads = check_thread_num(threads, batch=batch)
|
||||
|
|
@ -969,7 +972,7 @@ def run_attacks(url, **kwargs):
|
|||
"as of now only 1 attack is supported at a time, choose "
|
||||
"your attack and try again. You can use the -f flag if "
|
||||
"you do not want to complete an entire search again "
|
||||
"(IE -f /home/me/zeus-scanner/log/url-log/url-log-1.log)...", level=40
|
||||
"(IE -f /home/me/zeus-scanner/log/url-log/url-log-1.log)", level=40
|
||||
))
|
||||
lib.core.common.shutdown()
|
||||
|
||||
|
|
@ -1008,6 +1011,7 @@ def run_attacks(url, **kwargs):
|
|||
main_xss(
|
||||
url, verbose=verbose, proxy=proxy,
|
||||
agent=agent, tamper=tamper_script, batch=batch,
|
||||
force_ssl=force_ssl
|
||||
)
|
||||
elif whois:
|
||||
from lib.attacks.whois_lookup.whois import whois_lookup_main
|
||||
|
|
@ -1019,10 +1023,10 @@ def run_attacks(url, **kwargs):
|
|||
if check_for_protection(PROTECTED, "clickjacking"):
|
||||
clickjacking_main(url, agent=agent, proxy=proxy,
|
||||
forward=forwarded, batch=batch)
|
||||
elif github:
|
||||
from lib.attacks.gist_lookup import github_gist_search_main
|
||||
query = replace_http(url)
|
||||
github_gist_search_main(query, agent=agent, proxy=proxy, verbose=verbose)
|
||||
# elif github:
|
||||
# from lib.attacks.gist_lookup import github_gist_search_main
|
||||
# query = replace_http(url)
|
||||
# github_gist_search_main(query, agent=agent, proxy=proxy, verbose=verbose)
|
||||
elif pgp:
|
||||
from var.search.pgp_search import pgp_main
|
||||
pgp_main(url, verbose=verbose)
|
||||
|
|
@ -1030,7 +1034,7 @@ def run_attacks(url, **kwargs):
|
|||
pass
|
||||
else:
|
||||
logger.warning(set_color(
|
||||
"skipping '{}'...".format(url), level=30
|
||||
"skipping '{}'".format(url), level=30
|
||||
))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
import os
|
||||
import re
|
||||
import time
|
||||
import importlib
|
||||
import unicodedata
|
||||
|
||||
from xml.dom import minidom
|
||||
from requests.exceptions import ConnectionError
|
||||
from requests.exceptions import (
|
||||
ConnectionError,
|
||||
ReadTimeout
|
||||
)
|
||||
|
||||
from var.auto_issue.github import request_issue_creation
|
||||
from lib.core.common import (
|
||||
|
|
@ -12,7 +16,7 @@ from lib.core.common import (
|
|||
shutdown,
|
||||
pause,
|
||||
get_page,
|
||||
HTTP_HEADER
|
||||
HTTP_HEADER,
|
||||
)
|
||||
from lib.core.settings import (
|
||||
logger, set_color,
|
||||
|
|
@ -46,17 +50,12 @@ def get_charset(html, headers, **kwargs):
|
|||
content = headers.get(HTTP_HEADER.CONTENT_TYPE, "")
|
||||
charset = charset_regex.search(content)
|
||||
if charset is not None:
|
||||
return charset
|
||||
return charset.group(1)
|
||||
return None
|
||||
|
||||
|
||||
def detect_protection(url, status, html, headers, **kwargs):
|
||||
verbose = kwargs.get("verbose", False)
|
||||
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"attempting connection to '{}'...".format(url), level=10
|
||||
))
|
||||
try:
|
||||
# make sure there are no DBMS errors in the HTML
|
||||
for dbms in DBMS_ERRORS:
|
||||
|
|
@ -65,7 +64,7 @@ def detect_protection(url, status, html, headers, **kwargs):
|
|||
logger.warning(set_color(
|
||||
"it appears that the WAF/IDS/IPS check threw a DBMS error and may be vulnerable "
|
||||
"to SQL injection attacks. it appears the backend DBMS is '{}', site will be "
|
||||
"saved for further processing...".format(dbms), level=30
|
||||
"saved for further processing".format(dbms), level=30
|
||||
))
|
||||
write_to_log_file(url, SQLI_SITES_FILEPATH, SQLI_FOUND_FILENAME)
|
||||
return None
|
||||
|
|
@ -76,7 +75,7 @@ def detect_protection(url, status, html, headers, **kwargs):
|
|||
item = item[:-3]
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"loading script '{}'...".format(item), level=10
|
||||
"loading script '{}'".format(item), level=10
|
||||
))
|
||||
detection_name = "lib.firewall.{}"
|
||||
detection_name = detection_name.format(item)
|
||||
|
|
@ -89,7 +88,7 @@ def detect_protection(url, status, html, headers, **kwargs):
|
|||
del retval[retval.index("Generic (Unknown)")]
|
||||
except (Exception, IndexError):
|
||||
logger.warning(set_color(
|
||||
"multiple firewalls identified ({}), displaying most likely...".format(
|
||||
"multiple firewalls identified ({}), displaying most likely".format(
|
||||
", ".join([item.split("(")[0] for item in retval])
|
||||
), level=30
|
||||
))
|
||||
|
|
@ -100,7 +99,7 @@ def detect_protection(url, status, html, headers, **kwargs):
|
|||
logger.warning(set_color(
|
||||
"discovered firewall is unknown to Zeus, saving fingerprint to file. "
|
||||
"if you know the details or the context of the firewall please create "
|
||||
"an issue ({}) with the fingerprint, or a pull request with the script...".format(
|
||||
"an issue ({}) with the fingerprint, or a pull request with the script".format(
|
||||
ISSUE_LINK
|
||||
), level=30
|
||||
))
|
||||
|
|
@ -113,14 +112,14 @@ def detect_protection(url, status, html, headers, **kwargs):
|
|||
return None
|
||||
|
||||
except Exception as e:
|
||||
if "Read timed out." or "Connection reset by peer" in str(e):
|
||||
if any(err in str(e) for err in ["Read timed out.", "Connection reset by peer"]):
|
||||
logger.warning(set_color(
|
||||
"detection request failed, assuming no protection and continuing...", level=30
|
||||
"detection request failed, assuming no protection and continuing", level=30
|
||||
))
|
||||
return None
|
||||
else:
|
||||
logger.exception(set_color(
|
||||
"Zeus ran into an unexpected error '{}'...".format(e), level=50
|
||||
"Zeus ran into an unexpected error '{}'".format(e), level=50
|
||||
))
|
||||
request_issue_creation()
|
||||
return None
|
||||
|
|
@ -137,7 +136,7 @@ def detect_plugins(html, headers, **kwargs):
|
|||
plugin = plugin[:-3]
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"loading script '{}'...".format(plugin), level=10
|
||||
"loading script '{}'".format(plugin), level=10
|
||||
))
|
||||
plugin_detection = "lib.plugins.{}"
|
||||
plugin_detection = plugin_detection.format(plugin)
|
||||
|
|
@ -151,12 +150,12 @@ def detect_plugins(html, headers, **kwargs):
|
|||
logger.exception(str(e))
|
||||
if "Read timed out." or "Connection reset by peer" in str(e):
|
||||
logger.warning(set_color(
|
||||
"plugin request failed, assuming no plugins and continuing...", level=30
|
||||
"plugin request failed, assuming no plugins and continuing", level=30
|
||||
))
|
||||
return None
|
||||
else:
|
||||
logger.exception(set_color(
|
||||
"plugin detection has failed with error {}...".format(str(e))
|
||||
"plugin detection has failed with error {}".format(str(e))
|
||||
))
|
||||
request_issue_creation()
|
||||
|
||||
|
|
@ -181,7 +180,7 @@ def load_headers(url, req, **kwargs):
|
|||
|
||||
if len(req.cookies) > 0:
|
||||
logger.info(set_color(
|
||||
"found a request cookie, saving to file...", level=25
|
||||
"found a request cookie, saving to file", level=25
|
||||
))
|
||||
try:
|
||||
cookie_start = req.cookies.keys()
|
||||
|
|
@ -247,7 +246,9 @@ def main_header_check(url, **kwargs):
|
|||
identify_waf = kwargs.get("identify_waf", True)
|
||||
identify_plugins = kwargs.get("identify_plugins", True)
|
||||
show_description = kwargs.get("show_description", False)
|
||||
attempts = kwargs.get("attempts", 3)
|
||||
|
||||
default_sleep_time = 5
|
||||
protection = {"hostname": url}
|
||||
definition = {
|
||||
"x-xss": ("protection against XSS attacks", "XSS"),
|
||||
|
|
@ -260,69 +261,74 @@ def main_header_check(url, **kwargs):
|
|||
"content-security": ("header protection against multiple attack types", "ALL")
|
||||
}
|
||||
|
||||
req, status, html, headers = get_page(url, proxy=proxy, agent=agent, xforward=xforward)
|
||||
|
||||
try:
|
||||
req, status, html, headers = get_page(url, proxy=proxy, agent=agent, xforward=xforward)
|
||||
|
||||
logger.info(set_color(
|
||||
"detecting target charset..."
|
||||
"detecting target charset"
|
||||
))
|
||||
charset = get_charset(url, headers)
|
||||
charset = get_charset(html, headers)
|
||||
if charset is not None:
|
||||
logger.info(set_color(
|
||||
"target charset appears to be '{}'...".format(charset), level=25
|
||||
"target charset appears to be '{}'".format(charset), level=25
|
||||
))
|
||||
else:
|
||||
logger.warning(set_color(
|
||||
"unable to detect target charset...", level=30
|
||||
"unable to detect target charset", level=30
|
||||
))
|
||||
if identify_waf:
|
||||
waf_url = "{} {}".format(url, PROTECTION_CHECK_PAYLOAD)
|
||||
waf_url = "{} {}".format(url.strip(), PROTECTION_CHECK_PAYLOAD)
|
||||
_, waf_status, waf_html, waf_headers = get_page(waf_url, xforward=xforward, proxy=proxy, agent=agent)
|
||||
logger.info(set_color(
|
||||
"checking if target URL is protected by some kind of WAF/IPS/IDS..."
|
||||
"checking if target URL is protected by some kind of WAF/IPS/IDS"
|
||||
))
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"attempting connection to '{}'".format(waf_url), level=10
|
||||
))
|
||||
|
||||
identified_waf = detect_protection(url, waf_status, waf_html, waf_headers, verbose=verbose)
|
||||
|
||||
if identified_waf is None:
|
||||
logger.info(set_color(
|
||||
"no WAF/IDS/IPS has been identified on target URL...", level=25
|
||||
"no WAF/IDS/IPS has been identified on target URL", level=25
|
||||
))
|
||||
else:
|
||||
logger.warning(set_color(
|
||||
"the target URL WAF/IDS/IPS has been identified as '{}'...".format(identified_waf), level=35
|
||||
"the target URL WAF/IDS/IPS has been identified as '{}'".format(identified_waf), level=35
|
||||
))
|
||||
|
||||
if identify_plugins:
|
||||
logger.info(set_color(
|
||||
"attempting to identify plugins..."
|
||||
"attempting to identify plugins"
|
||||
))
|
||||
identified_plugin = detect_plugins(html, headers, verbose=verbose)
|
||||
if identified_plugin is not None:
|
||||
for plugin in identified_plugin:
|
||||
if show_description:
|
||||
logger.info(set_color(
|
||||
"possible plugin identified as '{}' (description: '{}')...".format(
|
||||
"possible plugin identified as '{}' (description: '{}')".format(
|
||||
plugin[0], plugin[1]
|
||||
), level=25
|
||||
))
|
||||
else:
|
||||
logger.info(set_color(
|
||||
"possible plugin identified as '{}'...".format(
|
||||
"possible plugin identified as '{}'".format(
|
||||
plugin[0]
|
||||
), level=25
|
||||
))
|
||||
else:
|
||||
logger.warning(set_color(
|
||||
"no known plugins identified on target...", level=30
|
||||
"no known plugins identified on target", level=30
|
||||
))
|
||||
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"loading XML data...", level=10
|
||||
"loading XML data", level=10
|
||||
))
|
||||
comparable_headers = load_xml_data(HEADER_XML_DATA)
|
||||
logger.info(set_color(
|
||||
"attempting to get request headers for '{}'...".format(url.strip())
|
||||
"attempting to get request headers for '{}'".format(url.strip())
|
||||
))
|
||||
try:
|
||||
found_headers = load_headers(url, req)
|
||||
|
|
@ -331,31 +337,56 @@ def main_header_check(url, **kwargs):
|
|||
found_headers = None
|
||||
else:
|
||||
logger.exception(set_color(
|
||||
"Zeus has hit an unexpected error and cannot continue '{}'...".format(e), level=50
|
||||
"Zeus has hit an unexpected error and cannot continue '{}'".format(e), level=50
|
||||
))
|
||||
request_issue_creation()
|
||||
|
||||
if found_headers is not None:
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"fetched {}...".format(found_headers), level=10
|
||||
"fetched {}".format(found_headers), level=10
|
||||
))
|
||||
headers_established = [str(h) for h in compare_headers(found_headers, comparable_headers)]
|
||||
for key in definition.iterkeys():
|
||||
if any(key in h.lower() for h in headers_established):
|
||||
logger.warning(set_color(
|
||||
"provided target has {}...".format(definition[key][0]), level=30
|
||||
"provided target has {}".format(definition[key][0]), level=30
|
||||
))
|
||||
for key in found_headers.iterkeys():
|
||||
protection[key] = found_headers[key]
|
||||
logger.info(set_color(
|
||||
"writing found headers to log file...", level=25
|
||||
"writing found headers to log file", level=25
|
||||
))
|
||||
return write_to_log_file(protection, HEADER_RESULT_PATH, HEADERS_FILENAME.format(replace_http(url)))
|
||||
else:
|
||||
logger.error(set_color(
|
||||
"unable to retrieve headers for site '{}'...".format(url.strip()), level=40
|
||||
"unable to retrieve headers for site '{}'".format(url.strip()), level=40
|
||||
))
|
||||
except ConnectionError:
|
||||
attempts = attempts - 1
|
||||
if attempts == 0:
|
||||
return False
|
||||
logger.warning(set_color(
|
||||
"target actively refused the connection, sleeping for {}s and retrying the request".format(
|
||||
default_sleep_time
|
||||
), level=30
|
||||
))
|
||||
time.sleep(default_sleep_time)
|
||||
main_header_check(
|
||||
url, proxy=proxy, agent=agent, xforward=xforward, show_description=show_description,
|
||||
identify_plugins=identify_plugins, identify_waf=identify_waf, verbose=verbose,
|
||||
attempts=attempts
|
||||
)
|
||||
except ReadTimeout:
|
||||
logger.error(set_color(
|
||||
"meta-data retrieval failed due to target URL timing out, skipping", level=40
|
||||
))
|
||||
except KeyboardInterrupt:
|
||||
if not pause():
|
||||
shutdown()
|
||||
shutdown()
|
||||
except Exception as e:
|
||||
logger.exception(set_color(
|
||||
"meta-data retrieval failed with unexpected error '{}'".format(
|
||||
str(e)
|
||||
), level=50
|
||||
))
|
||||
21
lib/plugins/clipbucket.py
Normal file
21
lib/plugins/clipbucket.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import re
|
||||
|
||||
|
||||
__product__ = "ClipBucket"
|
||||
__description__ = (
|
||||
"ClipBucket is an Open Source and freely downloadable PHP "
|
||||
"script that will let you start your own Video Sharing website"
|
||||
)
|
||||
|
||||
|
||||
def search(html, **kwargs):
|
||||
html = str(html)
|
||||
plugin_detection_schema = (
|
||||
re.compile(r"<.\S+.clipbucket", re.I),
|
||||
re.compile(r"content.[\'\"]clipbucket", re.I),
|
||||
re.compile(r"http(s)?.//(www.)?clip.bucket.com", re.I),
|
||||
re.compile(r"http(s)?.//(www.)?clipbucket.com", re.I),
|
||||
)
|
||||
for plugin in plugin_detection_schema:
|
||||
if plugin.search(html) is not None:
|
||||
return True
|
||||
19
lib/plugins/moodle.py
Normal file
19
lib/plugins/moodle.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import re
|
||||
|
||||
|
||||
__product__ = "Moodle"
|
||||
__description__ = (
|
||||
"Moodle is an opensource educational software written in PHP"
|
||||
)
|
||||
|
||||
|
||||
def search(html, **kwargs):
|
||||
html = str(html)
|
||||
plugin_detection_schema = (
|
||||
re.compile(r".moodle.", re.I),
|
||||
re.compile(r".moodlesession.", re.I),
|
||||
re.compile(r".php.moodlesession.(\w+)?(\d+)?", re.I)
|
||||
)
|
||||
for plugin in plugin_detection_schema:
|
||||
if plugin.search(html) is not None:
|
||||
return True
|
||||
18
lib/plugins/mssqlreportmanager.py
Normal file
18
lib/plugins/mssqlreportmanager.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import re
|
||||
|
||||
|
||||
__product__ = "Microsoft SQL Report Manager"
|
||||
__description__ = (
|
||||
"Microsoft SQL Server Report Manager - web-based report access and management tool"
|
||||
)
|
||||
|
||||
|
||||
def search(html, **kwargs):
|
||||
html = str(html)
|
||||
plugin_detection_schema = (
|
||||
re.compile(r"content.[\'\"]?microsoft.sql.server.report", re.I),
|
||||
re.compile(r"microsoft.sql.server.report.manager", re.I)
|
||||
)
|
||||
for plugin in plugin_detection_schema:
|
||||
if plugin.search(html) is not None:
|
||||
return True
|
||||
|
|
@ -11,6 +11,6 @@ def tamper(payload, **kwargs):
|
|||
if warning:
|
||||
logger.warning(set_color(
|
||||
"base64 tamper scripts may increase the possibility of not finding vulnerabilities "
|
||||
"in otherwise vulnerable sites...", level=30
|
||||
"in otherwise vulnerable sites", level=30
|
||||
))
|
||||
return base64.b64encode(payload)
|
||||
|
|
@ -12,7 +12,7 @@ def tamper(payload, **kwargs):
|
|||
if warning:
|
||||
logger.warning(set_color(
|
||||
"enclosing brackets is meant to be used as an obfuscation "
|
||||
"against an already valid vulnerable site...", level=30
|
||||
"against an already valid vulnerable site", level=30
|
||||
))
|
||||
|
||||
to_enclose = string.digits
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ def tamper(payload, **kwargs):
|
|||
warning = kwargs.get("warning", True)
|
||||
if warning:
|
||||
logger.warning(set_color(
|
||||
"hex tamper scripts may increase the risk of false positives...", level=30
|
||||
"hex tamper scripts may increase the risk of false positives", level=30
|
||||
))
|
||||
retval = hex(hash(payload))
|
||||
if "-" in str(retval):
|
||||
|
|
|
|||
29
lib/tamper_scripts/obfuscateentity_encode.py
Normal file
29
lib/tamper_scripts/obfuscateentity_encode.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
from lib.core.settings import (
|
||||
logger,
|
||||
set_color
|
||||
)
|
||||
|
||||
|
||||
def tamper(payload, **kwargs):
|
||||
warning = kwargs.get("warning", True)
|
||||
|
||||
if warning:
|
||||
logger.warning(set_color(
|
||||
"obfuscating payloads by their entity encoding equivalent may increase the "
|
||||
"risk of false positives", level=30
|
||||
))
|
||||
|
||||
skip = ";"
|
||||
encoding_schema = {
|
||||
" ": " ", "<": "<", ">": ">",
|
||||
"&": "&", '"': """, "'": "'",
|
||||
}
|
||||
retval = ""
|
||||
for char in str(payload):
|
||||
if char in encoding_schema.iterkeys():
|
||||
retval += encoding_schema[char]
|
||||
elif char not in encoding_schema.iterkeys() and char != skip:
|
||||
retval += char
|
||||
else:
|
||||
retval += char
|
||||
return retval
|
||||
|
|
@ -10,7 +10,7 @@ def tamper(payload, **kwargs):
|
|||
if warning:
|
||||
logger.warning(set_color(
|
||||
"obfuscating the payloads by ordinal equivalents may increase the risk "
|
||||
"of false positives...", level=30
|
||||
"of false positives", level=30
|
||||
))
|
||||
|
||||
retval = ""
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ def tamper(payload, **kwargs):
|
|||
if warning:
|
||||
logger.warning(set_color(
|
||||
"NULL encoding tamper scripts may increase the possibility of not finding vulnerabilities "
|
||||
"in otherwise vulnerable sites...", level=30
|
||||
"in otherwise vulnerable sites", level=30
|
||||
))
|
||||
|
||||
retval = ""
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ def request_issue_creation():
|
|||
if not lib.core.settings.get_md5sum():
|
||||
lib.core.settings.logger.fatal(lib.core.settings.set_color(
|
||||
"it appears that your checksums did not match, therefore it is assumed "
|
||||
"that you have edited some of the code, issue request denied...", level=50
|
||||
"that you have edited some of the code, issue request denied", level=50
|
||||
))
|
||||
lib.core.common.shutdown()
|
||||
|
||||
|
|
@ -49,18 +49,18 @@ def request_issue_creation():
|
|||
)
|
||||
if question.lower().startswith("n"):
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"Zeus has experienced an internal error and cannot continue, shutting down...", level=40
|
||||
"Zeus has experienced an internal error and cannot continue, shutting down", level=40
|
||||
))
|
||||
lib.core.common.shutdown()
|
||||
|
||||
lib.core.settings.fix_log_file()
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"Zeus got an unexpected error and will automatically create an issue for this error, please wait..."
|
||||
"Zeus got an unexpected error and will automatically create an issue for this error, please wait"
|
||||
))
|
||||
|
||||
def __extract_stacktrace(file_data):
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"extracting traceback from log file..."
|
||||
"extracting traceback from log file"
|
||||
))
|
||||
retval, buff_mode, _buffer = [], False, ""
|
||||
with open(file_data, "r+") as log:
|
||||
|
|
@ -73,19 +73,19 @@ def request_issue_creation():
|
|||
_buffer = ""
|
||||
if buff_mode:
|
||||
if len(line) > 400:
|
||||
line = line[:400] + "...\n"
|
||||
line = line[:400] + "\n"
|
||||
_buffer += line
|
||||
return "".join(retval)
|
||||
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"getting authorization..."
|
||||
"getting authorization"
|
||||
))
|
||||
|
||||
token = lib.core.settings.get_token(lib.core.settings.GITHUB_AUTH_PATH)
|
||||
|
||||
current_log_file = lib.core.settings.get_latest_log_file(lib.core.settings.CURRENT_LOG_FILE_PATH)
|
||||
stacktrace = __extract_stacktrace(current_log_file)
|
||||
identifier = lib.core.settings.create_identifier()
|
||||
identifier = lib.core.settings.create_identifier(stacktrace)
|
||||
issue_title = "Unhandled exception ({})".format(identifier)
|
||||
ff_version = lib.core.settings.get_browser_version()
|
||||
log_file_information = lib.core.settings.tails(current_log_file)
|
||||
|
|
@ -95,7 +95,7 @@ def request_issue_creation():
|
|||
"body": "Zeus version:\n`{}`\n\n"
|
||||
"Firefox version:\n`{}`\n\n"
|
||||
"Geckodriver version:\n`{}`\n\n"
|
||||
"Error info:\n```{}````\n\n"
|
||||
"Error info:\n```{}```\n\n"
|
||||
"Running details:\n`{}`\n\n"
|
||||
"Commands used:\n`{}`\n\n"
|
||||
"Log file info:\n```{}```".format(
|
||||
|
|
@ -121,12 +121,12 @@ def request_issue_creation():
|
|||
urllib2.urlopen(req, timeout=10).read()
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"issue has been created successfully with the following name '{}', your unique identifier "
|
||||
"for this issue is '{}' and the URL to your issue is '{}'...".format(
|
||||
"for this issue is '{}' and the URL to your issue is '{}'".format(
|
||||
issue_title, identifier, find_url(identifier)
|
||||
)
|
||||
))
|
||||
except Exception as e:
|
||||
lib.core.settings.logger.exception(lib.core.settings.set_color(
|
||||
"failed to auto create the issue, got exception '{}', "
|
||||
"you may manually create an issue...".format(e), level=50
|
||||
"you may manually create an issue".format(e), level=50
|
||||
))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
import os
|
||||
import sys
|
||||
reload(sys)
|
||||
sys.setdefaultencoding("utf-8") # this will take care of most of the Unicode errors.
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
|
|
@ -20,7 +17,7 @@ class Blackwidow(object):
|
|||
def __init__(self, url, user_agent=None, proxy=None, forward=None):
|
||||
self.url = url
|
||||
self.forward = forward or None
|
||||
self.proxy = lib.core.settings.proxy_string_to_dict(proxy) or None
|
||||
self.proxy = proxy
|
||||
self.user_agent = user_agent or lib.core.settings.DEFAULT_USER_AGENT
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -39,7 +36,8 @@ class Blackwidow(object):
|
|||
make sure the connection is good before you continue
|
||||
"""
|
||||
try:
|
||||
# verify=False will take care of SSLErrors
|
||||
# we'll skip SSL verification to avoid any SSLErrors that might
|
||||
# arise, we won't really need it with this anyways
|
||||
attempt, status, _, _ = lib.core.common.get_page(
|
||||
self.url, agent=self.user_agent, xforward=self.forward, skip_verf=True,
|
||||
proxy=self.proxy
|
||||
|
|
@ -55,14 +53,14 @@ class Blackwidow(object):
|
|||
else:
|
||||
info_msg += ""
|
||||
lib.core.settings.logger.fatal(lib.core.settings.set_color(
|
||||
"provided website '{}' is refusing connection{}...".format(
|
||||
"provided website '{}' is refusing connection{}".format(
|
||||
self.url, info_msg
|
||||
), level=50
|
||||
))
|
||||
lib.core.common.shutdown()
|
||||
else:
|
||||
lib.core.settings.logger.exception(lib.core.settings.set_color(
|
||||
"failed to connect to '{}' received error '{}'...".format(
|
||||
"failed to connect to '{}' received error '{}'".format(
|
||||
self.url, e
|
||||
), level=50
|
||||
))
|
||||
|
|
@ -106,27 +104,27 @@ def blackwidow_main(url, **kwargs):
|
|||
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"settings user-agent to '{}'...".format(agent), level=10
|
||||
"settings user-agent to '{}'".format(agent), level=10
|
||||
))
|
||||
if proxy is not None:
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"running behind proxy '{}'...".format(proxy), level=10
|
||||
"running behind proxy '{}'".format(proxy), level=10
|
||||
))
|
||||
lib.core.settings.create_dir("{}/{}".format(os.getcwd(), "log/blackwidow-log"))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"starting blackwidow on '{}'...".format(url)
|
||||
"starting blackwidow on '{}'".format(url)
|
||||
))
|
||||
crawler = Blackwidow(url, user_agent=agent, proxy=proxy, forward=forward)
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"testing connection to the URL...", level=10
|
||||
"testing connection to the URL", level=10
|
||||
))
|
||||
test_code = crawler.test_connection()
|
||||
if not test_code[0] == "ok":
|
||||
error_msg = (
|
||||
"connection test failed with status code: {}, reason: '{}'. "
|
||||
"test connection needs to pass, try a different link..."
|
||||
"test connection needs to pass, try a different link"
|
||||
)
|
||||
for error_code in lib.core.common.STATUS_CODES.keys():
|
||||
if error_code == test_code[1]:
|
||||
|
|
@ -144,15 +142,15 @@ def blackwidow_main(url, **kwargs):
|
|||
lib.core.common.shutdown()
|
||||
else:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"connection test succeeded, continuing...", level=25
|
||||
"connection test succeeded, continuing", level=25
|
||||
))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"crawling given URL '{}' for links...".format(url)
|
||||
"crawling given URL '{}' for links".format(url)
|
||||
))
|
||||
found = crawler.scrape_page_for_links(url)
|
||||
if len(found) > 0:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"found a total of {} links from given URL '{}'...".format(
|
||||
"found a total of {} links from given URL '{}'".format(
|
||||
len(found), url
|
||||
), level=25
|
||||
))
|
||||
|
|
@ -160,5 +158,5 @@ def blackwidow_main(url, **kwargs):
|
|||
filename=lib.core.settings.BLACKWIDOW_FILENAME)
|
||||
else:
|
||||
lib.core.settings.logger.fatal(lib.core.settings.set_color(
|
||||
"did not find any usable links from '{}'...".format(url), level=50
|
||||
"did not find any usable links from '{}'".format(url), level=50
|
||||
))
|
||||
|
|
@ -128,7 +128,7 @@ class SetBrowser(object):
|
|||
try:
|
||||
if not self.tor:
|
||||
logger.info(set_color(
|
||||
"setting the browser..."
|
||||
"setting the browser"
|
||||
))
|
||||
profile.set_preference("general.useragent.override", self.agent)
|
||||
browser = webdriver.Firefox(profile, proxy=self.__set_proxy())
|
||||
|
|
@ -137,7 +137,7 @@ class SetBrowser(object):
|
|||
browser = webdriver.Firefox(profile, proxy=self.__set_proxy())
|
||||
else:
|
||||
logger.info(set_color(
|
||||
"setting the Tor browser emulation..."
|
||||
"setting the Tor browser emulation"
|
||||
))
|
||||
profile = self.__tor_browser_emulation(profile)
|
||||
browser = webdriver.Firefox(profile)
|
||||
|
|
|
|||
|
|
@ -109,18 +109,18 @@ def get_pgp_keys(url_list, query, attribute="pre", **kwargs):
|
|||
identity_matcher = re.compile(r"\bbegin.pgp.public.key.block", re.I)
|
||||
amount_left = len(url_list)
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"checking a maximum of {} PGP keys...".format(amount_to_search)
|
||||
"checking a maximum of {} PGP keys".format(amount_to_search)
|
||||
))
|
||||
for i, url in enumerate(url_list, start=1):
|
||||
if i >= amount_to_search:
|
||||
break
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"checking '{}'...".format(url), level=10
|
||||
"checking '{}'".format(url), level=10
|
||||
))
|
||||
if i % 25 == 0:
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"currently checking PGP key #{}, {} left to check ({} total found)...".format(
|
||||
"currently checking PGP key #{}, {} left to check ({} total found)".format(
|
||||
i, amount_to_search - i, amount_left
|
||||
)
|
||||
))
|
||||
|
|
@ -140,7 +140,7 @@ def get_pgp_keys(url_list, query, attribute="pre", **kwargs):
|
|||
extracted_keys.add(context)
|
||||
except ReadTimeout:
|
||||
lib.core.settings.logger.error(lib.core.settings.set_color(
|
||||
"PGP key failed connection, assuming no good and skipping...", level=40
|
||||
"PGP key failed connection, assuming no good and skipping", level=40
|
||||
))
|
||||
for i, k in enumerate(extracted_keys):
|
||||
pgp_key = str(k).split("<{}>".format(attribute)) # split the string by the tag
|
||||
|
|
@ -164,7 +164,7 @@ def pgp_main(query, verbose=False):
|
|||
except Exception:
|
||||
query = query
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"searching public PGP files with given query '{}'...".format(query)
|
||||
"searching public PGP files with given query '{}'".format(query)
|
||||
))
|
||||
try:
|
||||
html = obtain_html(
|
||||
|
|
@ -172,25 +172,25 @@ def pgp_main(query, verbose=False):
|
|||
)
|
||||
except (Exception, ReadTimeout):
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"connection failed, assuming no PGP keys...", level=30
|
||||
"connection failed, assuming no PGP keys", level=30
|
||||
))
|
||||
html = None
|
||||
if html is not None:
|
||||
urls = gather_urls(html)
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"found a total of {} URLs...".format(len(urls))
|
||||
"found a total of {} URLs".format(len(urls))
|
||||
))
|
||||
if verbose:
|
||||
lib.core.settings.logger.debug(lib.core.settings.set_color(
|
||||
"found a '{}'...".format(urls), level=10
|
||||
"found a '{}'".format(urls), level=10
|
||||
))
|
||||
lib.core.settings.logger.info(lib.core.settings.set_color(
|
||||
"gathering PGP key(s) and writing to a file...", level=25
|
||||
"gathering PGP key(s) and writing to a file", level=25
|
||||
))
|
||||
return get_pgp_keys(urls, query, verbose=verbose)
|
||||
else:
|
||||
lib.core.settings.logger.warning(lib.core.settings.set_color(
|
||||
"did not find anything using query '{}'...".format(query), level=30
|
||||
"did not find anything using query '{}'".format(query), level=30
|
||||
))
|
||||
except KeyboardInterrupt:
|
||||
if not lib.core.common.pause():
|
||||
|
|
|
|||
|
|
@ -75,20 +75,20 @@ def get_urls(query, url, verbose=False, **kwargs):
|
|||
batch = kwargs.get("batch", False)
|
||||
xforward = kwargs.get("xforward", False)
|
||||
logger.info(set_color(
|
||||
"setting up virtual display to hide the browser..."
|
||||
"setting up virtual display to hide the browser"
|
||||
))
|
||||
ff_display = Display(visible=0, size=(800, 600))
|
||||
ff_display.start()
|
||||
browser = var.search.SetBrowser(agent=user_agent, proxy=proxy, tor=tor, xforward=xforward).set_browser()
|
||||
logger.info(set_color("browser will open shortly...", level=25))
|
||||
logger.info(set_color("browser will open shortly", level=25))
|
||||
browser.get(url)
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"searching search engine for the 'q' element (search button)...", level=10
|
||||
"searching search engine for the 'q' element (search button)", level=10
|
||||
))
|
||||
search = browser.find_element_by_name('q')
|
||||
logger.info(set_color(
|
||||
"searching search engine using query '{}'...".format(query)
|
||||
"searching search engine using query '{}'".format(query)
|
||||
))
|
||||
try:
|
||||
# enter the text you want to search and hit enter
|
||||
|
|
@ -98,31 +98,35 @@ def get_urls(query, url, verbose=False, **kwargs):
|
|||
time.sleep(3)
|
||||
else:
|
||||
logger.warning(set_color(
|
||||
"sleep time has been increased to 10 seconds due to tor being used...", level=30
|
||||
"sleep time has been increased to 10 seconds due to tor being used", level=30
|
||||
))
|
||||
time.sleep(10)
|
||||
except ElementNotInteractableException:
|
||||
# get rid of the popup box and hit enter after entering the text to search
|
||||
browser.execute_script("document.querySelectorAll('label.boxed')[1].click()")
|
||||
search.send_keys(query)
|
||||
search.send_keys(Keys.RETURN)
|
||||
time.sleep(3)
|
||||
try:
|
||||
for _ in range(5):
|
||||
browser.execute_script("document.querySelectorAll('label.boxed')[{}].click()".format(_))
|
||||
search.send_keys(query)
|
||||
search.send_keys(Keys.RETURN)
|
||||
time.sleep(3)
|
||||
except Exception:
|
||||
pass
|
||||
except UnicodeDecodeError:
|
||||
logger.error(set_color(
|
||||
"your query '{}' appears to have unicode characters in it, selenium is not "
|
||||
"properly formatted to handle unicode characters, this dork will be skipped...".format(
|
||||
"properly formatted to handle unicode characters, this dork will be skipped".format(
|
||||
query
|
||||
), level=40
|
||||
))
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"obtaining URL from selenium..."
|
||||
"obtaining URL from selenium"
|
||||
))
|
||||
try:
|
||||
retval = browser.current_url
|
||||
except UnexpectedAlertPresentException:
|
||||
logger.warning(set_color(
|
||||
"alert present, closing...", level=30
|
||||
"alert present, closing", level=30
|
||||
))
|
||||
# discover the alert and close it before continuing
|
||||
alert = browser.switch_to.alert
|
||||
|
|
@ -131,7 +135,7 @@ def get_urls(query, url, verbose=False, **kwargs):
|
|||
# if you have been IP banned, we'll extract the URL from it
|
||||
if IP_BAN_REGEX.search(retval) is not None:
|
||||
logger.warning(set_color(
|
||||
"it appears that Google is attempting to block your IP address, attempting bypass...", level=30
|
||||
"it appears that Google is attempting to block your IP address, attempting bypass", level=30
|
||||
))
|
||||
try:
|
||||
retval = URLParser(retval).extract_ip_ban_url()
|
||||
|
|
@ -155,7 +159,7 @@ def get_urls(query, url, verbose=False, **kwargs):
|
|||
write_to_log_file(retval, EXTRACTED_URL_LOG, EXTRACTED_URL_FILENAME)
|
||||
logger.info(set_color(
|
||||
"it is advised to extract the URL's from the produced URL written to the above "
|
||||
"(IE open the log, copy the url into firefox)...".format(retval)
|
||||
"(IE open the log, copy the url into firefox)".format(retval)
|
||||
))
|
||||
shutdown()
|
||||
except Exception as e:
|
||||
|
|
@ -165,7 +169,7 @@ def get_urls(query, url, verbose=False, **kwargs):
|
|||
ff_display.stop()
|
||||
logger.exception(set_color(
|
||||
"zeus was unable to extract the correct URL from the ban URL '{}', "
|
||||
"got exception '{}'...".format(
|
||||
"got exception '{}'".format(
|
||||
unquote(retval), e
|
||||
), level=50
|
||||
))
|
||||
|
|
@ -173,7 +177,7 @@ def get_urls(query, url, verbose=False, **kwargs):
|
|||
shutdown()
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"found current URL from selenium browser...", level=10
|
||||
"found current URL from selenium browser", level=10
|
||||
))
|
||||
logger.info(set_color(
|
||||
"closing the browser and continuing process.."
|
||||
|
|
@ -201,31 +205,31 @@ def parse_search_results(query, url_to_search, verbose=False, **kwargs):
|
|||
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"parsing blacklist...", level=10
|
||||
"parsing blacklist", level=10
|
||||
))
|
||||
parse_blacklist(query, BLACKLIST_FILE_PATH, batch=batch)
|
||||
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"checking for user-agent and proxy configuration...", level=10
|
||||
"checking for user-agent and proxy configuration", level=10
|
||||
))
|
||||
|
||||
if not parse_webcache and "google" in url_to_search:
|
||||
logger.warning(set_color(
|
||||
"will not parse webcache URL's (to parse webcache pass -W)...", level=30
|
||||
"will not parse webcache URL's (to parse webcache pass -W)", level=30
|
||||
))
|
||||
if not pull_all:
|
||||
logger.warning(set_color(
|
||||
"only pulling URLs with GET(query) parameters (to pull all URL's pass -E)...", level=30
|
||||
"only pulling URLs with GET(query) parameters (to pull all URL's pass -E)", level=30
|
||||
))
|
||||
|
||||
user_agent_info = "adjusting user-agent header to {}..."
|
||||
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 {}..."
|
||||
proxy_string_info = "setting proxy to {}"
|
||||
if proxy_string is not None:
|
||||
proxy_string = proxy_string_to_dict(proxy_string)
|
||||
proxy_string_info = proxy_string_info.format(
|
||||
|
|
@ -236,13 +240,13 @@ def parse_search_results(query, url_to_search, verbose=False, **kwargs):
|
|||
"tor proxy settings"
|
||||
)
|
||||
else:
|
||||
proxy_string_info = "no proxy configuration detected..."
|
||||
proxy_string_info = "no proxy configuration detected"
|
||||
|
||||
if forward_for:
|
||||
ip_to_use = (create_random_ip(), create_random_ip(), create_random_ip())
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"random IP addresses generated for headers '{}'...".format(ip_to_use), level=10
|
||||
"random IP addresses generated for headers '{}'".format(ip_to_use), level=10
|
||||
))
|
||||
|
||||
headers = {
|
||||
|
|
@ -256,7 +260,7 @@ def parse_search_results(query, url_to_search, verbose=False, **kwargs):
|
|||
HTTP_HEADER.USER_AGENT: user_agent
|
||||
}
|
||||
logger.info(set_color(
|
||||
"attempting to gather query URL..."
|
||||
"attempting to gather query URL"
|
||||
))
|
||||
try:
|
||||
query_url = get_urls(
|
||||
|
|
@ -268,17 +272,17 @@ def parse_search_results(query, url_to_search, verbose=False, **kwargs):
|
|||
logger.fatal(set_color(
|
||||
"firefox was not found in the default location on your system, "
|
||||
"check your installation and make sure it is in /usr/lib, if you "
|
||||
"find it there, restart your system and try again...", level=50
|
||||
"find it there, restart your system and try again", level=50
|
||||
))
|
||||
elif "connection refused" in str(e).lower():
|
||||
logger.fatal(set_color(
|
||||
"there are to many sessions of firefox opened and selenium cannot "
|
||||
"create a new one...", level=50
|
||||
"create a new one", level=50
|
||||
))
|
||||
run_fix(
|
||||
"would you like to attempt to auto clean the open sessions",
|
||||
"sudo sh {}".format(CLEANUP_TOOL_PATH),
|
||||
"kill off the open sessions of firefox and re-run Zeus...",
|
||||
"kill off the open sessions of firefox and re-run Zeus",
|
||||
exit_process=True
|
||||
)
|
||||
elif "Program install error!" in str(e):
|
||||
|
|
@ -289,50 +293,50 @@ def parse_search_results(query, url_to_search, verbose=False, **kwargs):
|
|||
run_fix(
|
||||
"would you like to attempt to fix this issue automatically",
|
||||
"sudo sh {}".format(FIX_PROGRAM_INSTALL_PATH),
|
||||
"you can manually try and re-install Xvfb to fix the problem...",
|
||||
"you can manually try and re-install Xvfb to fix the problem",
|
||||
exit_process=True
|
||||
)
|
||||
elif "Message: Reached error page:" in str(e):
|
||||
logger.fatal(set_color(
|
||||
"geckodriver has hit an error that usually means it needs to be reinstalled...", level=50
|
||||
"geckodriver has hit an error that usually means it needs to be reinstalled", level=50
|
||||
))
|
||||
question = prompt(
|
||||
"would you like to attempt a reinstallation of the geckodriver", opts="yN"
|
||||
)
|
||||
if question.lower().startswith("y"):
|
||||
logger.warning(set_color(
|
||||
"rewriting all executed information, path information, and removing geckodriver...", level=30
|
||||
"rewriting all executed information, path information, and removing geckodriver", level=30
|
||||
))
|
||||
rewrite_all_paths()
|
||||
logger.info(set_color(
|
||||
"all paths rewritten, you will be forced to re-install everything next run of Zeus..."
|
||||
"all paths rewritten, you will be forced to re-install everything next run of Zeus"
|
||||
))
|
||||
else:
|
||||
logger.fatal(set_color(
|
||||
"you will need to remove the geckodriver from /usr/bin and reinstall it...", level=50
|
||||
"you will need to remove the geckodriver from /usr/bin and reinstall it", level=50
|
||||
))
|
||||
shutdown()
|
||||
elif "Unable to find a matching set of capabilities" in str(e):
|
||||
logger.fatal(set_color(
|
||||
"it appears that firefox, selenium, and geckodriver are not playing nice with one another...", level=50
|
||||
"it appears that firefox, selenium, and geckodriver are not playing nice with one another", level=50
|
||||
))
|
||||
run_fix(
|
||||
"would you like to attempt to resolve this issue automatically",
|
||||
"sudo sh {}".format(REINSTALL_TOOL),
|
||||
("you will need to reinstall firefox to a later version, update selenium, and reinstall the "
|
||||
"geckodriver to continue using Zeus..."),
|
||||
"geckodriver to continue using Zeus"),
|
||||
exit_process=True
|
||||
)
|
||||
else:
|
||||
logger.exception(set_color(
|
||||
"{} failed to gather the URL from search engine, caught exception '{}' "
|
||||
"exception has been logged to current log file...".format(
|
||||
"exception has been logged to current log file".format(
|
||||
os.path.basename(__file__), str(e).strip()), level=50)
|
||||
)
|
||||
request_issue_creation()
|
||||
shutdown()
|
||||
logger.info(set_color(
|
||||
"URL successfully gathered, searching for GET parameters..."
|
||||
"URL successfully gathered, searching for GET parameters"
|
||||
))
|
||||
|
||||
logger.info(set_color(proxy_string_info))
|
||||
|
|
@ -341,7 +345,7 @@ def parse_search_results(query, url_to_search, verbose=False, **kwargs):
|
|||
req = requests.get(query_url, proxies=proxy_string, params=headers)
|
||||
except ConnectionError:
|
||||
logger.warning(set_color(
|
||||
"target machine refused connection, delaying and trying again...", level=30
|
||||
"target machine refused connection, delaying and trying again", level=30
|
||||
))
|
||||
time.sleep(3)
|
||||
req = requests.get(query_url, proxies=proxy_string, params=headers)
|
||||
|
|
@ -365,15 +369,15 @@ def parse_search_results(query, url_to_search, verbose=False, **kwargs):
|
|||
if verbose:
|
||||
try:
|
||||
logger.debug(set_color(
|
||||
"found '{}'...".format(url.split(splitter)[0]), level=10
|
||||
"found '{}'".format(url.split(splitter)[0]), level=10
|
||||
))
|
||||
except TypeError:
|
||||
logger.debug(set_color(
|
||||
"found '{}'...".format(str(url).split(splitter)[0]), level=10
|
||||
"found '{}'".format(str(url).split(splitter)[0]), level=10
|
||||
))
|
||||
except AttributeError:
|
||||
logger.debug(set_color(
|
||||
"found '{}...".format(str(url)), level=10
|
||||
"found '{}".format(str(url)), level=10
|
||||
))
|
||||
if url is not None:
|
||||
retval.add(url.split(splitter)[0])
|
||||
|
|
@ -384,12 +388,12 @@ def parse_search_results(query, url_to_search, verbose=False, **kwargs):
|
|||
if parse_webcache:
|
||||
if "webcache" in url:
|
||||
logger.info(set_color(
|
||||
"found a webcache URL, extracting..."
|
||||
"found a webcache URL, extracting"
|
||||
))
|
||||
url = URLParser(url).extract_webcache_url()
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"found '{}'...".format(url), level=15
|
||||
"found '{}'".format(url), level=15
|
||||
))
|
||||
true_retval.add(url)
|
||||
else:
|
||||
|
|
@ -403,18 +407,18 @@ def parse_search_results(query, url_to_search, verbose=False, **kwargs):
|
|||
amount_of_urls = len(open(file_path).readlines())
|
||||
success_rate = calculate_success(amount_of_urls)
|
||||
logger.info(set_color(
|
||||
"provided query has a {} success rate...".format(success_rate)
|
||||
"provided query has a {} success rate".format(success_rate)
|
||||
))
|
||||
else:
|
||||
logger.fatal(set_color(
|
||||
"did not find any URLs with given query '{}' writing query to blacklist...".format(query), level=50
|
||||
logger.warning(set_color(
|
||||
"did not find any URLs with given query '{}' writing query to blacklist".format(query), level=50
|
||||
))
|
||||
write_to_log_file(query, BLACKLIST_FILE_PATH, BLACKLIST_FILENAME, blacklist=True)
|
||||
shutdown()
|
||||
|
||||
logger.info(set_color(
|
||||
"found a total of {} URLs with given query '{}'...".format(len(true_retval), query)
|
||||
"found a total of {} URLs with given query '{}'".format(len(true_retval), query)
|
||||
))
|
||||
return list(true_retval) if len(true_retval) != 0 else None
|
||||
|
||||
|
||||
|
||||
def search_multiple_pages(query, link_amount, verbose=False, **kwargs):
|
||||
|
|
@ -431,7 +435,7 @@ def search_multiple_pages(query, link_amount, verbose=False, **kwargs):
|
|||
search_engine = AUTHORIZED_SEARCH_ENGINES["search-results"]
|
||||
|
||||
logger.warning(set_color(
|
||||
"searching multiple pages will not be done on Google...".format(search_engine), level=30
|
||||
"searching multiple pages will not be done on Google".format(search_engine), level=30
|
||||
))
|
||||
|
||||
if not parse_blacklist(query, BLACKLIST_FILE_PATH, batch=batch):
|
||||
|
|
@ -455,11 +459,11 @@ def search_multiple_pages(query, link_amount, verbose=False, **kwargs):
|
|||
while len(retval) <= link_amount:
|
||||
if verbose:
|
||||
logger.debug(set_color(
|
||||
"searching page number {}...".format(page_number), level=10
|
||||
"searching page number {}".format(page_number), level=10
|
||||
))
|
||||
if page_number % 10 == 0:
|
||||
logger.info(set_color(
|
||||
"currently on page {} of search results...".format(
|
||||
"currently on page {} of search results".format(
|
||||
page_number
|
||||
)
|
||||
))
|
||||
|
|
@ -481,44 +485,44 @@ def search_multiple_pages(query, link_amount, verbose=False, **kwargs):
|
|||
page_number += 1
|
||||
else:
|
||||
logger.warning(set_color(
|
||||
"hit max page number {}...".format(MAX_PAGE_NUMBER), level=30
|
||||
"hit max page number {}".format(MAX_PAGE_NUMBER), level=30
|
||||
))
|
||||
break
|
||||
else:
|
||||
logger.warning(set_color(
|
||||
"no more results found for given query '{}'...".format(query), level=30
|
||||
"no more results found for given query '{}'".format(query), level=30
|
||||
))
|
||||
break
|
||||
except KeyboardInterrupt:
|
||||
logger.error(set_color(
|
||||
"user aborted, dumping already found URL(s)...", level=40
|
||||
"user aborted, dumping already found URL(s)", level=40
|
||||
))
|
||||
write_to_log_file(retval, URL_LOG_PATH, URL_FILENAME)
|
||||
logger.info(set_color(
|
||||
"found a total of {} URL(s)...".format(len(retval)), level=25
|
||||
"found a total of {} URL(s)".format(len(retval)), level=25
|
||||
))
|
||||
shutdown()
|
||||
except Exception as e:
|
||||
logger.exception(set_color(
|
||||
"Zeus ran into an unexpected error '{}'...".format(e), level=50
|
||||
"Zeus ran into an unexpected error '{}'".format(e), level=50
|
||||
))
|
||||
request_issue_creation()
|
||||
shutdown()
|
||||
|
||||
if len(retval) > 0:
|
||||
logger.info(set_color(
|
||||
"a total of {} URL(s) found out of the requested {}...".format(len(retval), link_amount), level=25
|
||||
"a total of {} URL(s) found out of the requested {}".format(len(retval), link_amount), level=25
|
||||
))
|
||||
file_path = write_to_log_file(retval, URL_LOG_PATH, URL_FILENAME)
|
||||
if show_success:
|
||||
amount_of_urls = len(open(file_path).readlines())
|
||||
success_rate = calculate_success(amount_of_urls)
|
||||
logger.info(set_color(
|
||||
"provided query has a {} success rate...".format(success_rate)
|
||||
"provided query has a {} success rate".format(success_rate)
|
||||
))
|
||||
return list(retval)
|
||||
else:
|
||||
logger.warning(set_color(
|
||||
"did not find any links with given query '{}' writing to blacklist...".format(query), level=30
|
||||
"did not find any links with given query '{}' writing to blacklist".format(query), level=30
|
||||
))
|
||||
write_to_log_file(query, BLACKLIST_FILE_PATH, BLACKLIST_FILENAME)
|
||||
|
|
|
|||
142
zeus.py
142
zeus.py
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import io
|
||||
import sys
|
||||
import time
|
||||
import shlex
|
||||
import warnings
|
||||
|
|
@ -14,7 +15,8 @@ from lib.header_check import main_header_check
|
|||
from lib.core.parse import ZeusParser
|
||||
from lib.core.errors import (
|
||||
InvalidInputProvided,
|
||||
InvalidProxyType
|
||||
InvalidProxyType,
|
||||
ZeusArgumentException
|
||||
)
|
||||
from lib.core.common import (
|
||||
start_up,
|
||||
|
|
@ -43,10 +45,19 @@ warnings.simplefilter("ignore")
|
|||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# this will take care of most of the Unicode errors.
|
||||
reload(sys)
|
||||
sys.setdefaultencoding("utf-8")
|
||||
sys.setrecursionlimit(1500)
|
||||
|
||||
opt = ZeusParser.cmd_parser()
|
||||
|
||||
ZeusParser().single_show_args(opt)
|
||||
|
||||
# verify all the arguments passed before we continue
|
||||
# with the process
|
||||
ZeusParser().verify_args()
|
||||
|
||||
# run the setup on the program
|
||||
setup(verbose=opt.runInVerbose)
|
||||
|
||||
|
|
@ -58,11 +69,11 @@ if __name__ == "__main__":
|
|||
if opt.runInVerbose:
|
||||
being_run = find_running_opts(opt)
|
||||
logger.debug(set_color(
|
||||
"running with options '{}'...".format(being_run), level=10
|
||||
"running with options '{}'".format(being_run), level=10
|
||||
))
|
||||
|
||||
logger.info(set_color(
|
||||
"log file being saved to '{}'...".format(get_latest_log_file(CURRENT_LOG_FILE_PATH))
|
||||
"log file being saved to '{}'".format(get_latest_log_file(CURRENT_LOG_FILE_PATH))
|
||||
))
|
||||
|
||||
|
||||
|
|
@ -83,14 +94,14 @@ if __name__ == "__main__":
|
|||
|
||||
if urls_to_use is None:
|
||||
logger.error(set_color(
|
||||
"unable to run attacks appears that no file was created for the retrieved data...", level=40
|
||||
"unable to run attacks appears that no file was created for the retrieved data", level=40
|
||||
))
|
||||
shutdown()
|
||||
options = [
|
||||
opt.runSqliScan, opt.runPortScan,
|
||||
opt.adminPanelFinder, opt.runXssScan,
|
||||
opt.performWhoisLookup, opt.performClickjackingScan,
|
||||
opt.searchGithub, opt.pgpLookup
|
||||
opt.pgpLookup
|
||||
]
|
||||
if any(options):
|
||||
with open(urls_to_use) as urls:
|
||||
|
|
@ -98,38 +109,47 @@ if __name__ == "__main__":
|
|||
current = i
|
||||
if "webcache" in url:
|
||||
logger.warning(set_color(
|
||||
"ran into unexpected webcache URL skipping...", level=30
|
||||
"ran into unexpected webcache URL skipping", level=30
|
||||
))
|
||||
current -= 1
|
||||
else:
|
||||
logger.info(set_color(
|
||||
"currently running on '{}' (target #{})...".format(
|
||||
url.strip(), current
|
||||
), level=25
|
||||
))
|
||||
logger.info(set_color(
|
||||
"fetching target meta-data..."
|
||||
))
|
||||
main_header_check(
|
||||
url, verbose=opt.runInVerbose, agent=agent_to_use,
|
||||
proxy=proxy_to_use, xforward=opt.forwardedForRandomIP,
|
||||
identify_plugins=opt.identifyPlugin, identify_waf=opt.identifyProtection,
|
||||
show_description=opt.showPluginDescription
|
||||
)
|
||||
run_attacks(
|
||||
url.strip(),
|
||||
sqlmap=opt.runSqliScan, nmap=opt.runPortScan, pgp=opt.pgpLookup,
|
||||
xss=opt.runXssScan, whois=opt.performWhoisLookup, admin=opt.adminPanelFinder,
|
||||
clickjacking=opt.performClickjackingScan, github=opt.searchGithub,
|
||||
verbose=opt.runInVerbose, batch=opt.runInBatch,
|
||||
auto_start=opt.autoStartSqlmap, xforward=opt.forwardedForRandomIP,
|
||||
sqlmap_args=opt.sqlmapArguments, nmap_args=opt.nmapArguments,
|
||||
show_all=opt.showAllConnections, do_threading=opt.threadPanels,
|
||||
tamper_script=opt.tamperXssPayloads, timeout=opt.controlTimeout,
|
||||
proxy=proxy_to_use, agent=agent_to_use, conf_file=opt.sqlmapConfigFile,
|
||||
threads=opt.amountOfThreads
|
||||
)
|
||||
print("\n")
|
||||
if not url.strip() == "http://" or url == "https://":
|
||||
logger.info(set_color(
|
||||
"currently running on '{}' (target #{})".format(
|
||||
url.strip(), current
|
||||
), level=25
|
||||
))
|
||||
logger.info(set_color(
|
||||
"fetching target meta-data"
|
||||
))
|
||||
identified = main_header_check(
|
||||
url, verbose=opt.runInVerbose, agent=agent_to_use,
|
||||
proxy=proxy_to_use, xforward=opt.forwardedForRandomIP,
|
||||
identify_plugins=opt.identifyPlugin, identify_waf=opt.identifyProtection,
|
||||
show_description=opt.showPluginDescription
|
||||
)
|
||||
if not identified:
|
||||
logger.error(set_color(
|
||||
"target is refusing to allow meta-data dumping, skipping", level=40
|
||||
))
|
||||
run_attacks(
|
||||
url.strip(),
|
||||
sqlmap=opt.runSqliScan, nmap=opt.runPortScan, pgp=opt.pgpLookup,
|
||||
xss=opt.runXssScan, whois=opt.performWhoisLookup, admin=opt.adminPanelFinder,
|
||||
clickjacking=opt.performClickjackingScan, github=opt.searchGithub,
|
||||
verbose=opt.runInVerbose, batch=opt.runInBatch,
|
||||
auto_start=opt.autoStartSqlmap, xforward=opt.forwardedForRandomIP,
|
||||
sqlmap_args=opt.sqlmapArguments, nmap_args=opt.nmapArguments,
|
||||
show_all=opt.showAllConnections, do_threading=opt.threadPanels,
|
||||
tamper_script=opt.tamperXssPayloads, timeout=opt.controlTimeout,
|
||||
proxy=proxy_to_use, agent=agent_to_use, conf_file=opt.sqlmapConfigFile,
|
||||
threads=opt.amountOfThreads, force_ssl=opt.forceSSL
|
||||
)
|
||||
print("\n")
|
||||
else:
|
||||
logger.warning(set_color(
|
||||
"malformed URL discovered, skipping", level=30
|
||||
))
|
||||
|
||||
|
||||
proxy_to_use, agent_to_use = config_headers(
|
||||
|
|
@ -146,7 +166,7 @@ if __name__ == "__main__":
|
|||
# use a personal dork as the query
|
||||
if opt.dorkToUse is not None and not opt.searchMultiplePages:
|
||||
logger.info(set_color(
|
||||
"starting dork scan with query '{}'...".format(opt.dorkToUse)
|
||||
"starting dork scan with query '{}'".format(opt.dorkToUse)
|
||||
))
|
||||
try:
|
||||
selenium_search.parse_search_results(
|
||||
|
|
@ -159,19 +179,19 @@ if __name__ == "__main__":
|
|||
supported_proxy_types = ("socks5", "socks4", "https", "http")
|
||||
logger.fatal(set_color(
|
||||
"the provided proxy is not valid, specify the protocol and try again, supported "
|
||||
"proxy protocols are {} (IE socks5://127.0.0.1:9050)...".format(
|
||||
"proxy protocols are {} (IE socks5://127.0.0.1:9050)".format(
|
||||
", ".join(list(supported_proxy_types))), level=50
|
||||
))
|
||||
except Exception as e:
|
||||
if "Permission denied:" in str(e):
|
||||
logger.fatal(set_color(
|
||||
"your permissions are not allowing Zeus to run, "
|
||||
"try running Zeus with sudo...", level=50
|
||||
"try running Zeus with sudo", level=50
|
||||
))
|
||||
shutdown()
|
||||
else:
|
||||
logger.exception(set_color(
|
||||
"ran into exception '{}'...".format(e), level=50
|
||||
"ran into exception '{}'".format(e), level=50
|
||||
))
|
||||
request_issue_creation()
|
||||
pass
|
||||
|
|
@ -189,7 +209,7 @@ if __name__ == "__main__":
|
|||
|
||||
if dork_to_use is None:
|
||||
logger.warning(set_color(
|
||||
"there has been no dork to specified to do the searching, defaulting to random dork...", level=30
|
||||
"there has been no dork to specified to do the searching, defaulting to random dork", level=30
|
||||
))
|
||||
dork_to_use = get_random_dork()
|
||||
|
||||
|
|
@ -197,14 +217,14 @@ if __name__ == "__main__":
|
|||
|
||||
if opt.amountToSearch is None:
|
||||
logger.warning(set_color(
|
||||
"did not specify amount of links to find defaulting to 75...", level=30
|
||||
"did not specify amount of links to find defaulting to 75", level=30
|
||||
))
|
||||
link_amount_to_search = 75
|
||||
else:
|
||||
link_amount_to_search = opt.amountToSearch
|
||||
|
||||
logger.info(set_color(
|
||||
"searching Google using dork '{}' for a total of {} links...".format(
|
||||
"searching Google using dork '{}' for a total of {} links".format(
|
||||
dork_to_use, link_amount_to_search
|
||||
)
|
||||
))
|
||||
|
|
@ -218,11 +238,11 @@ if __name__ == "__main__":
|
|||
except Exception as e:
|
||||
if "Error 400" in str(e):
|
||||
logger.fatal(set_color(
|
||||
"failed to connect to search engine...".format(e), level=50
|
||||
"failed to connect to search engine".format(e), level=50
|
||||
))
|
||||
else:
|
||||
logger.exception(set_color(
|
||||
"failed with unexpected error '{}'...".format(e), level=50
|
||||
"failed with unexpected error '{}'".format(e), level=50
|
||||
))
|
||||
shutdown()
|
||||
|
||||
|
|
@ -234,7 +254,7 @@ if __name__ == "__main__":
|
|||
for dork in dorks.readlines():
|
||||
dork = dork.strip()
|
||||
logger.info(set_color(
|
||||
"starting dork scan with query '{}'...".format(dork)
|
||||
"starting dork scan with query '{}'".format(dork)
|
||||
))
|
||||
try:
|
||||
selenium_search.parse_search_results(
|
||||
|
|
@ -244,7 +264,7 @@ if __name__ == "__main__":
|
|||
)
|
||||
except Exception as e:
|
||||
logger.exception(set_color(
|
||||
"ran into exception '{}'...".format(e), level=50
|
||||
"ran into exception '{}'".format(e), level=50
|
||||
))
|
||||
request_issue_creation()
|
||||
pass
|
||||
|
|
@ -256,10 +276,10 @@ if __name__ == "__main__":
|
|||
random_dork = get_random_dork().strip()
|
||||
if opt.runInVerbose:
|
||||
logger.debug(set_color(
|
||||
"choosing random dork from etc/dorks.txt...", level=10
|
||||
"choosing random dork from etc/dorks.txt", level=10
|
||||
))
|
||||
logger.info(set_color(
|
||||
"using random dork '{}' as the search query...".format(random_dork)
|
||||
"using random dork '{}' as the search query".format(random_dork)
|
||||
))
|
||||
try:
|
||||
selenium_search.parse_search_results(
|
||||
|
|
@ -271,7 +291,7 @@ if __name__ == "__main__":
|
|||
|
||||
except Exception as e:
|
||||
logger.exception(set_color(
|
||||
"ran into exception '{}' and cannot continue, saved to current log file...".format(e),
|
||||
"ran into exception '{}' and cannot continue, saved to current log file".format(e),
|
||||
level=50
|
||||
))
|
||||
request_issue_creation()
|
||||
|
|
@ -281,7 +301,7 @@ if __name__ == "__main__":
|
|||
elif opt.spiderWebSite:
|
||||
problem_identifiers = ["http://", "https://"]
|
||||
if not URL_REGEX.match(opt.spiderWebSite):
|
||||
err_msg = "URL did not match a true URL{}..."
|
||||
err_msg = "URL did not match a true URL{}"
|
||||
if not any(m in opt.spiderWebSite for m in problem_identifiers):
|
||||
err_msg = err_msg.format(" issue seems to be that http:// "
|
||||
"or https:// is not present in the URL")
|
||||
|
|
@ -317,7 +337,7 @@ if __name__ == "__main__":
|
|||
# enumerate a file and run attacks on the URL's provided
|
||||
elif opt.fileToEnumerate is not None:
|
||||
logger.info(set_color(
|
||||
"found a total of {} URL's to enumerate in given file...".format(
|
||||
"found a total of {} URL's to enumerate in given file".format(
|
||||
len(open(opt.fileToEnumerate).readlines())
|
||||
)
|
||||
))
|
||||
|
|
@ -325,7 +345,7 @@ if __name__ == "__main__":
|
|||
|
||||
else:
|
||||
logger.critical(set_color(
|
||||
"failed to provide a mandatory argument, you will be redirected to the help menu...", level=50
|
||||
"failed to provide a mandatory argument, you will be redirected to the help menu", level=50
|
||||
))
|
||||
time.sleep(2)
|
||||
zeus_help_menu_command = shlex.split("python zeus.py --help")
|
||||
|
|
@ -333,7 +353,7 @@ if __name__ == "__main__":
|
|||
except IOError as e:
|
||||
if "Invalid URL" in str(e):
|
||||
logger.exception(set_color(
|
||||
"URL provided is not valid, schema appears to be missing...", level=50
|
||||
"URL provided is not valid, schema appears to be missing", level=50
|
||||
))
|
||||
request_issue_creation()
|
||||
shutdown()
|
||||
|
|
@ -344,38 +364,40 @@ if __name__ == "__main__":
|
|||
))
|
||||
shutdown()
|
||||
elif "No such file or directory" in str(e):
|
||||
logger.exception(e)
|
||||
logger.fatal(set_color(
|
||||
"provided file does not exist, make sure you have the full path...", level=50
|
||||
"provided file does not exist, make sure you have the full path", level=50
|
||||
))
|
||||
shutdown()
|
||||
else:
|
||||
logger.exception(set_color(
|
||||
"Zeus has hit an unexpected error and cannot continue, error code '{}'...".format(e), level=50
|
||||
"Zeus has hit an unexpected error and cannot continue, error code '{}'".format(e), level=50
|
||||
))
|
||||
request_issue_creation()
|
||||
except KeyboardInterrupt:
|
||||
logger.fatal(set_color(
|
||||
"user aborted process...", level=50
|
||||
"user aborted process", level=50
|
||||
))
|
||||
shutdown()
|
||||
except UnboundLocalError:
|
||||
logger.warning(set_color(
|
||||
"do not interrupt the browser when selenium is running, "
|
||||
"it will cause Zeus to crash...", level=30
|
||||
"it will cause Zeus to crash", level=30
|
||||
))
|
||||
except ZeusArgumentException:
|
||||
shutdown()
|
||||
except Exception as e:
|
||||
if "url did not match a true url" in str(e).lower():
|
||||
logger.error(set_color(
|
||||
"you did not provide a URL that is capable of being processed, "
|
||||
"the URL provided to the spider needs to contain protocol as well "
|
||||
"ie. 'http://google.com' (it is advised not to add the GET parameter), "
|
||||
"fix the URL you want to scan and try again...", level=40
|
||||
"fix the URL you want to scan and try again", level=40
|
||||
))
|
||||
shutdown()
|
||||
elif "Service geckodriver unexpectedly exited" in str(e):
|
||||
logger.fatal(set_color(
|
||||
"it seems your firefox version is not compatible with the geckodriver version, "
|
||||
"please re-install Zeus and try again...", level=50
|
||||
"please re-install Zeus and try again", level=50
|
||||
))
|
||||
shutdown()
|
||||
elif "Max retries exceeded with url" in str(e):
|
||||
|
|
@ -387,7 +409,7 @@ if __name__ == "__main__":
|
|||
shutdown()
|
||||
else:
|
||||
logger.exception(set_color(
|
||||
"ran into exception '{}' exception has been saved to log file...".format(e), level=50
|
||||
"ran into exception '{}' exception has been saved to log file".format(e), level=50
|
||||
))
|
||||
request_issue_creation()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue