+ All Categories
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


Top Related