-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy path802.11evil
More file actions
executable file
·421 lines (356 loc) · 10.7 KB
/
Copy path802.11evil
File metadata and controls
executable file
·421 lines (356 loc) · 10.7 KB
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
#!/usr/bin/env bash
#
# 802.11evil
#
# Create evil WiFi access point.
#
# Author: Emanuel Duss
#
set -o nounset
_red="$(tput setaf 1)"
_green="$(tput setaf 2)"
_reset="$(tput sgr0)"
echo_info(){ echo "${_green}[*] ${*}${_reset}" >&2; }
echo_error(){ echo "${_red}[#] ${*}${_reset}" >&2; }
print_usage(){
cat << EOI
Usage: 802.11evil [OPTION ...]
Program:
Create evil WiFi access point / router.
Options:
-l LAN interface (default: eth0)
-a Access Point interface (default: wlan0)
-d Disable WiFi (routing only) (default: off)
-4 IPv4 only mode (default: off)
-i Access Point IP address (default: 192.168.42.1)
-s Access Point SSID (default: 802.11evil)
-p Access Point password (default: password)
-r Redirect on/off (default: off)
-f Redirect ports from (default: 80,443)
-t Redirect ports to (default: 8080)
-o DHCP Option 121 for Static Route (default: off)
Example: 0.0.0.0/1,128.0.0.0/1
Author: Emanuel Duss (https://emanuelduss.ch)
EOI
}
check_dependencies(){
local fail=0
for command in "$@"
do
if ! hash "$command" &> /dev/null
then
echo_error "Command \"$command\" not found."
fail=1
fi
done
[[ "$fail" == 1 ]] && exit 1
}
parse_arguments(){
LAN_INTERFACE="eth0"
AP_INTERFACE="wlan0"
DISABLEWIFI="off"
AP_ADDRESS="192.168.42.1" # Will be /24
AP_ADDRESS6="fd42::1"
AP_ADDRESS6PREFIX="${AP_ADDRESS6%::*}::"
SSID="802.11evil"
PASSWORD="password"
REDIRECT="off"
REDIRECTPORTS="80,443"
REDIRECTTO="8080"
IPV4ONLY="off"
DHCP121OPTION="off"
while getopts 4l:i:a:ds:p:rf:t:o:h name
do
case $name
in
4)
IPV4ONLY="on"
;;
l)
LAN_INTERFACE="$OPTARG"
;;
a)
AP_INTERFACE="$OPTARG"
;;
d)
DISABLEWIFI="on"
;;
i)
AP_ADDRESS="$OPTARG"
;;
s)
SSID="$OPTARG"
;;
p)
PASSWORD="$OPTARG"
;;
r)
REDIRECT="on"
;;
f)
REDIRECTPORTS="$OPTARG"
;;
t)
REDIRECTTO="$OPTARG"
;;
o)
DHCP121OPTION="$OPTARG"
;;
h)
print_usage
exit
;;
?)
print_usage >&2
exit 1
;;
esac
done
}
# Always run exit_trap; only run exit_cleanup when set to 1
CLEANUP="0"
enable_cleanup(){ CLEANUP="1"; }
exit_trap(){
echo
echo_info "Stopping 802.11evil..."
[[ "${CLEANUP}" == "1" ]] && exit_cleanup
}
trap exit_trap EXIT
exit_cleanup(){
echo_info "Stopping dnsmasq..."
pkill dnsmasq
echo_info "Stopping hostapd..."
pkill hostapd
echo_info "Restoring network interface configuration for interface ${AP_INTERFACE}..."
ip address flush "${AP_INTERFACE}"
base64 -d <<< "${INITIAL_AP_INTERFACE}" | ip address restore "${AP_INTERFACE}"
echo_info "Restoring network interface configuration for interface ${LAN_INTERFACE}..."
ip address flush "${LAN_INTERFACE}"
base64 -d <<< "${INITIAL_LAN_INTERFACE}" | ip address restore "${LAN_INTERFACE}"
echo_info "Restoring IP routing table..."
ip route restore < "${INITIAL_IPROUTE}"
rm "${INITIAL_IPROUTE}"
echo_info "Restoring IP forwarding mode..."
sysctl -q -w net.ipv4.ip_forward="${INITIAL_IPFORWARD}"
echo_info "Restoring iptables configuration..."
iptables-restore <(echo "${INITIAL_IPTABLES}")
if [[ "$IPV4ONLY" == "off" ]]
then
echo_info "Restoring IPv6 routing table..."
ip -6 route restore < "${INITIAL_IP6ROUTE}"
rm "${INITIAL_IP6ROUTE}"
echo_info "Restoring IPv6 forwarding mode..."
sysctl -q -w net.ipv6.conf.all.forwarding="${INITIAL_IP6FORWARD}"
echo_info "Restoring ip6tables configuration..."
ip6tables-restore <(echo "${INITIAL_IP6TABLES}")
fi
echo_info "Stopped."
}
show_banner(){
cat << EOI
___ ___ ____ _ _ _ _
( _ ) / _ \___ \ / / | _____ _(_) |
/ _ \| | | |__) | | | |/ _ \ \ / / | |
| (_) | |_| / __/ _| | | __/\ V /| | |
\___/ \___/_____(_)_|_|\___| \_/ |_|_|
Evil Wi-Fi access point / router
EOI
}
show_settings(){
echo_info "Configured LAN interface: ${LAN_INTERFACE}"
echo_info "Configured access point interface: ${AP_INTERFACE}"
echo_info "Configured access point IP address: ${AP_ADDRESS}"
echo_info "IPv4 only mode: ${IPV4ONLY}"
echo_info "Configured SSID: ${SSID}"
echo_info "Configured password: ${PASSWORD}"
echo_info "Configured to redirect: ${REDIRECT}"
echo_info "Configured port(s) to redirect: ${REDIRECTPORTS}"
echo_info "Configured port to redirect to: ${REDIRECTTO}"
echo_info "Configured DHCP option 121: ${DHCP121OPTION}"
if [[ "${DISABLEWIFI}" == "off" ]]
then
if hash qrencode
then
echo_info "Wi-Fi QR Code:"
qrencode -t utf8 <<< "WIFI:S:${SSID};T:WPA;P:${PASSWORD};;"
else
echo_info "Cannot generate Wi-Fi QR code because qrencode is not installed."
fi
fi
echo
}
check_preconditions(){
if [[ "$UID" != 0 ]]
then
echo_error "Program must be run as root."
exit 1
fi
}
check_host_network_issues(){
echo_info "Checking for common networking issues..."
local fail=0
if systemctl --quiet is-active NetworkManager
then
echo_error "NetworkManager must not be running."
fail=1
fi
[[ "$fail" == 1 ]] && exit 1
}
check_host_ipv6_capability(){
if ip -6 addr list ${LAN_INTERFACE} | grep -q global
then
echo_info "Output LAN interface has IPv6. Using IPv4 and IPv6 mode."
else
echo_info "Output LAN interface does not have IPv6. Using IPv4 only mode."
IPV4ONLY="on"
fi
}
save_initial_configuration(){
echo_info "Saving initial configuration..."
INITIAL_LAN_INTERFACE="$(ip address save "${LAN_INTERFACE}" | base64 -w0)"
INITIAL_AP_INTERFACE="$(ip address save "${AP_INTERFACE}" | base64 -w0)"
INITIAL_IPFORWARD="$(sysctl -n net.ipv4.ip_forward)"
INITIAL_IPROUTE=$(mktemp -p /dev/shm/ 802.11evil-route-XXX) # Restore from STDIN does not work (illegal seek error)
ip route save > "${INITIAL_IPROUTE}"
INITIAL_IPTABLES="$(iptables-save)"
if [[ "$IPV4ONLY" == "off" ]]
then
INITIAL_IP6ROUTE=$(mktemp -p /dev/shm/ 802.11evil-route6-XXX)
ip -6 route save > "${INITIAL_IP6ROUTE}"
INITIAL_IP6FORWARD="$(sysctl -n net.ipv6.conf.all.forwarding)"
INITIAL_IP6TABLES="$(ip6tables-save)"
fi
}
configure_network(){
echo_info "Configure access point interface..."
echo_info "Flushing current configuration..."
ip address flush "${AP_INTERFACE}"
echo_info "Configuring IPv4 address ${AP_ADDRESS} on interface ${AP_INTERFACE}..."
ip address add "${AP_ADDRESS}/24" dev "${AP_INTERFACE}"
if [[ "$IPV4ONLY" == "off" ]]
then
echo_info "Configuring IPv6 address ${AP_ADDRESS6} on interface ${AP_INTERFACE}..."
ip address add "${AP_ADDRESS6}/64" dev "${AP_INTERFACE}"
fi
echo_info "Enabing interface..."
ip link set dev "${AP_INTERFACE}" up
sleep 1
ip -br address list "${AP_INTERFACE}"
if [[ "${REDIRECT}" == "on" ]]
then
for port in ${REDIRECTPORTS//,/ }
do
echo_info "Configure port redirects for IPv4 for port $port to redirect to ${REDIRECTTO}..."
iptables -t nat -A PREROUTING -i "${AP_INTERFACE}" -p tcp --dport "$port" -j REDIRECT --to-port "${REDIRECTTO}"
if [[ "$IPV4ONLY" == "off" ]]
then
echo_info "Configure port redirects for IPv6 for port $port to redirect to ${REDIRECTTO}..."
ip6tables -t nat -A PREROUTING -i "${AP_INTERFACE}" -p tcp --dport "$port" -j REDIRECT --to-port "${REDIRECTTO}"
fi
done
echo_info "Configured redirects:"
iptables -nL -t nat | grep REDIRECT
if [[ "$IPV4ONLY" == "off" ]]
then
ip6tables -nL -t nat | grep REDIRECT
fi
else
echo_info "Not configured to redirect ports."
fi
}
configure_ap(){
echo_info "Starting hostapd for interface ${AP_INTERFACE} with SSID ${SSID} and password ${PASSWORD}..."
if [[ "${DISABLEWIFI}" == "on" ]]
then
echo_info "WiFi is disabled. Only router functionality is available."
else
echo_info "Starting hostapd..."
# See documentation: https://git.w1.fi/cgit/hostap/plain/hostapd/hostapd.conf
hostapd <(cat << EOI
interface=${AP_INTERFACE}
# Default Linux driver
driver=nl80211
# Advertise country code and allowed channels
ieee80211d=1
country_code=CH
# Mode: a = 5 GHz, b = 2.4 GHz, g = 2.4 GHz
hw_mode=g
# Manually selecht channel (1, 6 or 11 for 2.4 GHz)
channel=1
# Allow all MAC addresses to connect
macaddr_acl=0
# WiFi Name and Password
ssid=${SSID}
wpa_passphrase=${PASSWORD}
# Enable WPA, 2 = WPA2 and WPA3
wpa=2
# WPA2 PSK
auth_algs=1
wpa_key_mgmt=WPA-PSK
# Disable insecure TKIP encryption algorithm
wpa_pairwise=CCMP
rsn_pairwise=CCMP
EOI
) &
fi
}
configure_dnsmasq(){
local subnet="$(cut -d . -f 1-3 <<< "${AP_ADDRESS}")"
local routeradvertisements=""
local staticroute=""
if [[ "$IPV4ONLY" == "off" ]]
then
echo_info "Configuring Router Advertisements for ${AP_ADDRESS6PREFIX}..."
routeradvertisements="--enable-ra --ra-param=${AP_INTERFACE},60 \
--dhcp-range=::,constructor:${AP_INTERFACE},ra-stateless,64 \
--dhcp-option=option6:dns-server,${AP_ADDRESS6}"
fi
if [[ "$DHCP121OPTION" != "off" ]]
then
echo_info "Configuring DHCP static routes (DHCP option 121) for ${DHCP121OPTION}..."
staticroute="--dhcp-option-force option:classless-static-route,${DHCP121OPTION//,/,$AP_ADDRESS,},$AP_ADDRESS"
fi
echo_info "Starting dnsmasq..."
dnsmasq --no-daemon \
--interface "${AP_INTERFACE}" --bind-interfaces \
--dhcp-range="${subnet}.50,${subnet}.150,2m" \
${staticroute} \
${routeradvertisements} \
--log-dhcp --log-queries \
-C /dev/null &
}
configure_nat(){
echo_info "Configuring IP forwarding and NAT for IPv4 on interface ${LAN_INTERFACE}..."
sysctl -q -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o "${LAN_INTERFACE}" -j MASQUERADE
iptables -P FORWARD ACCEPT
if [[ "$IPV4ONLY" == "off" ]]
then
echo_info "Configuring IP forwarding and NAT for IPv6 on interface ${LAN_INTERFACE}..."
# Accept RA even if IPv6 forwarding is enabled, otherwise the default route is removed
sysctl -q -w net.ipv6.conf."${LAN_INTERFACE}".accept_ra=2
sysctl -q -w net.ipv6.conf.all.forwarding=1
ip6tables -t nat -A POSTROUTING -o "${LAN_INTERFACE}" -j MASQUERADE
ip6tables -P FORWARD ACCEPT
fi
}
main(){
check_dependencies hostapd dnsmasq
parse_arguments "$@"
shift $((OPTIND - 1))
show_banner
show_settings
check_preconditions
check_host_ipv6_capability
check_host_network_issues
save_initial_configuration
enable_cleanup
configure_ap
configure_network
configure_dnsmasq
configure_nat
echo_info "Successfully set up 802.11evil."
echo_info "Press ^C (Ctrl-C) to stop 802.11evil."
read -r -d '' # Wait for ^C
}
main "$@"