blob: 25ac7599bbf1a00519c17e556908b6514fad530b (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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
|