diff options
Diffstat (limited to 'no_buster.sh')
-rwxr-xr-x | no_buster.sh | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/no_buster.sh b/no_buster.sh new file mode 100755 index 0000000..25ac759 --- /dev/null +++ b/no_buster.sh @@ -0,0 +1,127 @@ +#!/usr/bin/env bash + +# no_buster - a tool to check if someone uses a 'default' wordlist to gain access to web directorys that are not visible by default +# author: Mike Wollmann aka. jak1 +# requires: root access +# iptables +# +# TODO/WIP: +# add: checks if apache has this path, so we don't catch real paths in our routin and accidentaly ban someone for using the webservices the right way X_X! + + +# --> configuration section +max_rows=2; # when get 5 (default) hits in a row the ip gets blocked +dir_files="./wordlists/dirb/common.txt ./wordlists/dirbuster/apache-user-enum-1.0.txt"; # dont add more then 10 files! every file has 10 words to check for! 10*10 = 100 words per log entry! every 60 secounds per default. +check_first_x_lines=10; +wl_file_opt="head -n${check_first_x_lines}"; + +check_every_sec=60; # time between checks +check_log_lines=10; # 10 by default, can be increased, but will cause some cpu usage the higher it is. +log_file_opt="tail -n${check_log_lines}"; # using tail +access_log="/var/log/apache2/access.log"; +access_log="./access.log"; # remove this line later! + +no_buster_log_dir="/var/log/no_buster/"; +no_buster_log_file="no_buster"; + +ip_tables="/sbin/iptables"; +ip_tables_chain="no_buster"; +# <-- configuration section + + +if [[ `whoami` != "root" ]]; then + echo "you need to be root for:"; + echo " - reading ${access_log}"; + echo " - reading and writing to iptables"; + echo " - writing no_buster.log to ${no_buster_log_dir}"; + exit 1 +fi + +n=`which iptables` +if [[ $? != 0 ]]; then + echo "iptables is required!"; +fi +unset $n + +function cac_chain(){ + # check and create chain + check=`${ip_tables} -L ${ip_tables_chain} -v -n`; + if [[ $? != 0 ]]; then + `${ip_tables} -N ${ip_tables_chain}`; + `${ip_tables} -A OUTPUT -j ${ip_tables_chain}`; + `${ip_tables} -A ${ip_tables_chain} -p tcp --dport 80 -j ACCEPT`; + `${ip_tables} -A ${ip_tables_chain} -p tcp --dport 443 -j ACCEPT`; + echo "chain '${ip_tables_chain}' created"; + fi +} + +function logging(){ + if [[ ! -d "${no_buster_log_dir}" ]]; then + mkdir -p "${no_buster_log_dir}"; + fi + timestamp=$(date +'%d.%m.%Y - %r'); + filedate=$(date +'%m-%Y'); + echo -e "${timestamp}: ${1}" >> "${no_buster_log_dir}${no_buster_log_file}-${filedate}.log"; +} + +function block_ip(){ + # dont block loopback! + if [[ "${1}" != "127.0.0.1" ]]; then + check=`${ip_tables} -L ${ip_tables_chain} -v -n | grep "${1}"`; + if [[ ${?} != 0 ]]; then + # http:// (should not even get used anymore) + e1=`${ip_tables} -A ${ip_tables_chain} -p tcp --dport 80 -s "${1}" -j DROP`; + # https:// + e2=`${ip_tables} -A ${ip_tables_chain} -p tcp --dport 443 -s "${1}" -j DROP`; + logging "${1} got blocked for ports: 80 & 443\n ${2}"; + return 1 + else + # because of log spam ^^' cause of tail -n{N} it well get removed in the next {N} hits via p80/p443 + #logging "WARN: $1 got allready blocked" + #logging "${check}" + return 0 + fi + fi + return 0 + +} + +function wl_check(){ + n_ip=""; + last_lines=`${log_file_opt} ${access_log}`; + IFS=$'\n' read -rd '' -a y <<<"$last_lines"; + o_hit_paths=""; + for ((i = 1; i < ${#y[@]}; i++)); do + o_ip=`echo ${y[$i]} | awk '{print $1}'`; + o_hit_path=`echo ${y[$i]} | awk '{print $7}'`; + if [[ "${n_ip}" == "${o_ip}" || ${n_ip} == "" ]]; then + for dir_file in ${dir_files}; do + if [[ -f "${dir_file}" ]]; then + wl_file=`${wl_file_opt} ${dir_file}`; + for x in ${wl_file}; do + if [[ "${o_hit_path}" == *"${x}"* ]]; then + hits_per_row=$((hits_per_row+1)); + o_hit_paths="${o_hit_paths}\n\t\t\t\t${o_hit_path}"; + if [[ ${hits_per_row} -ge ${max_rows} ]]; then + block_ip ${o_ip} "reason:\n\t\t\t\tfound '${hits_per_row}' hits in a row. \n\t\t\tpaths:${o_hit_paths}"; + fi + break; + else + o_hit_paths=""; + hits_per_row=0; + fi + done + fi + done + fi + n_ip=${o_ip}; + done +} + + +running=1; +cac_chain; +while [[ ${running} != 0 ]]; do + wl_check; + sleep ${check_every_sec}; +done
\ No newline at end of file |