summaryrefslogtreecommitdiff
path: root/no_buster.sh
diff options
context:
space:
mode:
Diffstat (limited to 'no_buster.sh')
-rwxr-xr-xno_buster.sh127
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