+ All Categories
Home > Documents > WiFi Captive Portal Bot (portal-bot) - Candela Technologies · Inside the bash script The...

WiFi Captive Portal Bot (portal-bot) - Candela Technologies · Inside the bash script The...

Date post: 27-Apr-2019
Category:
Upload: phungbao
View: 230 times
Download: 0 times
Share this document with a friend
19
http://www.candelatech.com [email protected] +1 360 380 1618 [PST, GMT -8] WiFi Captive Portal Bot (portal-bot) Goal: Execute a battery of of captive portal logins from virtual wifi stations using the newer script. Public access open WiFi service is often gated with a web sign-on form (a captive portal). LANforge virtual stations can emulate sign-in to the captive portal using the portal-bot.pl script. This script is by necessity incomplete because many captive portals have different behaviors and login form requirements. With this script, you provide a bot plugin that bridges the gap. This cookbook will coach you through a basic portal-bot integration and then you will create ten stations that authenticate through a captive WiFi portal. In this example, we will be testing agains a simple LAMP server on the upstream side of the AP. Do no use your LANforge server as the LAMP server because the routing will be difficult. In this chapter, a LAMP server is at 10.26.1.254, and there is an /etc/hosts entry for basic-portal to that address. Basic Interactions of a Captive Portal The basic order of operations of a captive portal are summarized in these steps: 1. A WiFi station accesses the LAN and is assigned a DHCP address. 2. The AP redirects any DNS and HTTP(s) request from the station. It returns either a login page directly a 301-Redirect to the login page 3. The station user submits this form. This form knows where to submit itself to, but it is possible that the form does not submit to the same address or service that it came from. 4. A successful authentication provides one of these responses: The originally requested page, either as a 301-Redirect or as a proxied result. A portal-iframe providing a logout or service menu and the original content inside. A redirect page that uses javascript or meta-refresh mechanisms to tell the browser to reload the originally requested page. Network Testing and Emulation Solutions
Transcript

http://[email protected]+13603801618[PST,GMT-8]

WiFiCaptivePortalBot(portal-bot)

Goal:Executeabatteryofofcaptiveportalloginsfromvirtualwifistationsusingthenewerscript.

PublicaccessopenWiFiserviceisoftengatedwithawebsign-onform(acaptiveportal).LANforgevirtualstationscanemulatesign-intothecaptiveportalusingtheportal-bot.plscript.Thisscriptisbynecessityincompletebecausemanycaptiveportalshavedifferentbehaviorsandloginformrequirements.Withthisscript,youprovideabotpluginthatbridgesthegap.Thiscookbookwillcoachyouthroughabasicportal-botintegrationandthenyouwillcreatetenstationsthatauthenticatethroughacaptiveWiFiportal.

Inthisexample,wewillbetestingagainsasimpleLAMPserverontheupstreamsideoftheAP.DonouseyourLANforgeserverastheLAMPserverbecausetheroutingwillbedifficult.Inthischapter,aLAMPserverisat10.26.1.254,andthereisan/etc/hostsentryforbasic-portaltothataddress.

BasicInteractionsofaCaptivePortalThebasicorderofoperationsofacaptiveportalaresummarizedinthesesteps:1. AWiFistationaccessestheLANandisassignedaDHCPaddress.

2. TheAPredirectsanyDNSandHTTP(s)requestfromthestation.Itreturnseitheraloginpagedirectly

a301-Redirecttotheloginpage

3. Thestationusersubmitsthisform.Thisformknowswheretosubmititselfto,butitispossiblethattheformdoesnotsubmittothesameaddressorservicethatitcamefrom.

4. Asuccessfulauthenticationprovidesoneoftheseresponses:Theoriginallyrequestedpage,eitherasa301-Redirectorasaproxiedresult.

Aportal-iframeprovidingalogoutorservicemenuandtheoriginalcontentinside.

Aredirectpagethatusesjavascriptormeta-refreshmechanismstotellthebrowsertoreloadtheoriginallyrequestedpage.

NetworkTestingandEmulationSolutions

ConfiguringaDemoCaptivePortalProvideLogin/Logoutpages

IfyouwishtosetupaloginandlogoutpageonanApache/PHPservertotestwith,youcancopythebelowfilestothe/var/www/htmldirectoryontheLAMPserver.login.php:<!DOCTYPEhtml!><?php$valid=true;if($_SERVER['REQUEST_METHOD']=='POST'){/*customerrorreporting,seeget_explanation*/if(!array_key_exists('username',$_POST)){header("HTTP/1.1400BadRequest");header("X-err-no:9400");header("X-err-msg:missingusername");$valid=false;}}?><html><head><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/><?phpif($valid){?><title>Login</title><?php}else{?><title>BadRequest</title><?php}?></head><body><?phpif($_SERVER['REQUEST_METHOD']=='POST'){?><?phpif(!$valid){?><h1>BadRequest</h1><?phpreturn;}?>

<?=$_POST['username']?>accessgranted.<?php}else{?><formmethod="post"action="">Login:<inputtype="text"name="username"value=""/><br/><inputtype="submit"name="login"value="Login"/></form><?php}?></body></html>

ProvideaRedirectinlieuofPortalCapture

Gettingaredirecttotheloginpagedoesnothavetobeverycomplex.Theportal-botscriptwillfirststartoffrequestingwhateverURLyouwish,sorequesthttp://basic-portal/start.HereisanApacheconfigurationlinetoredirectthatURItologin.php:httpd.conf

<Location/start>Redirect/start/login.php</Location>

Afteraddingthisredirect,restartyourApacherserviceusingthiscommand:

sudoapachectlconfigtest&&sudoapachectlrestart

Testingyourredirect

Youcanusethecommandcurl-sqvhttp://basic-portal/starttotestouttheredirectyoujustcreated.

UsingthePortalBotbashscriptBeforewegetstraighttoworkingwithportal-bot.pl,let'sseehowitisused.YourLANforgeinstallationhasanexamplescriptcalledportal-bot.bash-exampleforyoutocopyandmodify.Thisscriptisintendedforyoutologinandlogoutseparately.TheLANforgemanagerwillcallportal-bot.pldifferentlywhenbuildingupthestationortearingdownthestation,theseactionsaresimilar:

i ./portal-bot.bash willlogyourstationin

i ./portal-bot.bash--logout willlogyourstationout

Insidethebashscript

Theportal-bot.bashscriptisforexercisingyourportal-bot.plscriptoptionsfromthecommandlinewhileyoudevelopwithit.ThisisveryclosetothevaluesyouwillplaceinthePorts→Misc/PostIF-UPfield.

Switchesyouwon'tuseintheGUI

YouwillneverplacethePBOT_NOFORKoptioninthePorts→Misc/PostIF-UPfieldbecausethatwillinterrupttheprocessingoftheLANforgeManagerprocess.Youwillalsoneverplace$*inthatfield,either.Youcanplacethe--verboseand--debugflagsinthere,butitcanfillyourdiskwithlogoutputmorequickly.

Belowisanexampleportal-bot.bashscriptwith \ line-continuationcharactersformattedforclarity:

PBOT_NOFORK=1./portal-bot.pl\--devsta100\--botbp.pm\--ip410.26.2.30\--dns192.168.100.1\--mgt/dev/null\--delays0,1,3\--user"bob"\--pass"secret"\--ap_url"http://basic-portal/"\--start_url"http://basic-portal/start"\--login_form"login.php"\--login_action"login.php"\--logout_url"logout.php"\--verbose--debug$*Belowisthesamescriptusingshortswitches:

PBOT_NOFORK=1./portal-bot.pl\-ista100\-bbp.pm\--ip410.26.2.30\--dns192.168.100.1\--mgt/dev/null\--delays0,1,3\-u"bob"\-p"secret"\-a"http://basic-portal/"\-s"http://basic-portal/start"\-n"login.php"\-o"login.php"\-t"logout.php"\

-v-d$*

Usingtheportal-bot.bashcommandonthecommand-line:

Acommonmisconceptionisthinkingthat$*isacommand-lineargument.Itisonlyusedinbashscripts.Donotput$*onthecommand-line.

PBOT_NOFORK=1./portal-bot.pl-ista100-bbp.pm--ip410.26.2.30\--dns192.168.100.1--mgt/dev/null-u"bob"-p"secret"\-a"http://basic-portal/"-s"http://basic-portal/start"-n"login.php"-o"login.php"-t"logout.php"-v-d

Usingtheportal-bot.plperlscriptTips:

Firstthingtodo:editacopyofthatscriptandadjustitforyourstationdeviceandit'sIPaddress.

Add-dtoaddmoredebuggingmessages.Thatmakesdbg()statementsprint.Add--printafteryougetthescripttowork.ThiswillprintouttheformatoftheargumentsusefulforputtingthestatementsintotheGUIPorts→Misc/PostIF-UPfield.

ThefirstsixargumentsareprovidedbyLANforgewhenyouuseportal-bot.plwithastation.Youwanttopopulatetheseinyourbashscript,butnotinthePostIF_UPfield.

PBOT_NOFORKThisenvironmentvariabletellstheportal-bot.plscripttonotfork.Useitonlywhendeveloping.Omittingthisisnormalandallowsformulti-processingofwebrequestsfromLANforge.

-istationname

--botThebotpluginyouprovide

--ip4TheIPofthestation.ThisscriptisuselessiftherehasbeennoDHCPlease.

--ip6Use''fornoIPv6address.

--dnsTheDNSaddressesprovidedfromtheDHCPlease

--mgtTheFIFOthatsignalstheLANforgeserver.Youdon'tuseitwhentesting.

ThesecondsetofargumentsdescribeyourownAPenvironment:

--user|-uportalusername

--pass|-pportaluserpassword

--ap_url|-aAstringtoprependtoURLswhentalkingtotheAP.Notnecessary,butifyoudon'tuseit,youhavetoprovidefullyqualifiedURLsto--login_form,--login_action,and--logout_form.

--start_url|-sThefirstURLrequestedfromtheAP,thisshouldprovideeitheraloginpageoraredirecttoaloginpage.Ifyougetyourdestinationpage(like,ifyourequestbaidu.comandactuallygetit),yourstationhasprobablynotbeenloggedoutfromthecaptiveportal.

--login_form|-nThisiswhatyourequesttogetaloginform.Oftenitisreturnedintheredirect,butsometimesyoucannotgetacookieassignmentifyoudonotrequestitspecifically.

--login_action|-oSubmityourlogincredentialstothisURL.

--delaysCommaseparatedlistofsecondstodelayatcertainpoints:1. $::delays[0]Usedtodelaytheveryfirst'start_url'GETrequest2. $::delays[1]UsedtodelaythefirstPOSTrequestin'submit_login'3. $::delays[2]Usedtodelaythe'submit_logout'request.4. $::delays[3+]Yourbotcanutilizefurtherdelaysifyouspecify

Youmayspecifyskipsbyaddingazero:--delays1,0,2

Youmayspecifyarandomtimebyusing'random':--delays1,random,2

Youmayspecifyjustonetimeforalldelays:--delays2

Youmayspecifyarandomrange:--delays3-20,4-25

--logout_form|-tSubmittothisURLtologoutofthecaptiveportal

-v-dVerboseanddebugoutput,respectively.

--printSkipsprocessandprintsoutformattedarguments.

$*Expandstoallremainingshellarguments

WewillconnecttoourLANforgesystem*.Youwanttocopythisfiletoyourown./portal-bot.bashfile,edititandthenmakeitexecutable.

i *YoucanconnectviaVNC,PuTTYorotherSSHclient.

i Usechmod+xportal-bot.bash tomakeyourscriptexecutable.

Nowlet'sseehowtousethisscriptwithstationsta100.Runthecommands:

$cd/home/lanforge$chmod+xportal-bot.bash$./portal-bot.bash

Youwillseealotofoutput,itwillshowthecontentsofthewebpagesitfinds.

WatchingtheLogs

Typicallyyouwon'tneedtolookatthisoutputintheterminal,andyouwillnotadd-d-vflagstoyourLANforgestations.Youverylikelywillneedtocheckthelogoutputfromthesescriptsincaseyouneedtodiagnoseconnectionproblemsduringyourtest.Eachvirtualstationleavesaloginthe/home/lanforge/wifidirectory,likewifi/portal-bot.sta100.log

i Watchlogsusingtail:tail-Fwifi/portal-bot.sta100.log

ExecutingtheLANforgecurlcommandsyourself

Tofindtheactualcurlcommandsbeingexecuted,youwanttogrepthelogs.Belowisanexampleofgreppingthelogsandrunningthecurlcommand.

$cd/home/lanforge/wifi$grepSubmittingportal-bot-sta100.logSubmitting:/home/lanforge/local/bin/curl-sLki-c/tmp/sta100_cookie.txt-b/tmp/sta100_cookie.txt-4--interfacesta100--localaddr10.44.4.222--dns-servers192.168.100.1--dns-interfacesta100--dns-ipv4-addr10.44.4.222-XGET'http://basic-portal/start'Submitting:/home/lanforge/local/bin/curl-sLki-c/tmp/sta100_cookie.txt-b/tmp/sta100_cookie.txt-4--interfacesta100--localaddr10.44.4.222--dns-servers192.168.100.1--dns-interfacesta100--dns-ipv4-addr10.44.4.222-XPOST-d'username=bob''http://basic-portal/login.php'

Youmightnoticedthatsomeofthecommandsinthelogmightappearrepeated,thereareareasofredundantlogging.Thereisacasewhereyoucanlegitimatelyseerepeatedcommands:whenyouhaveanPostIF_UPvalue

configuredfortheportyouaretestingwith.(RememberthatthePostIF_UPfieldshouldbeblankwhendevelopingthescript.)

Remember,thiscurlcommandcannotberunwithoutfirstdoingasource/home/lanforge/lanforge.profileinyourshell(ourcurlisacustombuild).Hereisanexample.Wetakeacommandsimilartotheoneabove,add-qvandcancelitusing Ctl-C :

$cd/home/lanforge$sourcelanforge.profile#adda-qvtoseeheaderdetails$/home/lanforge/local/bin/curl-qv-sLki-c/tmp/sta100_cookie.txt-b/tmp/sta100_cookie.txt-4--interfacesta100--localaddr10.41.4.223--dns-interfacesta100--dns-ipv4-addr10.41.4.223http://basic-portal/start*STATE:INIT=>CONNECThandle0xa80158;line1397(connection#-5000)*Addedconnection0.Thecachenowcontains1members*Trying10.51.0.254...*TCP_NODELAYset*bind-local,addr:10.41.4.223dev:sta100*SO_BINDTODEVICEsta100failedwitherrno1:Operationnotpermitted;willdoregularbind*Name'sta100'family2resolvedto'10.41.4.223'family2*Localport:0*STATE:CONNECT=>WAITCONNECThandle0xa80158;line1450(connection#0)^C

ExplainingthecurlCommand

Therearemanyargumentstothecurlcommand,butingeneral,youshouldbeabletocopyandpastethecommandintoaterminalanditshouldwork(seenoteaboutlanforge.profileabove).Belowisanexampleofacurlcommand,with \ charactersasline-continuationmarks,formattedforclarity.

$/home/lanforge/local/bin/curl-qv\-sLki\-c/tmp/sta100_cookie.txt\-b/tmp/sta100_cookie.txt\-4\--interfacesta100\--localaddr10.41.4.223\--dns-interfacesta100\--dns-ipv4-addr10.41.4.223\http://basic-portal/start

Switch ExampleValue Purpose

-q Suppresspageoutput

-v Verbose,printsdiagnosticsteps

-s Suppressespageoutput

-L Followredirects

-k Suppresscertificatevalidationerrors

-i PrintHTTPheaders

-c sta100_cookie.txt Sendcookiesfromfile

-b sta100_cookie.txt Savecookiestofile

-4 UseIPv4

--interface sta100 bindtothisinterface

--localaddr 10.41.4.223 bindtothisaddress

--dns-interface sta100 sendDNSqueriesfromthisinterface

--dns-ipv4-addr 10.41.4.223 bindtothisaddresswhensendingDNSqueries

--dns-interface sta100 sendDNSqueriesfromthisinterface

-XGET UseHTTPGETmethod

POST UseHTTPPOSTmethod-d 'username=bob' URLencodedformparametersusedduringPOSTmethod

Yourportal-bot.bashscriptisintendedtobeawayoffocusingonthedevelopmentofyourbotpluginandnotrepetitivelytypingalongcurlcommand.

WritingyourBotPluginYourbotplugin,thePerlmoduleyouwillwriteforyourcaptiveportal,iscentraltotheoperationoftheportal-bot.plscript.Itisalsoimportantthatyoudonotaltertheportal-bot.plscriptunlessabsolutelynecessary,becauseyourchangescouldbeoverwrittenbyupgrades.Anyalterationtothetimeatwhichthefork()callismadeinthisscriptcanmaketheLANforgeservergrindtoahalt.

i Onlyedityourbotperlmodule,please.

TheBotSubroutines

Theexamplebot,bp.pm,providedwithLANforgedefinesfoursubroutines.Inorder:

find_redirect_urlThissubroutinereceivestheresponseoftheHTTP(S)GETofyour--start_urlparameter.Lookthroughthistoseeif:

youarealreadygettingdestinationcontent--ifso,youwerenotloggedout,

yougetaloginformdirectlyandnotaredirect,

oryougetaredirecttoaloginpage(possiblyonaseparateportlike:8080)

Ifyougetaredirecttoanotherport,comparethe--login_urlvaluetothis.Ifitisdifferent,considerupdatingyourlogin_urlparameter.

Theremightbemanyformparameters,likeonesforasessionid,aPHP_SESSID,acookie,abase64encodedstringindicatingyouroriginallyrequestedurl(orjustaplainURL-encodedurl),andanypossibleco-brandingparametersthatmightindicateanyadvertisingcampaignsassociatedwiththiscaptiveportal.Missingsomeofthesemightmakesubmittingtheformgiveyouanerror.Storethesevaluesasnecessaryinyourbot::namespace.Youdonotsubmityourloginpageinthismethod.

i Defineapackagescopevariableusingour$thing; afteryourpackagestatement.

submit_loginHereiswhereyousubmityourloginpageforms.Thebotlib::request()functionisprovidedtomakeGETandPOSTrequetsverboselogginganddebugging.Thepageisreturnedaslinesinthe@responsearray.

my$post_data="username=".uri_escape($user_name);my@response=();request({'curl_args'=>$::curl_args,'url'=>$post_url,'method'=>'POST','delay'=>'0,3',#see--delaysoption'post_data'=>$post_data,'print'=>1},#turnsondebugging\@response);

Thesubmit_loginfunctionusesthe$::delay[1]parameterif--delayswereset.Seeparagraphon

randomDelay.

interpret_login_responseHereyoudetermineifyouaregettinganaccessdeniederrororarebeingforwardedtoyouroriginalstart_urldestination.Setyour$resultvariabletoOKorFAIL.Usethelogg()methodtoaddinformationforthewifi/portal-botlog.

Inordertoaddevents,suchaspageloadtime,youwanttousethebotlib::newEvent()function:

my$page_time=botlib::time_milli()-$::start_at;newEvent("portal_login:$result",$page_time,$::dev);

Youreventlogwillgainmessageslikethese:

get_explanationSomewebapplicationscanprovidecustomizederrormessagesintheirresponse.Youcanaddaget_explanation()functiontoyourbottocollectthisinformation.Thebotlib::dbgdie()methodwilltakeadvantageofthismethodifavailable.Belowisanexcerptfromthemethodfoundinbp.pm:

subget_explanation{for$line(@$ra_result){($err_code)=$line=~/^X-err-no:(.*)$/if($line=~/^X-err-no:/);($err_msg)=$line=~/^X-err-msg:(.*)$/if($line=~/^X-err-msg:/);}return"$err_code,$err_msg";}

NoticehowthisparsesouttheHTTPheadersfoundiftheparameterusernameweremissingwhendoingaPOSTtobasic-portal/login.php:

header("X-err-no:9400");header("X-err-msg:missingusername");

YouwillseethesemessagesshowupintheLANforgeEventslog:

submit_logoutManycaptiveportalsdonotpublicisetheirlogoutURLs,soitmightbeavailableonlyonanadminpagefortheAP.Youwillknowwhenthelogout_urlparameterworksifyoucandoalogoutwiththatstation,andthensuccessfullylogbackinusingthesamestationandseeingthecaptiveportalsign-inpageagain.

randomDelayThedelayparametertobotlib::request()hasmanyoverloadstothecall:

Asimplenumberisasimpledelayinseconds.Nootherunitsareused.

Ifyouspecify'random'inthedelayparameter,thebotlib::randomDelay()iscalled,producingarangebetween[1-119]seconds.

Ifyouspecify'3-16',randomDelay(3,16)iscalledtoproducearandomrangebetween[3-16]seconds.

Ifyouspecifytwonumbersseparatedbyacomma,itlooksatyour@::delayslist,andpicksthesecondargumentifitcan,thelastitemof@::delaysifthelististooshort,orthefirstargumentiftherearenoitemsinthedelaylist.

Wehavenowcoveredallofthescriptingdevelopmentareasfortheportal-bot.plpluginyouwillwrite.

ConfiguringyourStationsASingleStation

Weassumeyouhaveportal-bot.bashworkingatthispoint.Thisishowyoucanconfigureasinglestation:1. Usetheportal-bot.pl--printcommandtoprintoutthearguments.2. Copytheresult(startingwith"portal-bot.pl")intothePort->Miscwindow.Avoidpopulatingthisfield

whileyouaredevelopingthescript!Ifyouplaceavalueintothatfield,yourportal-botscriptwillnotonlyexecute,buttheManagerprocesswillalsoexecutethescriptspecifiedinthePOST_IFUPfield.Thiscanbereallyconfusing.

MultipleStations

TogetmultiplevirtualstationslogginginanoutusingtheGUI,wejustneedafewofthoseparametersforthestationconfiguration.WewillusetheBatchModifyfeaturetoalteraseriesofstations.1. InthePortstab,createaseriesofstations.Inthisexamplewewillcreatethemwith:

Port:wiphy2

SelectDHCP-IPv4

Quantity:10

STAID:300

SSID:jedtest

Passphrase:jedtest1

SelectWPA2

SelectDown

2. HighlightthemandclickBatchModify.

3. ClicktheDownbutton.

4. Inyourterminal,invoketheportal-bot.bashwiththe--printargument:

./portal-bot.bash--printportal-bot.pl--botbp.pm--userbob--passbob1--ap_urlhttp://basic-portal/--start_urlhttp://basic-portal/start--login_formlogin.php--login_actionlogin.php--logout_formlogout.php

5. Usethe[+]buttontoexpandtoBox2.WewillenterthefollowingversionofourcommandintothePostIF-UPScriptarea.(Thepictureshowstheshortswitches.)

ClickOK

6. InthePortstab,doubleclicksta300andintheMiscConfigurationtab,youwillseethePostIF-UPScriptvalues.

TestingaStation

ExercisingthesestationsstartswithbringingthemupanddownusingtheBatchModifytool.1. Highlightonestation,sta300,andclickBatchModify.2. ClicktheDownbuttontoadmin-downthestation.

3. InashellontheLANforge,gotto/home/lanforge/wifiandtailthelogforstation300:

tail-fportal-bot.sta300.log

4. ClicktheUpbuttontoadmin-upthestation.

5. ClickthePortalLoginbuttonforcethestationtologinifyoudonotseeanymessagesinthelogfileyouaretailing.

TroubleshootingTechniques

Ifyourstationcannottalktothecaptiveportal,likeyouhaveatime-out,thesestepswillhelpidentifywherethereisamisconfiguration:1. PingtheportalfromLANforge:pingbasic-portal

2. Pingtheportalfromsta300:ping-I10.27.0.16basic-portal

3. Usecurltodownloadtheportalpagebyhand:curl-sqvhttp://basic-portal/login.php4. Checktherouteontheportalsideifyouarerouting.Someexamples:

route-n

routeadd-net10.27.0.0/23gw10.26.1.1

5. Checkaccesslogsfortheportal.Theremightbeahostnameissue.

UsingthePortBringupPluginUsingthePortBringupPluginisamuchmorefunwaytogetdatathanlookingatlogfiles.1. InthePluginsmenu,selectPortBringupTest.

2. HighlightaseriesofstationsandclickAddPort:

3. ClickStart

4. Youwillseethereportingwindow.ItoftentakesmanysecondsorafewminutesforstationstoaquireDHCPaddressesandstartreportinginformationintotheplugin.

CandelaTechnologies,Inc.,2417MainStreet,Suite201,Ferndale,WA98248,USAwww.candelatech.com|[email protected]|+1.360.380.1618


Recommended