Merge pull request #473 from FluxionNetwork/resumable-attacks
Resumable attacks
This commit is contained in:
commit
8d2304e71b
|
@ -24,6 +24,8 @@ CaptivePortalGatewayNetwork=${CaptivePortalGatewayAddress%.*}
|
||||||
# ============== < Captive Portal Subroutines > ============== #
|
# ============== < Captive Portal Subroutines > ============== #
|
||||||
# ============================================================ #
|
# ============================================================ #
|
||||||
captive_portal_unset_jammer_interface() {
|
captive_portal_unset_jammer_interface() {
|
||||||
|
CaptivePortalJammerInterfaceOriginal=""
|
||||||
|
|
||||||
if [ ! "$CaptivePortalJammerInterface" ]; then return 1; fi
|
if [ ! "$CaptivePortalJammerInterface" ]; then return 1; fi
|
||||||
CaptivePortalJammerInterface=""
|
CaptivePortalJammerInterface=""
|
||||||
|
|
||||||
|
@ -38,20 +40,18 @@ captive_portal_unset_jammer_interface() {
|
||||||
captive_portal_set_jammer_interface() {
|
captive_portal_set_jammer_interface() {
|
||||||
if [ "$CaptivePortalJammerInterface" ]; then return 0; fi
|
if [ "$CaptivePortalJammerInterface" ]; then return 0; fi
|
||||||
|
|
||||||
|
if [ ! "$CaptivePortalJammerInterfaceOriginal" ]; then
|
||||||
if [ ! "$CaptivePortalUninitializedJammerInterface" ]; then
|
|
||||||
echo "Running get jammer interface." > $FLUXIONOutputDevice
|
echo "Running get jammer interface." > $FLUXIONOutputDevice
|
||||||
if ! fluxion_get_interface attack_targetting_interfaces \
|
if ! fluxion_get_interface attack_targetting_interfaces \
|
||||||
"$CaptivePortalJammerInterfaceQuery"; then
|
"$CaptivePortalJammerInterfaceQuery"; then
|
||||||
echo "Failed to get jammer interface" > $FLUXIONOutputDevice
|
echo "Failed to get jammer interface" > $FLUXIONOutputDevice
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
local selectedInterface=$FluxionInterfaceSelected
|
CaptivePortalJammerInterfaceOriginal=$FluxionInterfaceSelected
|
||||||
else
|
|
||||||
local selectedInterface=$CaptivePortalUninitializedJammerInterface
|
|
||||||
unset CaptivePortalUninitializedJammerInterface
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local selectedInterface=$CaptivePortalJammerInterfaceOriginal
|
||||||
|
|
||||||
if ! fluxion_allocate_interface $selectedInterface; then
|
if ! fluxion_allocate_interface $selectedInterface; then
|
||||||
echo "Failed to allocate jammer interface" > $FLUXIONOutputDevice
|
echo "Failed to allocate jammer interface" > $FLUXIONOutputDevice
|
||||||
return 2
|
return 2
|
||||||
|
@ -71,6 +71,8 @@ captive_portal_ap_interfaces() {
|
||||||
}
|
}
|
||||||
|
|
||||||
captive_portal_unset_ap_interface() {
|
captive_portal_unset_ap_interface() {
|
||||||
|
CaptivePortalAccessPointInterfaceOriginal=""
|
||||||
|
|
||||||
if [ ! "$CaptivePortalAccessPointInterface" ]; then return 1; fi
|
if [ ! "$CaptivePortalAccessPointInterface" ]; then return 1; fi
|
||||||
if [ "$CaptivePortalAccessPointInterface" = \
|
if [ "$CaptivePortalAccessPointInterface" = \
|
||||||
"${CaptivePortalJammerInterface}v" ]; then
|
"${CaptivePortalJammerInterface}v" ]; then
|
||||||
|
@ -86,19 +88,18 @@ captive_portal_unset_ap_interface() {
|
||||||
captive_portal_set_ap_interface() {
|
captive_portal_set_ap_interface() {
|
||||||
if [ "$CaptivePortalAccessPointInterface" ]; then return 0; fi
|
if [ "$CaptivePortalAccessPointInterface" ]; then return 0; fi
|
||||||
|
|
||||||
if [ ! "$CaptivePortalUninitializedAccessPointInterface" ]; then
|
if [ ! "$CaptivePortalAccessPointInterfaceOriginal" ]; then
|
||||||
echo "Running get ap interface." > $FLUXIONOutputDevice
|
echo "Running get ap interface." > $FLUXIONOutputDevice
|
||||||
if ! fluxion_get_interface captive_portal_ap_interfaces \
|
if ! fluxion_get_interface captive_portal_ap_interfaces \
|
||||||
"$CaptivePortalAccessPointInterfaceQuery"; then
|
"$CaptivePortalAccessPointInterfaceQuery"; then
|
||||||
echo "Failed to get ap interface" > $FLUXIONOutputDevice
|
echo "Failed to get ap interface" > $FLUXIONOutputDevice
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
local selectedInterface=$FluxionInterfaceSelected
|
CaptivePortalAccessPointInterfaceOriginal=$FluxionInterfaceSelected
|
||||||
else
|
|
||||||
local selectedInterface=$CaptivePortalUninitializedAccessPointInterface
|
|
||||||
unset CaptivePortalUninitializedAccessPointInterface
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local selectedInterface=$CaptivePortalAccessPointInterfaceOriginal
|
||||||
|
|
||||||
if ! fluxion_allocate_interface $selectedInterface; then
|
if ! fluxion_allocate_interface $selectedInterface; then
|
||||||
echo "Failed to allocate ap interface" > $FLUXIONOutputDevice
|
echo "Failed to allocate ap interface" > $FLUXIONOutputDevice
|
||||||
return 2
|
return 2
|
||||||
|
@ -140,9 +141,15 @@ function captive_portal_unset_ap_service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function captive_portal_set_ap_service() {
|
function captive_portal_set_ap_service() {
|
||||||
if [ "$CaptivePortalAPService" ]; then return 0; fi
|
if [ "$CaptivePortalAPService" ]; then
|
||||||
|
if ! type -t ap_service_start; then
|
||||||
|
# AP Service: Load the service's helper routines.
|
||||||
|
source "lib/ap/$CaptivePortalAPService.sh"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
if ! interface_is_wireless "$CaptivePortalAccessPointInterface"; then
|
if ! interface_is_wireless "$CaptivePortalAccessPointInterface"; then
|
||||||
return 0;
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
captive_portal_unset_ap_service
|
captive_portal_unset_ap_service
|
||||||
|
@ -205,10 +212,16 @@ captive_portal_unset_authenticator() {
|
||||||
|
|
||||||
captive_portal_set_authenticator() {
|
captive_portal_set_authenticator() {
|
||||||
if [ "$CaptivePortalAuthenticatorMode" ]; then
|
if [ "$CaptivePortalAuthenticatorMode" ]; then
|
||||||
|
case "$CaptivePortalAuthenticatorMode" in
|
||||||
|
"hash")
|
||||||
|
if [ "$CaptivePortalHashPath" ]; then
|
||||||
echo "Captive Portal authentication mode is already set, skipping!" \
|
echo "Captive Portal authentication mode is already set, skipping!" \
|
||||||
> $FLUXIONOutputDevice
|
> $FLUXIONOutputDevice
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
captive_portal_unset_authenticator
|
captive_portal_unset_authenticator
|
||||||
|
|
||||||
|
@ -277,7 +290,7 @@ captive_portal_set_authenticator() {
|
||||||
captive_portal_run_certificate_generator() {
|
captive_portal_run_certificate_generator() {
|
||||||
xterm -bg "#000000" -fg "#CCCCCC" \
|
xterm -bg "#000000" -fg "#CCCCCC" \
|
||||||
-title "Generating Self-Signed SSL Certificate" -e openssl req \
|
-title "Generating Self-Signed SSL Certificate" -e openssl req \
|
||||||
-subj '/CN=captive.router.lan/O=CaptivePortal/OU=Networking/C=US' \
|
-subj '/CN=captive.gateway.lan/O=CaptivePortal/OU=Networking/C=US' \
|
||||||
-new -newkey rsa:2048 -days 365 -nodes -x509 \
|
-new -newkey rsa:2048 -days 365 -nodes -x509 \
|
||||||
-keyout "$FLUXIONWorkspacePath/server.pem" \
|
-keyout "$FLUXIONWorkspacePath/server.pem" \
|
||||||
-out "$FLUXIONWorkspacePath/server.pem"
|
-out "$FLUXIONWorkspacePath/server.pem"
|
||||||
|
@ -299,7 +312,10 @@ captive_portal_unset_certificate() {
|
||||||
|
|
||||||
# Create Self-Signed SSL Certificate
|
# Create Self-Signed SSL Certificate
|
||||||
captive_portal_set_certificate() {
|
captive_portal_set_certificate() {
|
||||||
if [ "$CaptivePortalSSL" ]; then
|
if [ \
|
||||||
|
"$CaptivePortalSSL" = "disabled" -o \
|
||||||
|
"$CaptivePortalSSL" = "enabled" -a \
|
||||||
|
-f "$FLUXIONWorkspacePath/server.pem" ]; then
|
||||||
echo "Captive Portal SSL mode already set to $CaptivePortalSSL!" \
|
echo "Captive Portal SSL mode already set to $CaptivePortalSSL!" \
|
||||||
> $FLUXIONOutputDevice
|
> $FLUXIONOutputDevice
|
||||||
return 0
|
return 0
|
||||||
|
@ -323,6 +339,18 @@ captive_portal_set_certificate() {
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Check if we're restoring and we need to re-create certificate.
|
||||||
|
if [ "$CaptivePortalSSL" = "enabled" ]; then
|
||||||
|
if ! captive_portal_run_certificate_generator; then
|
||||||
|
fluxion_conditional_bail "cert-gen failed!"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
CaptivePortalSSL="enabled"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ "$FLUXIONAuto" ]; then
|
if [ "$FLUXIONAuto" ]; then
|
||||||
CaptivePortalSSL="disabled"
|
CaptivePortalSSL="disabled"
|
||||||
else
|
else
|
||||||
|
@ -1251,6 +1279,41 @@ prep_attack() {
|
||||||
CaptivePortalState="Ready"
|
CaptivePortalState="Ready"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
load_attack() {
|
||||||
|
local -r configurationPath=$1
|
||||||
|
|
||||||
|
local configuration
|
||||||
|
readarray -t configuration < <(more "$configurationPath")
|
||||||
|
|
||||||
|
CaptivePortalJammerInterfaceOriginal=${configuration[0]}
|
||||||
|
CaptivePortalAccessPointInterfaceOriginal=${configuration[1]}
|
||||||
|
CaptivePortalAPService=${configuration[2]}
|
||||||
|
CaptivePortalAuthenticatorMode=${configuration[3]}
|
||||||
|
CaptivePortalSSL=${configuration[4]}
|
||||||
|
CaptivePortalConnectivity=${configuration[5]}
|
||||||
|
CaptivePortalUserInterface=${configuration[6]}
|
||||||
|
|
||||||
|
# Hash authenticator mode configuration.
|
||||||
|
CaptivePortalHashPath=${configuration[7]}
|
||||||
|
}
|
||||||
|
|
||||||
|
save_attack() {
|
||||||
|
local -r configurationPath=$1
|
||||||
|
|
||||||
|
# Store/overwrite attack configuration for pause & resume.
|
||||||
|
# Order: JammerWI, APWI, APServ, AuthMode, SSL, Conn, UI
|
||||||
|
echo "$CaptivePortalJammerInterfaceOriginal" > "$configurationPath"
|
||||||
|
echo "$CaptivePortalAccessPointInterfaceOriginal" >> "$configurationPath"
|
||||||
|
echo "$CaptivePortalAPService" >> "$configurationPath"
|
||||||
|
echo "$CaptivePortalAuthenticatorMode" >> "$configurationPath"
|
||||||
|
echo "$CaptivePortalSSL" >> "$configurationPath"
|
||||||
|
echo "$CaptivePortalConnectivity" >> "$configurationPath"
|
||||||
|
echo "$CaptivePortalUserInterface" >> "$configurationPath"
|
||||||
|
|
||||||
|
# Hash authenticator mode configuration.
|
||||||
|
echo "$CaptivePortalHashPath" >> "$configurationPath"
|
||||||
|
}
|
||||||
|
|
||||||
stop_attack() {
|
stop_attack() {
|
||||||
# Attempt to find PIDs of any running authenticators.
|
# Attempt to find PIDs of any running authenticators.
|
||||||
local authenticatorPID=$(ps a | grep -vE "xterm|grep" | grep captive_portal_authenticator.sh | awk '{print $1}')
|
local authenticatorPID=$(ps a | grep -vE "xterm|grep" | grep captive_portal_authenticator.sh | awk '{print $1}')
|
||||||
|
|
|
@ -222,6 +222,8 @@ handshake_snooper_set_deauthenticator_identifier() {
|
||||||
}
|
}
|
||||||
|
|
||||||
handshake_snooper_unset_jammer_interface() {
|
handshake_snooper_unset_jammer_interface() {
|
||||||
|
HandshakeSnooperJammerInterfaceOriginal=""
|
||||||
|
|
||||||
if [ ! "$HandshakeSnooperJammerInterface" ]; then return 1; fi
|
if [ ! "$HandshakeSnooperJammerInterface" ]; then return 1; fi
|
||||||
HandshakeSnooperJammerInterface=""
|
HandshakeSnooperJammerInterface=""
|
||||||
|
|
||||||
|
@ -238,19 +240,18 @@ handshake_snooper_set_jammer_interface() {
|
||||||
#if [ "$HandshakeSnooperDeauthenticatorIdentifier" = \
|
#if [ "$HandshakeSnooperDeauthenticatorIdentifier" = \
|
||||||
# "$HandshakeSnooperMonitorMethodOption" ]; then return 0; fi
|
# "$HandshakeSnooperMonitorMethodOption" ]; then return 0; fi
|
||||||
|
|
||||||
if [ ! "$HandshakeSnooperUninitializedJammerInterface" ]; then
|
if [ ! "$HandshakeSnooperJammerInterfaceOriginal" ]; then
|
||||||
echo "Running get jammer interface." > $FLUXIONOutputDevice
|
echo "Running get jammer interface." > $FLUXIONOutputDevice
|
||||||
if ! fluxion_get_interface attack_targetting_interfaces \
|
if ! fluxion_get_interface attack_targetting_interfaces \
|
||||||
"$HandshakeSnooperJammerInterfaceQuery"; then
|
"$HandshakeSnooperJammerInterfaceQuery"; then
|
||||||
echo "Failed to get jammer interface" > $FLUXIONOutputDevice
|
echo "Failed to get jammer interface" > $FLUXIONOutputDevice
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
local selectedInterface=$FluxionInterfaceSelected
|
HandshakeSnooperJammerInterfaceOriginal=$FluxionInterfaceSelected
|
||||||
else
|
|
||||||
local selectedInterface=$HandshakeSnooperUninitializedJammerInterface
|
|
||||||
unset HandshakeSnooperUninitializedJammerInterface
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local selectedInterface=$HandshakeSnooperJammerInterfaceOriginal
|
||||||
|
|
||||||
if ! fluxion_allocate_interface $selectedInterface; then
|
if ! fluxion_allocate_interface $selectedInterface; then
|
||||||
echo "Failed to allocate jammer interface" > $FLUXIONOutputDevice
|
echo "Failed to allocate jammer interface" > $FLUXIONOutputDevice
|
||||||
return 2
|
return 2
|
||||||
|
@ -424,31 +425,6 @@ prep_attack() {
|
||||||
|
|
||||||
IOUtilsHeader="handshake_snooper_header"
|
IOUtilsHeader="handshake_snooper_header"
|
||||||
|
|
||||||
local -r attackPath="$FLUXIONPath/attacks/Handshake Snooper"
|
|
||||||
|
|
||||||
# Attempt loading configuration if one is available.
|
|
||||||
# TODO: Enable this by removing extraneous " -a ! " when properly implemented.
|
|
||||||
if [ -f "$attackPath/attack.conf" -a ! ]; then
|
|
||||||
local choice=${1:+Y}
|
|
||||||
# TODO: This doesn't translate choices to the selected language.
|
|
||||||
while ! echo "$choice" | grep -q "^[ynYN]$" &> /dev/null; do
|
|
||||||
echo -ne "$FLUXIONVLine Would you like to repeat the last attack? [Y/n] "
|
|
||||||
read choice
|
|
||||||
if [ ! "$choice" ]; then break; fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "${choice,,}" != "n" ]; then
|
|
||||||
local configuration
|
|
||||||
readarray -t configuration < <(more "$attackPath/attack.conf")
|
|
||||||
|
|
||||||
HandshakeSnooperDeauthenticatorIdentifier=${configuration[0]}
|
|
||||||
HandshakeSnooperJammerInterface=${configuration[1]}
|
|
||||||
HandshakeSnooperVerifierIdentifier=${configuration[2]}
|
|
||||||
HandshakeSnooperVerifierInterval=${configuration[3]}
|
|
||||||
HandshakeSnooperVerifierSynchronicity=${configuration[4]}
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Removed read-only due to local constant shadowing bug.
|
# Removed read-only due to local constant shadowing bug.
|
||||||
# I've reported the bug, we can add it when fixed.
|
# I've reported the bug, we can add it when fixed.
|
||||||
local sequence=(
|
local sequence=(
|
||||||
|
@ -463,15 +439,32 @@ prep_attack() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
HandshakeSnooperState="Ready"
|
||||||
|
}
|
||||||
|
|
||||||
|
load_attack() {
|
||||||
|
local -r configurationPath=$1
|
||||||
|
|
||||||
|
local configuration
|
||||||
|
readarray -t configuration < <(more "$configurationPath")
|
||||||
|
|
||||||
|
HandshakeSnooperDeauthenticatorIdentifier=${configuration[0]}
|
||||||
|
HandshakeSnooperJammerInterfaceOriginal=${configuration[1]}
|
||||||
|
HandshakeSnooperVerifierIdentifier=${configuration[2]}
|
||||||
|
HandshakeSnooperVerifierInterval=${configuration[3]}
|
||||||
|
HandshakeSnooperVerifierSynchronicity=${configuration[4]}
|
||||||
|
}
|
||||||
|
|
||||||
|
save_attack() {
|
||||||
|
local -r configurationPath=$1
|
||||||
|
|
||||||
# Store/overwrite attack configuration for pause & resume.
|
# Store/overwrite attack configuration for pause & resume.
|
||||||
# Order: DeauthID, JammerWI, VerifId, VerifInt, VerifSync
|
# Order: DeauthID, JammerWI, VerifId, VerifInt, VerifSync
|
||||||
echo "$HandshakeSnooperDeauthenticatorIdentifier" > "$attackPath/attack.conf"
|
echo "$HandshakeSnooperDeauthenticatorIdentifier" > "$configurationPath"
|
||||||
echo "$HandshakeSnooperJammerInterface" >> "$attackPath/attack.conf"
|
echo "$HandshakeSnooperJammerInterfaceOriginal" >> "$configurationPath"
|
||||||
echo "$HandshakeSnooperVerifierIdentifier" >> "$attackPath/attack.conf"
|
echo "$HandshakeSnooperVerifierIdentifier" >> "$configurationPath"
|
||||||
echo "$HandshakeSnooperVerifierInterval" >> "$attackPath/attack.conf"
|
echo "$HandshakeSnooperVerifierInterval" >> "$configurationPath"
|
||||||
echo "$HandshakeSnooperVerifierSynchronicity" >> "$attackPath/attack.conf"
|
echo "$HandshakeSnooperVerifierSynchronicity" >> "$configurationPath"
|
||||||
|
|
||||||
HandshakeSnooperState="Ready"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_attack() {
|
stop_attack() {
|
||||||
|
|
55
fluxion.sh
55
fluxion.sh
|
@ -450,6 +450,26 @@ fluxion_handle_target_change() {
|
||||||
FluxionTargetChannel=${targetInfo[2]}
|
FluxionTargetChannel=${targetInfo[2]}
|
||||||
|
|
||||||
FluxionTargetSSIDClean=$(fluxion_target_normalize_SSID)
|
FluxionTargetSSIDClean=$(fluxion_target_normalize_SSID)
|
||||||
|
|
||||||
|
if ! stop_attack; then
|
||||||
|
fluxion_conditional_bail "Target tracker failed to stop attack."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! unprep_attack; then
|
||||||
|
fluxion_conditional_bail "Target tracker failed to unprep attack."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! load_attack "$FLUXIONPath/attacks/$FluxionAttack/attack.conf"; then
|
||||||
|
fluxion_conditional_bail "Target tracker failed to load attack."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! prep_attack; then
|
||||||
|
fluxion_conditional_bail "Target tracker failed to prep attack."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! fluxion_run_attack; then
|
||||||
|
fluxion_conditional_bail "Target tracker failed to start attack."
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# If target monitoring enabled, act on changes.
|
# If target monitoring enabled, act on changes.
|
||||||
|
@ -1699,10 +1719,14 @@ fluxion_unprep_attack() {
|
||||||
|
|
||||||
IOUtilsHeader="fluxion_header"
|
IOUtilsHeader="fluxion_header"
|
||||||
|
|
||||||
# Remove any lingering targetting loaded subroutines
|
# Remove any lingering targetting subroutines loaded.
|
||||||
unset attack_targetting_interfaces
|
unset attack_targetting_interfaces
|
||||||
unset attack_tracking_interfaces
|
unset attack_tracking_interfaces
|
||||||
|
|
||||||
|
# Remove any lingering restoration subroutines loaded.
|
||||||
|
unset load_attack
|
||||||
|
unset save_attack
|
||||||
|
|
||||||
FluxionTargetTrackerInterface=""
|
FluxionTargetTrackerInterface=""
|
||||||
|
|
||||||
return 1 # Trigger another undo since prep isn't significant.
|
return 1 # Trigger another undo since prep isn't significant.
|
||||||
|
@ -1736,11 +1760,34 @@ fluxion_prep_attack() {
|
||||||
|
|
||||||
# Check if attack provides tracking interfaces, get & set one.
|
# Check if attack provides tracking interfaces, get & set one.
|
||||||
# TODO: Uncomment the lines below after implementation.
|
# TODO: Uncomment the lines below after implementation.
|
||||||
#if type -t attack_tracking_interfaces &> /dev/null; then
|
if type -t attack_tracking_interfaces &> /dev/null; then
|
||||||
# if ! fluxion_target_set_tracker; then return 4; fi
|
if ! fluxion_target_set_tracker; then return 4; fi
|
||||||
#fi
|
fi
|
||||||
|
|
||||||
|
# If attack is capable of restoration, check for configuration.
|
||||||
|
if type -t load_attack &> /dev/null; then
|
||||||
|
# If configuration file available, check if user wants to restore.
|
||||||
|
if [ -f "$path/attack.conf" ]; then
|
||||||
|
local choice="?"
|
||||||
|
# TODO: This doesn't translate choices to the selected language.
|
||||||
|
while ! echo "$choice" | grep -q "^[ynYN]$" &> /dev/null; do
|
||||||
|
echo -ne "$FLUXIONVLine Would you like to repeat the last attack? [Y/n] "
|
||||||
|
read choice
|
||||||
|
if [ ! "$choice" ]; then break; fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${choice,,}" != "n" ]; then
|
||||||
|
load_attack "$path/attack.conf"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if ! prep_attack; then return 5; fi
|
if ! prep_attack; then return 5; fi
|
||||||
|
|
||||||
|
# Save the attack for user's convenience if possible.
|
||||||
|
if type -t save_attack &> /dev/null; then
|
||||||
|
save_attack "$path/attack.conf"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
fluxion_run_attack() {
|
fluxion_run_attack() {
|
||||||
|
|
Loading…
Reference in New Issue