/
wef
executable file
·4781 lines (4035 loc) · 159 KB
/
wef
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
#
# WEF - WiFi Exploitation Framework
# Discord: @d3ext
# Website: https://d3ext.github.io/
# Mail: <d3ext@proton.me>
# Github: https://github.com/D3Ext
#
# Check dependencies to work with the least possible tools
function check_dependencies(){
echo
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Checking installed tools and requirements..."
else
color_output_no_line "*" "Comprobando herramientas instaladas y requisitos..."
fi; echo; sleep 0.2
main_tools=(ip iw macchanger aircrack-ng airmon-ng aireplay-ng airodump-ng mdk4 xterm awk sed jq lspci column curl ps)
for program in "${main_tools[@]}"; do
if [ ! "$(command -v $program)" ]; then
tools_missing="true"
if [ "$x" != "true" ]; then
echo
x="true"
fi
if [ "$lang" == "en" ]; then
echo -e "${yC}${program}${blueC} not installed${endC}"
else
echo -e "${yC}${program}${blueC} no instalado${endC}"
fi; sleep 0.05
fi
done
if [ "$tools_missing" == "true" ]; then
echo
if [ "$lang" == "en" ]; then
color_output "*" "Install necessary requirements before using this tool"
else
color_output "*" "Instala los requisitos necesarios antes de usar esta herramienta"
fi
exit 0
else
sleep 0.5
fi
}
function run_setup(){
color_output "*" "Installing wef..."
sleep 0.1
mkdir /opt/wef \
/opt/wef/cache \
/opt/wef/main \
/opt/wef/main/captures \
/opt/wef/main/logs \
/opt/wef/main/graphs 2>/dev/null
sleep 0.1
# Download captive portals if they are not already on current directory
if [ -d ".git" ] && [ -d "captive-portals" ]; then
cp -r captive-portals/ /opt/wef/main/ 2>/dev/null
elif [ ! -d "captive-portals" ]; then
curl -LJO https://github.com/D3Ext/WEF/archive/main.zip &>/dev/null
unzip WEF-main.zip &>/dev/null
rm WEF-main.zip 2>/dev/null
downloaded="true"
cp -r WEF-main/captive-portals/ /opt/wef/main/ 2>/dev/null
fi
sleep 0.1
# Download wordlists if they are not already on current directory
if [ -d ".git" ] && [ -d "wordlists" ]; then
cp -r wordlists/ /opt/wef/main/ 2>/dev/null
gunzip /opt/wef/main/wordlists/rockyou.txt.gz 2>/dev/null
elif [ ! -d "captive-portals" ]; then
if [ "$downloaded" != "true" ]; then
curl -LJO https://github.com/D3Ext/WEF/archive/main.zip &>/dev/null
unzip WEF-main.zip &>/dev/null
rm WEF-main.zip 2>/dev/null
downloaded="true"
fi
cp -r WEF-main/wordlists/ /opt/wef/main/ 2>/dev/null
gunzip /opt/wef/main/wordlists/rockyou.txt.gz 2>/dev/null
fi
sleep 0.1
if [ -d ".git" ] && [ -f "wef" ]; then
cp wef /opt/wef/wef
cp src/mac-vendors.json /opt/wef/mac-vendors.json 2>/dev/null
elif [ ! -f "wef" ]; then
if [ "$downloaded" != "true" ]; then
curl -LJO https://github.com/D3Ext/WEF/archive/main.zip &>/dev/null
unzip WEF-main.zip &>/dev/null
rm WEF-main.zip 2>/dev/null
downloaded="true"
fi
cp WEF-main/wef /opt/wef/wef 2>/dev/null
cp WEF-main/mac-vendors.json /opt/wef/mac-vendors.json 2>/dev/null
fi
sleep 0.1
ln -s /opt/wef/wef /usr/bin/wef 2>/dev/null
chmod +x /opt/wef/wef /usr/bin/wef 2>/dev/null
if [ "$downloaded" == "true" ]; then
rm -rf WEF-main 2>/dev/null
fi
# Check if the wef config file exists in /opt/wef/
if [ ! -f "/opt/wef/wef.cnf" ]; then
echo -e "${blueC}[${yC}*${blueC}] Creating config file (/opt/wef/wef.cnf)${endC}"
echo "# This is default config file
# This file must be saved as /opt/wef/wef.cnf
# Then you can edit it to make it much more flexible and to adapt to your requirements
# Default lenguage to use. Values: en, es
lang=en
# Colorize output (recommended to be enabled)
use_colors=true
# Enable/disable verbose by default (recommended to be enabled)
verbose=true" >> /opt/wef/wef.cnf
fi
color_output_ln "*" "WEF successfully installed on path, execute ${yC}wef${endC}"
}
function run_update(){
rm /usr/bin/wef /opt/wef/wef 2>/dev/null
run_setup &>/dev/null
}
function parse_config(){
# If config has verbose enabled it will be used by default without the --verbose parameter
verbose=$(awk -F "=" '/verbose/ {print $2}' /opt/wef/wef.cnf | sed 's/#.*//' | tr -d " " | sed '/^$/d')
if [ ! "$verbose" ]; then
while true; do
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Do you want to enable verbose by default? Can be changed later in /opt/wef/wef.cnf [${yC}y${blueC}/${yC}n${blueC}]: " && read verbose_option
else
color_output_no_line "*" "¿Quieres activar por defecto el verbose? Se puede cambiar mas tarde en /opt/wef/wef.cnf [${yC}s${blueC}/${yC}n${blueC}]: " && read verbose_option
fi
if [ "$verbose_option" == "y" ] || [ "$verbose_option" == "yes" ] || [ "$verbose_option" == "s" ] || [ "$verbose_option" == "si" ]; then
content="$(cat /opt/wef/wef.cnf | grep -v "verbose=")"
echo -e "${content}# Enable/disable verbose by default (recommended to be enabled)\nverbose=true" > /opt/wef/wef.cnf
verbose="true"
break
elif [ "$verbose_option" == "n" ] || [ "$verbose_option" == "no" ] ; then
content="$(cat /opt/wef/wef.cnf | grep -v "verbose=")"
echo -e "${content}# Enable/disable verbose by default (recommended to be enabled)\nverbose=false" > /opt/wef/wef.cnf
verbose="false"
break
fi
done
fi
# Config wifi band in which to scan APs
frecuency_band=$(awk -F "=" '/frecuency_band/ {print $2}' /opt/wef/wef.cnf | sed 's/#.*//' | tr -d " ")
if [ ! "$frecuency_band" ]; then
while true; do
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Do you want to scan nearby access points on 2.4GHz, 5GHz or autodetect? You can change this later in /opt/wef/wef.cnf [${yC}2.4${blueC}/${yC}5${blueC}/${yC}auto${blueC}]: " && read scan_option
else
color_output_no_line "*" "¿Quieres escanear los puntos de acceso cercano en 2.4GHz, 5GHz o detectar automáticamente? Puedes cambiarlo mas tarde en /opt/wef/wef.cnf [${yC}2.4${blueC}/${yC}5${blueC}/${yC}auto${blueC}]: " && read scan_option
fi
if [ "$scan_option" == "2" ] || [ "$scan_option" == "2.4" ]; then
content="$(cat /opt/wef/wef.cnf | grep -v "frecuency_band=")"
echo -e "${content}\n
# Wifi band in which to scan access points. Values: 2.4, 5, auto
frecuency_band=2.4" > /opt/wef/wef.cnf
frecuency_band="2.4"
break
elif [ "$scan_option" == "5" ] ; then
content="$(cat /opt/wef/wef.cnf | grep -v "frecuency_band=")"
echo -e "${content}\n
# Wifi band in which to scan access points. Values: 2.4, 5, auto
frecuency_band=5" > /opt/wef/wef.cnf
frecuency_band="5"
break
elif [ "$scan_option" == "auto" ] || [ "$scan_option" == "autodetect" ]; then
content="$(cat /opt/wef/wef.cnf | grep -v "frecuency_band=")"
echo -e "${content}\n
# Wifi band in which to scan access points. Values: 2.4, 5, auto
frecuency_band=auto" > /opt/wef/wef.cnf
frecuency_band="auto"
break
fi
done
fi
# enable monitor mode at launch if it is set by default
auto_enable_monitor=$(awk -F "=" '/auto_enable_monitor/ {print $2}' /opt/wef/wef.cnf | sed 's/#.*//' | tr -d " ")
if [ ! "$auto_enable_monitor" ]; then
while true; do
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Do you want to enable monitor mode on each launch by default? Can be changed later in /opt/wef/wef.cnf [${yC}y${blueC}/${yC}n${blueC}]: " && read automon_option
else
color_output_no_line "*" "¿Quieres activar por defecto el modo monitor en cada arranque? Se puede cambiar mas tarde en /opt/wef/wef.cnf [${yC}s${blueC}/${yC}n${blueC}]: " && read automon_option
fi
if [ "$automon_option" == "y" ] || [ "$automon_option" == "yes" ] || [ "$automon_option" == "s" ] || [ "$automon_option" == "si" ]; then
content="$(cat /opt/wef/wef.cnf | grep -v "auto_enable_monitor=")"
echo -e "${content}\n
# Automatically enable monitor mode during launch
auto_enable_monitor=true" > /opt/wef/wef.cnf
auto_enable_monitor="true"
break
elif [ "$automon_option" == "n" ] || [ "$automon_option" == "no" ] ; then
content="$(cat /opt/wef/wef.cnf | grep -v "auto_enable_monitor=")"
echo -e "${content}\n
# Automatically enable monitor mode during launch
auto_enable_monitor=false" > /opt/wef/wef.cnf
auto_enable_monitor="false"
break
fi
done
fi
# Detect auto graph creation
create_graph=$(awk -F "=" '/create_graph/ {print $2}' /opt/wef/wef.cnf | sed 's/#.*//' | tr -d " ")
if [ ! "$create_graph" ]; then
while true; do
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Do you want to create a graph (using airgraph-ng) on each scan? Can be changed later in /opt/wef/wef.cnf [${yC}y${blueC}/${yC}n${blueC}]: " && read graph_option
else
color_output_no_line "*" "¿Quieres crear un gráfico (usando airgraph-ng) en cada escaneo? Se puede cambiar mas tarde en /opt/wef/wef.cnf [${yC}s${blueC}/${yC}n${blueC}]: " && read graph_option
fi
if [ "$graph_option" == "y" ] || [ "$graph_option" == "yes" ] || [ "$graph_option" == "s" ] || [ "$graph_option" == "si" ]; then
content="$(cat /opt/wef/wef.cnf | grep -v "create_graph=")"
echo -e "${content}\n
# Create a graph of every single scan you perform using airgraph-ng to see target devices and AP info
create_graph=true" > /opt/wef/wef.cnf
create_graph="true"
break
elif [ "$graph_option" == "n" ] || [ "$graph_option" == "no" ] ; then
content="$(cat /opt/wef/wef.cnf | grep -v "create_graph=")"
echo -e "${content}\n
# Create a graph of every single scan you perform using airgraph-ng to see target devices and AP info
create_graph=false" > /opt/wef/wef.cnf
create_graph="false"
break
fi
done
fi
scan_on_each_attack=$(awk -F "=" '/scan_on_each_attack/ {print $2}' /opt/wef/wef.cnf | sed 's/#.*//' | tr -d " ")
if [ ! "$scan_on_each_attack" ]; then
while true; do
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Do you want to scan APs on each attack? Can be changed later in /opt/wef/wef.cnf [${yC}y${blueC}/${yC}n${blueC}]: " && read scan_option
else
color_output_no_line "*" "¿Quieres escanear APs en cada ataque? Se puede cambiar mas tarde en /opt/wef/wef.cnf [${yC}s${blueC}/${yC}n${blueC}]: " && read scan_option
fi
if [ "$scan_option" == "y" ] || [ "$scan_option" == "yes" ] || [ "$scan_option" == "s" ] || [ "$scan_option" == "si" ]; then
content="$(cat /opt/wef/wef.cnf | grep -v "scan_on_each_attack=")"
echo -e "${content}\n
# Scan nearby access points each time you decide to perform an attack
scan_on_each_attack=true" > /opt/wef/wef.cnf
scan_on_each_attack="true"
break
elif [ "$scan_conf" == "n" ] || [ "$scan_conf" == "no" ]; then
content="$(cat /opt/wef/wef.cnf | grep -v "scan_on_each_attack=")"
echo -e "${content}\n
# Scan nearby access points each time you decide to perform an attack
scan_on_each_attack=false" > /opt/wef/wef.cnf
scan_on_each_attack="false"
break
fi
done
fi
# Config 'airmon check kill' which is useful for headless use and other things
kill_network_services=$(awk -F '=' '/airmon_check_kill/ {print $2}' /opt/wef/wef.cnf | sed 's/#.*//' | tr -d " ")
if [ ! "$kill_network_services" ]; then
while true; do
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Do you want to execute \"airmon-ng check kill\" when enabling monitor mode? This will stop your active network connections! Can be changed later in /opt/wef/wef.cnf [${yC}y${blueC}/${yC}n${blueC}]: " && read kns_option
else
color_output_no_line "*" "¿Quieres ejecutar \"airmon-ng check kill\" al activar el modo monitor? ¡Esto cortará tus conexiones activas! Se puede cambiar mas tarde en /opt/wef/wef.cnf [${yC}s${blueC}/${yC}n${blueC}]: " && read kns_option
fi
if [ "$kns_option" == "y" ] || [ "$kns_option" == "yes" ] || [ "$kns_option" == "s" ] || [ "$kns_option" == "si" ]; then
content="$(cat /opt/wef/wef.cnf | grep -v "airmon_check_kill=")"
echo -e "${content}\n
# Execute 'airmon check kill' when you enable monitor mode (disable it on headless device)
airmon_check_kill=true" > /opt/wef/wef.cnf
kill_network_services="true"
break
elif [ "$kns_option" == "n" ] || [ "$kns_option" == "no" ] ; then
content="$(cat /opt/wef/wef.cnf | grep -v "airmon_check_kill=")"
echo -e "${content}\n
# Execute 'airmon check kill' when you enable monitor mode (disable it on headless device)
airmon_check_kill=false" > /opt/wef/wef.cnf
kill_network_services="false"
break
fi
done
fi
identify_devices=$(awk -F "=" '/identify_devices/ {print $2}' /opt/wef/wef.cnf | sed 's/#.*//' | tr -d " ")
if [ ! "$identify_devices" ]; then
while true; do
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Do you want to identify vendor of discovered stations (based on a database)? Can be changed later in /opt/wef/wef.cnf [${yC}y${blueC}/${yC}n${blueC}]: " && read identify_option
else
color_output_no_line "*" "¿Quieres identificar el vendor de las estaciones descubiertas (basado en una base de datos)? Se puede cambiar mas tarde en /opt/wef/wef.cnf [${yC}s${blueC}/${yC}n${blueC}]: " && read identify_option
fi
if [ "$identify_option" == "y" ] || [ "$identify_option" == "yes" ] || [ "$identify_option" == "s" ] || [ "$identify_option" == "si" ]; then
content="$(cat /opt/wef/wef.cnf | grep -v "identify_devices=")"
echo -e "${content}\n
# Identify vendor of each nearby device found, based on a database (i.e. TP-LINK)
identify_devices=true" > /opt/wef/wef.cnf
identify_devices="true"
break
elif [ "$identify_option" == "n" ] || [ "$identify_option" == "no" ] ; then
content="$(cat /opt/wef/wef.cnf | grep -v "identify_devices=")"
echo -e "${content}\n
# Identify vendor of each nearby device found, based on a database (i.e. TP-LINK)
identify_devices=false" > /opt/wef/wef.cnf
identify_devices="false"
break
fi
done
fi
}
#
# Functions used to catch Ctrl+C sigterm, to remove temporal files and to revert interface changes
#
# Ctrl + C
function ctrl_c(){
if [ "$(check_interface_mode)" == "monitor" ]; then
while true; do
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Do you want to disable monitor mode? (default=yes) [${yC}y${blueC}/${yC}n${blueC}]: " && read disable_opt
else
color_output_no_line "*" "¿Quieres desactivar el modo monitor? (por defecto=si) [${yC}s${blueC}/${yC}n${blueC}]: " && read disable_opt
fi
if [ "$disable_opt" == "y" ] || [ "$disable_opt" == "yes" ] || [ "$disable_opt" == "s" ] || [ "$disable_opt" == "si" ] || [ ! "$disable_opt" ]; then
disable_mon
if [ "$lang" == "en" ]; then
good_output "+" "Monitor mode disabled"
else
good_output "+" "Modo monitor desactivado"
fi
break
elif [ "$disable_opt" == "n" ] || [ "$disable_opt" == "no" ]; then
break
elif [ "$disable_opt" != "n" ] && [ "$disable_opt" != "no" ]; then
color_output "X" "Invalid option"
fi
done
fi
kill_processes
wpa_process="$(ps -faux | grep "wpa_supplicant")"
if [ ! "${wpa_process}" ]; then
if [ "$lang" == "en" ]; then
color_output "*" "Restarting connections"
else
color_output "*" "Restableciendo conexiones"
fi
systemctl restart wpa_supplicant 2>/dev/null
net_process="$(ps -faux | gre "NetworkManager")"
if [ ! "${net_process}" ]; then
systemctl restart NetworkManager 2>/dev/null
fi
fi
if [ "$lang" == "en" ]; then
color_output "!" "Exiting..."
else
color_output "!" "Saliendo..."
fi
# Remove files created during the attacks
rm hostapd-wpe.log 2>/dev/null
rm /opt/wef/cache/eviltwin_attempts.txt 2>/dev/null
rm -rf /tmp/www 2>/dev/null
exit 0
}
# Ctrl + C for EvilTwin attack
function evil_twin_c(){
# Kill created processes
if [ "$lang" == "en" ]; then
color_output_ln "!" "Stoping processes..."
else
color_output_ln "!" "Parando procesos..."
fi
rm /opt/wef/cache/eviltwin_attempts.txt 2>/dev/null
killall dhcp &>/dev/null
kill_processes
systemctl restart systemd-resolved &>/dev/null
# Reconfigure the network adapter
if [ "$lang" == "en" ]; then
color_output "*" "Reconfiguring interface"
else
color_output "*" "Reconfigurando la interfaz"
fi
restore_interface_eviltwin
}
function wash_c(){
kill -9 ${wash_PID} 2>/dev/null; wait ${wash_PID} 2>/dev/null
}
# Ctrl + C for cracking processes
function crack_c(){
killall hashcat john aircrack-ng 2>/dev/null
}
# Ctrl + C for inhibition function
function inhibition_c(){
# Kill deauth process
killall aireplay-ng 2>/dev/null
}
function keep_exit(){
if [ "$lang" == "en" ]; then
echo -ne "${blueC}[${yC}*${blueC}] Do you want to exit from tool (${yC}y${blueC}) or going back to main menu (${yC}n${blueC})? : ${endC}" && read exit_status
else
echo -ne "${blueC}[${yC}*${blueC}] ¿Quieres salir de la herramienta (${yC}s${blueC}) o volver al menu (${yC}n${blueC})? : ${endC}" && read exit_status
fi
ctrl_c_pressed="true"
# If input is y or yes exit from the function
if [ "$exit_status" == "y" ] || [ "$exit_status" == "yes" ] || [ "$exit_status" == "s" ] || [ "$exit_status" == "si" ]; then
ctrl_c
elif [ "$exit_status" != "n" ] && [ "$exit_status" != "no" ]; then
keep_exit
fi
}
function keep_exit_c(){
kill_processes
if [ "$lang" == "en" ]; then
echo -ne "\n${blueC}[${yC}*${blueC}] Ctrl+C detected, do you want to exit from tool? [${yC}y${blueC}/${yC}n${blueC}]: ${endC}" && read exit_status
else
echo -ne "\n${blueC}[${yC}*${blueC}] Ctrl+C detectado, ¿quieres salir de la herramienta? [${yC}s${blueC}/${yC}n${blueC}]: ${endC}" && read exit_status
fi
if [ "$exit_status" == "y" ] || [ "$exit_status" == "yes" ] || [ "$exit_status" == "s" ] || [ "$exit_status" == "si" ]; then
ctrl_c
elif [ "$exit_status" == "n" ] || [ "$exit_status" == "no" ]; then
if [[ $input == 1 ]]; then
echo -ne "${blueC}[${yC}WEF${blueC}] >>${endC} "
fi
else
keep_exit_c
fi
}
function keep_exit_eviltwin(){
if [ "$lang" == "en" ]; then
echo -ne "\n${blueC}[${yC}*${blueC}] Ctrl+C detected, do you want to exit from tool? [${yC}y${blueC}/${yC}n${blueC}]: ${endC}" && read exit_status
else
echo -ne "\n${blueC}[${yC}*${blueC}] Ctrl+C detectado, ¿quieres salir de la herramienta? [${yC}s${blueC}/${yC}n${blueC}]: ${endC}" && read exit_status
fi
if [ "$exit_status" == "y" ] || [ "$exit_status" == "yes" ] || [ "$exit_status" == "s" ] || [ "$exit_status" == "si" ]; then
evil_twin_c
exit 0
elif [ "$exit_status" != "n" ] && [ "$exit_status" != "no" ]; then
keep_exit_eviltwin
fi
}
function kill_processes(){
# Avoid errors by killing possible processes which haven't been killed (shouldn't occur, just to prevent)
if [ "${airodump_PID}" ]; then
kill -9 ${airodump_PID} 2>/dev/null; wait ${airodump_PID} 2>/dev/null
fi
if [ "${aireplay_PID}" ]; then
kill -9 ${aireplay_PID} 2>/dev/null; wait ${aireplay_PID} 2>/dev/null
fi
if [ "${mdk4_PID}" ]; then
kill -9 ${mdk4_PID} 2>/dev/null; wait ${mdk4_PID} 2>/dev/null
fi
if [ "${hcx_PID}" ]; then
kill -9 ${hcx_PID} 2>/dev/null; wait ${hcx_PID} 2>/dev/null
fi
if [ "${wash_PID}" ]; then
kill -9 ${wash_PID} 2>/dev/null; wait ${wash_PID} 2>/dev/null
fi
if [ "${reaver_PID}" ]; then
kill -9 ${reaver_PID} 2>/dev/null; wait ${reaver_PID} 2>/dev/null
fi
if [ "${passive_PID}" ]; then
kill -9 ${passive_PID} 2>/dev/null; wait ${passive_PID} 2>/dev/null
fi
if [ "${hostapd_PID}" ]; then
kill -9 ${hostapd_PID} 2>/dev/null; wait ${hostapd_PID} 2>/dev/null
fi
if [ "${dnsmasq_PID}" ]; then
kill -9 ${dnsmasq_PID} 2>/dev/null; wait ${dnsmasq_PID} 2>/dev/null
fi
if [ "${lighttpd_PID}" ]; then
kill -9 ${lighttpd_PID} 2>/dev/null; wait ${lighttpd_PID} 2>/dev/null
fi
if [ "${eviltwin_PID}" ]; then
kill -9 ${eviltwin_PID} 2>/dev/null; wait ${eviltwin_PID} 2>/dev/null
fi
if [ "${eviltwin_deauth_PID}" ]; then
kill -9 ${eviltwin_deauth_PID} 2>/dev/null; wait ${eviltwin_deauth_PID} 2>/dev/null
fi
}
#
# Logging functions to avoid repeating code
#
function banner(){
echo -e "${yC}██╗ ██╗███████╗███████╗"
echo -e "██║ ██║██╔════╝██╔════╝ "
echo -e "██║ █╗ ██║█████╗ █████╗ "
echo -e "██║███╗██║██╔══╝ ██╔══╝ ${blueC}WiFi Exploitation Framework ${yC}${program_version}"
echo -e "╚███╔███╔╝███████╗██║ "
echo -e " ╚══╝╚══╝ ╚══════╝╚═╝${endC}"
}
function color_output_ln(){
echo -e "\n${blueC}[${yC}${1}${blueC}] ${2}${endC}"
}
function color_output(){
echo -e "${blueC}[${yC}${1}${blueC}] ${2}${endC}"
}
function color_output_no_line(){
echo -ne "${blueC}[${yC}${1}${blueC}] ${2}${endC}"
}
function color_output_tab(){
echo -e "\t${blueC}[${yC}${1}${blueC}] ${2}${endC}"
}
function good_output_ln(){
echo -e "\n${blueC}[${greenC}${1}${blueC}] ${2}${endC}"
}
function good_output(){
echo -e "${blueC}[${greenC}${1}${blueC}] ${2}${endC}"
}
function press_enter_attack(){
if [ "$lang" == "en" ]; then
echo -ne "\n${grayC}Press [Enter] to continue and launch attack${endC} " && read continue
else
echo -ne "\n${grayC}Presiona [Enter] para continuar y lanzar el ataque${endC} " && read continue
fi
}
function press_enter(){
echo -ne "\n${grayC}${1}${endC}" && read continue
}
# Create a simple progress bar with dots
function progress_bar(){
echo -ne "${blueC}[${yC}${3}${blueC}] ${4}"
for ((i = 0; i <= ${1}; i++)); do
echo -ne "."
sleep ${2}
done
echo -e "${endC}"
}
# This function is used when user selects an attack and monitor mode isn't enabled
function log_monitor_is_disabled(){
if [ "$lang" == "en" ]; then
color_output_ln "*" "Your network adapter interface is not in monitor mode."
echo -e "${blueC}[${yC}*${blueC}] Please, before doing any operation use the ${yC}enable${blueC} command to enable monitor mode${endC}"
else
color_output_ln "*" "La interfaz de la tarjeta de red no está en modo monitor."
echo -e "${blueC}[${yC}*${blueC}] Antes de realizar cualquier operación usa el comando ${yC}enable${blueC} para activar el modo monitor${endC}"
fi
clear_p=0
}
# Tell the user that the attack has been completed and a log was stored under logs folder
function log_completed(){
if [ "$lang" == "en" ]; then
good_output_ln "+" "Attack completed"; sleep 0.1
color_output "*" "Log with some attack info stored in /opt/wef/main/logs/${essid}.log"
else
good_output_ln "+" "Ataque completado"; sleep 0.1
color_output "*" "Log con información sobre el ataque creado en /opt/wef/main/logs/${essid}.log"
fi
}
function log_cracking_completed(){
if [ "$lang" == "en" ]; then
good_output "+" "Cracking process completed"
else
good_output "+" "Proceso de cracking completado"
fi
}
function log_handshakes_not_found(){
if [ "$lang" == "en" ]; then
color_output_ln "X" "Handshakes file not found\n"
else
color_output_ln "X" "Archivo de handshakes no encontrado\n"
fi
sleep 1
}
function log_command_not_found(){
if [ "$lang" == "en" ]; then
color_output "*" "${1} not installed" #, ensure to install it before performing this operation"
else
color_output "*" "${1} no instalado" #, asegurate de tenerlo instalado antes de realizar esta operación"
fi
}
# Tell the user that he/she can type "back" and he/she will return to main menu
function log_back_to_menu(){
if [ "$lang" == "en" ]; then
color_output_ln "*" "Type ${yC}back${blueC} to return to main menu"
else
color_output_ln "*" "Escribe ${yC}back${blueC} para volver al menú principal"
fi
}
function log_capture_files(){
if [ "$lang" == "en" ]; then
color_output "*" "Network capture saved as /opt/wef/main/captures/${essid}/${cap_name}.cap"
else
color_output "*" "Captura de red guardada como /opt/wef/main/captures/${essid}/${cap_name}.cap"
fi
}
function log_attack_info(){
if [ "$lang" == "en" ]; then
good_output "+" "Attack information"
else
good_output "+" "Información del ataque"
fi
if [ "$essid" ]; then
echo -e "${blueC} ESSID:${grayC} ${essid}${endC}"
fi
if [ "$ap_bssid" ]; then
echo -e "${blueC} BSSID:${grayC} ${ap_bssid}${endC}"
fi
if [ "$channel" ]; then
if [ "$lang" == "en" ]; then
echo -e "${blueC} Channel:${grayC} ${channel}${endC}"
else
echo -e "${blueC} Canal:${grayC} ${channel}${endC}"
fi
fi
if [ "$attack_time" ]; then
if [ "$lang" == "en" ]; then
echo -e "${blueC} Duration:${grayC} ${attack_time}${endC}"
else
echo -e "${blueC} Duración:${grayC} ${attack_time}${endC}"
fi
fi
if [ "$packets_to_send" ]; then
if [ "$lang" == "en" ]; then
echo -e "${blueC} Packets:${grayC} ${packets_to_send}${endC}"
else
echo -e "${blueC} Paquetes:${grayC} ${packets_to_send}${endC}"
fi
fi
if [ "$c_h" ]; then
if [ "$lang" == "en" ]; then
echo -e "${blueC} Capture handshakes?:${grayC} ${c_h}${endC}"
else
echo -e "${blueC} Capturar handshakes?:${grayC} ${c_h}${endC}"
fi
fi
if [ "$c_i" ]; then
if [ "$lang" == "en" ]; then
echo -e "${blueC} Capture IVs?:${grayC} ${c_i}${endC}"
else
echo -e "${blueC} Capturar IVs?:${grayC} ${c_i}${endC}"
fi
fi
}
function log_functions_info(){
if [ "$lang" == "en" ]; then
color_output_ln "*" "You can find an explanation of every single attack in the official Wiki: https://github.com/D3Ext/WEF/wiki/Attacks"
else
color_output_ln "*" "Puedes encontrar la explicación de cada ataque en la Wiki oficial: https://github.com/D3Ext/WEF/wiki/Attacks"
fi
}
#
# Help panels functions
#
function help_panel(){
echo -e "${yC} __ _____ ___ "
echo -e " \ \ / / __| __|"
echo -e " \ \/\/ /| _|| _| "
echo -e " \_/\_/ |___|_| "
echo -e "\n${blueC}[${yC}WEF${blueC}] WiFi Exploitation Framework ${yC}${program_version}${endC}"
list_interfaces # Show active interfaces (excluding the ethernet and loopback ones)
if [ "$lang" == "en" ]; then
echo -e "\n${blueC}Required parameters:"
echo -e "\t${yC}-i, --interface)${blueC} \tThe name of your network adapter interface in managed mode"
echo -e "\nOptional parameters:"
echo -e "\t${yC}-h, --help)${blueC} \t\tShow this help panel"
echo -e "\t${yC}--version)${blueC} \t\tPrint the version and exit${endC}"
else
echo -e "\n${blueC}Parametros requeridos:"
echo -e "\t${yC}-i, --interface)${blueC} \tEl nombre de la interfaz de tu tarjeta de red en modo managed"
echo -e "\nParametros opcionales:"
echo -e "\t${yC}-h, --help)${blueC} \t\tMuestra este panel de ayuda"
echo -e "\t${yC}--version)${blueC} \t\tImprime por pantalla la versión actual del programa${endC}"
fi
exit 0
}
# Attacks panel
function attacks_panel(){
if [ "$lang" == "en" ]; then
echo -e "\n${blueC}--------${yC}DoS attacks${blueC}--------\t--------${yC}WEP attacks${blueC}---------\t-----${yC}Rogue AP attacks${blueC}----${endC}"
echo -e "${blueC}[${yC}1${blueC}] Deauthentication attack\t[${yC}9${blueC}] ARP Replay attack\t\t[${yC}15${blueC}] EvilTwin attack${endC}"
echo -e "${blueC}[${yC}2${blueC}] WIDS Confusion attack\t[${yC}10${blueC}] HIRTE attack${endC}"
echo -e "${blueC}[${yC}3${blueC}] Authentication attack\t[${yC}11${blueC}] Caffe Latte attack${endC}"
echo -e "${blueC}[${yC}4${blueC}] Beacon Flood attack\t\t[${yC}12${blueC}] Fake Auth attack${endC}"
echo -e "${blueC}[${yC}5${blueC}] TKIP attack${endC}"
echo -e "\n${blueC}--------${yC}WPS attacks${blueC}--------\t------${yC}Handshake attacks${blueC}-----${endC}"
echo -e "${blueC}[${yC}6${blueC}] Pixie Dust attack\t\t[${yC}13${blueC}] WPA/WPA2 capture attack${endC}"
echo -e "${blueC}[${yC}7${blueC}] PIN Bruteforce attack\t[${yC}14${blueC}] PMKID attack${endC}"
echo -e "${blueC}[${yC}8${blueC}] Null PIN attack"
else
echo -e "\n${blueC}---------${yC}Ataques DoS${blueC}---------\t--------${yC}Ataques WEP${blueC}---------\t-----${yC}Ataques Rogue AP${blueC}-----${endC}"
echo -e "${blueC}[${yC}1${blueC}] Ataque de deautenticación\t[${yC}9${blueC}] Ataque ARP Replay\t\t[${yC}15${blueC}] Ataque EvilTwin${endC}"
echo -e "${blueC}[${yC}2${blueC}] Ataque de confusión WIDS\t[${yC}10${blueC}] Ataque HIRTE${endC}"
echo -e "${blueC}[${yC}3${blueC}] Ataque de autenticación\t[${yC}11${blueC}] Ataque Caffe Latte${endC}"
echo -e "${blueC}[${yC}4${blueC}] Ataque Beacon Flood\t\t[${yC}12${blueC}] Ataque de falsa auth.${endC}"
echo -e "${blueC}[${yC}5${blueC}] Ataque TKIP${endC}"
echo -e "\n${blueC}--------${yC}Ataques WPS${blueC}----------\t----${yC}Ataques de Handshake${blueC}----${endC}"
echo -e "${blueC}[${yC}6${blueC}] Ataque Pixie Dust\t\t[${yC}13${blueC}] Ataque de captura WPA/2${endC}"
echo -e "${blueC}[${yC}7${blueC}] Ataque de fuerza bruta\t[${yC}14${blueC}] Ataque PMKID${endC}"
echo -e "${blueC}[${yC}8${blueC}] Ataque de PIN nulo${endC}"
fi
}
# Commands help panel
function commands_panel(){
if [ "$lang" == "en" ]; then
echo -e "\n ${yC}COMMANDS:${endC}"
echo -e "\n\t${yC}NETWORK ADAPTER:${endC}"
echo -e "${blueC}\t enable\t\t\tenable monitor mode for especified network interface${endC}"
echo -e "${blueC}\t disable\t\tdisable monitor mode and enable managed mode for especified network interface${endC}"
echo -e "${blueC}\t mac\t\t\tchange interface MAC with a custom or random address${endC}"
echo -e "${blueC}\t check_vif\t\tcheck if your network adapter supports VIF (Virtual Interface)${endC}"
echo -e "\n\t${yC}ACCESS POINTS:${endC}"
echo -e "${blueC}\t scan\t\t\t\tscan nearby access points${endC}"
echo -e "${blueC}\t list_aps\t\t\tlist already scanned APs${endC}"
echo -e "${blueC}\t inhibit <bssid> <channel>\tinhibit connections of an AP until you press Ctrl + C (deauth all clients)${endC}"
echo -e "${blueC}\t graph <file.csv> <output.png>\tcreate a graph (using airgraph-ng) of APs and its devices (especify an airodump-ng csv file)${endC}"
echo -e "\n\t${yC}HANDSHAKES:${endC}"
echo -e "${blueC}\t check <file.cap>\t\t\tcheck if given capture file contains at least one WPA handshake${endC}"
echo -e "${blueC}\t crack <file.cap> <wordlist.txt>\tcrack given handshake with given wordlist using aircrack-ng${endC}"
echo -e "${blueC}\t john <file.cap> <wordlist.txt>\t\tcrack given handshake with given wordlist using john the ripper${endC}"
echo -e "${blueC}\t hashcat <file.cap> <wordlist.txt>\tcrack given handshake with given wordlist using hashcat${endC}"
echo -e "${blueC}\t convert <file.cap> <output.hc22000>\tconvert given capture file to hashcat crackeable format"
echo -e "\n\t${yC}INFORMATIVE:${endC}"
echo -e "${blueC}\t identify <mac>\t\tprint vendor of given MAC address (i.e. D0:37:45:37:B5:6D -> TP-LINK)"
echo -e "${blueC}\t info\t\t\tshow info about the network adapter interface${endC}"
echo -e "${blueC}\t panel\t\t\tdisplay attack options panel${endC}"
echo -e "${blueC}\t attacks\t\tshow info about the different attacks${endC}"
echo -e "${blueC}\t chipsets\t\tlist chipsets that supports monitor mode${endC}"
echo -e "\n\t${yC}CONFIG:${endC}"
echo -e "${blueC}\t verbose\t\tset verbose on, to see more output${endC}"
echo -e "${blueC}\t no verbose\t\tset verbose off, to see less output${endC}"
echo -e "${blueC}\t update\t\t\tcheck if an update is available and ask you to install it${endC}"
echo -e "${blueC}\t edit\t\t\tedit config file using default text editor (re-execute tool to apply changes)${endC}"
echo -e "${blueC}\t clear/cls\t\tclear the screen${endC}"
echo -e "${blueC}\t version\t\tprint the info about the version of wef${endC}"
echo -e "${blueC}\t exit/quit\t\texit from framework${endC}"
echo -e "${blueC}\t help/?\t\t\tprint this help panel${endC}"
elif [ "$lang" == "es" ]; then
echo -e "\n ${yC}COMANDOS:${endC}"
echo -e "\n\t${yC}ADAPTADOR DE RED:${endC}"
echo -e "${blueC}\t enable\t\t\thabilita el modo monitor en la interfaz de red especificada${endC}"
echo -e "${blueC}\t disable\t\tdesactiva el modo monitor y habilita el modo managed en la interfaz de red especificada${endC}"
echo -e "${blueC}\t mac\t\t\tcambia la MAC de la interfaz por una dirección concreta o una aleatoria${endC}"
echo -e "${blueC}\t check_vif\t\tcomprueba si tu adaptador de red soporta VIF (Interfaz Virtual)${endC}"
echo -e "\n\t${yC}PUNTOS DE ACCESO:${endC}"
echo -e "${blueC}\t scan\t\t\t\tescanea los puntos de acceso cercanos${endC}"
echo -e "${blueC}\t list_aps\t\t\tmuestra la lista de los APs escaneados${endC}"
echo -e "${blueC}\t inhibit <bssid> <channel>\tinhibe las conexiones de un AP hasta que presiones Ctrl + C (deautentica a todos los clientes)${endC}"
echo -e "${blueC}\t graph <file.csv> <output.png>\tcrea un gráfico (usando airgraph-ng) sobre los APs y sus clientes (especifica un archivo csv de airodump-ng)${endC}"
echo -e "\n\t${yC}HANDSHAKES:${endC}"
echo -e "${blueC}\t check <file.cap>\t\t\tcomprueba si el archivo especificado contiene al menos un handshake WPA${endC}"
echo -e "${blueC}\t crack <file.cap> <wordlist.txt>\tcrackea el handshake dado con la wordlist especificada usando aircrack-ng${endC}"
echo -e "${blueC}\t john <file.cap> <wordlist.txt>\t\tcrackea el handshake dado con la wordlist especificada usando john the ripper${endC}"
echo -e "${blueC}\t hashcat <file.cap> <wordlist.txt>\tcrackea el handshake dado con la wordlist especificada usando hashcat${endC}"
echo -e "${blueC}\t convert <file.cap> <output.hc22000>\tconvierte el archivo de captura a un formato crackeable con hashcat"
echo -e "\n\t${yC}INFORMATIVO:${endC}"
echo -e "${blueC}\t identify <mac>\t\tmuestra el vendor de la dirección MAC proporcionada (e.g. D0:37:45:37:B5:6D -> TP-LINK)"
echo -e "${blueC}\t info\t\t\tmuestra información sobre la interfaz del adaptador de red${endC}"
echo -e "${blueC}\t panel\t\t\tmuestra el panel con las opciones de los ataques${endC}"
echo -e "${blueC}\t attacks\t\tmuestra info sobre los diferentes ataques${endC}"
echo -e "${blueC}\t chipsets\t\tlista los chipsets que soportan modo monitor${endC}"
echo -e "\n\t${yC}CONFIG:${endC}"
echo -e "${blueC}\t verbose\t\tactiva el verbose, para ver mas info durante los ataques${endC}"
echo -e "${blueC}\t no verbose\t\tdesactiva el verbose, para ver menos info durante los ataque${endC}"
echo -e "${blueC}\t update\t\t\tcomprueba si hay alguna actualización disponible y la instala${endC}"
echo -e "${blueC}\t edit\t\t\tedita el archivo de config usando el editor de texto predeterminado (reejecuta WEF para aplicar los cambios)${endC}"
echo -e "${blueC}\t clear/cls\t\tlimpia la pantalla${endC}"
echo -e "${blueC}\t version\t\timprime la version actual de la herramienta${endC}"
echo -e "${blueC}\t exit/quit\t\tsalir del framework${endC}"
echo -e "${blueC}\t help/?\t\t\timprime este panel de ayuda${endC}"
fi
}
function evil_twin_panel() {
if [ "$lang" == "en" ]; then
color_output "1" "Rogue AP + Captive Portal"
color_output "2" "Rogue AP + Captive Portal + DoS"
color_output "3" "Rogue AP + Captive Portal + WiFi Enterprise"
color_output "4" "Rogue AP + Captive Portal + WiFi Enterprise + DoS"
else
color_output "1" "Rogue AP + Portal Cautivo"
color_output "2" "Rogue AP + Portal Cautivo + DoS"
color_output "3" "Rogue AP + Portal Cautivo + WiFi Enterprise"
color_output "4" "Rogue AP + Portal Cautivo + WiFi Enterprise + DoS"
fi
}
# Chipsets for monitor mode
function chipsets_panel(){
echo -e "\n\t${yC}Chipsets"
echo -e "\t--------${blueC}"
echo -e "\tRTL8812AU"
echo -e "\tAR9271"
echo -e "\tMT7610U"
echo -e "\tMT7612U"
echo -e "\tRTL8814U"
echo -e "\tRTL8188EUS${endC}"
color_output_ln "*" "${netCard} chipset: ${yC}${chipset}${endC}"
}
#
# Auxiliar functions to ask data to user (ESSID, BSSID, attack time, frames to send...)
#
function ask_target(){
while true; do
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Introduce target number: " && read number
else
color_output_no_line "*" "Introduce el número del objetivo: " && read number
fi
if [ ! "$number" ]; then
if [ "$lang" == "en" ]; then
echo -e "${grayC}Introduce a valid number${endC}"
else
echo -e "${grayC}Introduce un número valido${endC}"
fi
continue
elif [ "$number" == "exit" ] || [ "$number" == "quit" ]; then
ctrl_c
elif [ "$number" == "back" ]; then
break
elif [[ $number =~ ^[0-9]+$ ]]; then
break
else
if [ "$lang" == "en" ]; then
echo -e "${grayC}Introduce a valid number${endC}"
else
echo -e "${grayC}Introduce un número valido${endC}"
fi
continue
fi
done
}
function ask_target_client(){
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Introduce target client number: " && read client_number
else
color_output_no_line "*" "Introduce el número del cliente objetivo: " && read client_number
fi
if [ "${client_number}" == "exit" ] || [ "${client_number}" == "quit" ]; then
ctrl_c
fi
}
# Ask for BSSID
function ask_bssid(){
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Introduce BSSID of the target AP: " && read ap_bssid
else
color_output_no_line "*" "Introduce la BSSID del AP objetivo: " && read ap_bssid
fi
if [ "${ap_bssid}" == "exit" ] || [ "${ap_bssid}" == "quit" ]; then
ctrl_c
fi
}
# Ask for attack duration
function ask_time(){
if [ "$lang" == "en" ]; then
color_output_no_line "*" "Introduce attack duration (default=${default}): " && read attack_time
else
color_output_no_line "*" "Introduce la duración del ataque (por defecto=${default}): " && read attack_time
fi
if [ "${attack_time}" == "exit" ] || [ "${attack_time}" == "quit" ]; then
ctrl_c
fi
if [ ! "${attack_time}" ]; then
attack_time="${default}"
fi
if [[ ${attack_time} =~ [^0-9ms] ]] && [ "${attack_time}" != "back" ]; then
if [ "$lang" == "en" ]; then
color_output "X" "Invalid attack duration!"
else
color_output "X" "Duración inválida!"
fi
ask_time
fi
}
# Ask amount of frames to send